Агуулгыг алгасах

eID — Admin консол (операторын самбар)

Operator/developer-т зориулсан гарын авлага: eID платформын Admin консол нь Next.js операторын самбар (admin/, порт 3001) ба Go admin API (/v3/admin/*)-ийн хосолсон систем. Оператор үүгээр иргэн, төхөөрөмж, сертификат, session, KYC/DAN, байгууллага (Legal Person), холбогдогч тал (RP), audit бүртгэл болон системийн төлөвийг удирдана.

Тусдаа app. Admin консол нь web/ (иргэний RP demo, порт 3000)-оос БҮРЭН тусдаа Next.js application. Кодын мод: admin/src/.

1. Юуг удирддаг вэ

Хэсэг Чадвар
Иргэд (/users) Хайх (etsi / РД / нэр / documentNumber), дэлгэрэнгүй + төхөөрөмж + сертификат + audit
Төхөөрөмж (/devices) Жагсаалт/хайлт, дэлгэрэнгүй, алдагдсан төхөөрөмж идэвхгүйжүүлэх
Сертификат (/certificates) Жагсаалт/хайлт, статус, цуцлах (revoke)
PKI (/pki, /org-ca) CA статус, OCSP/CRL зам, e-Seal QSCD төлөв
Байгууллага (/organizations) Legal Person бүртгэл, төлөөлөгч, e-Seal cert гаргах
RP (/rps) Холбогдогч талыг register/edit/deactivate/reactivate, secret rotate, дэд систем (subsystem) удирдах
Зөвшөөрөл (/approvals) 4-eyes: эмзэг үйлдлийг өөр админ баталгаажуулах
Audit (/audit) Бүх үйлдлийн бүртгэл + CSV export (eIDAS/ISO 27001)
Админ хэрэглэгч (/admins) Admin эрх үүсгэх/role солих/идэвхгүйжүүлэх (зөвхөн SUPER_ADMIN)
Систем (/system) Хувилбар, uptime, тохиргоо/HSM/KYC/PKI-ийн НУУЦГҮЙ төлөв

2. Архитектур — BFF (браузер секрет хардаггүй)

Admin консол нь Backend-for-Frontend (BFF) загвартай. Браузер admin session токеныг ХЭЗЭЭ Ч хардаггүй — токен зөвхөн Next серверийн httpOnly cookie-д хадгалагдана.

Браузер ──fetch──▶ Next BFF (порт 3001) ──Bearer──▶ Go admin API (/v3/admin/*)
  (cookie:            /api/login, /api/mfa,            adminAuth middleware
   admin_session,     /api/proxy/[...path]             + requireCap (RBAC)
   httpOnly)
  • Клиент → BFF. Хуудсууд api("users?q=…") дуудахад /api/proxy/* route-руу очно (admin/src/lib/client.ts).
  • BFF → Go. Proxy route cookie-оос session токен уншиж, Authorization: Bearer <token>-оор ${ADMIN_BACKEND_URL}/v3/admin/<path> руу дамжуулна (admin/src/app/api/proxy/[...path]/route.ts). Токен браузерт ил гарахгүй тул XSS-ээр хулгайлагдахгүй.
  • Хамгаалалт. Path-traversal allowlist ([A-Za-z0-9._-], ./.. хориглоно), mutating хүсэлтэд Origin/Referer host-ийг host-той тулгах (CSRF defense-in-depth, sameSite=strict дээр нэмж), upstream 5xx-ийг ерөнхий мессежээр далдлах.
  • Auth guard. (app) layout нь server дээр getMe() дуудаж session байхгүй/хүчингүй бол /login руу шиднэ (admin/src/app/(app)/layout.tsx).
  • CSP/security headers. admin/src/middleware.ts — nonce + strict-dynamic, connect-src 'self', frame-ancestors 'none', HSTS зэрэг.

Trust boundary. Go тал /v3/admin/*-ийг adminAuth middleware-ээр хамгаална (server/internal/httpapi/server.go). Дараалал: (1) Authorization: Bearer <session токен> → бодит RBAC; (2) X-Admin-Key → break-glass SUPER_ADMIN (constant-time тулгалт); (3) зөвхөн dev profile дээр SMARTID_ADMIN_API_KEY хоосон бол нээлттэй SUPER_ADMIN. staging/prod-д ХЭЗЭЭ Ч fail-open болохгүй — Bearer эсвэл break-glass key заавал.

3. Нэвтрэлт + MFA

Урсгал: имэйл/нууц үг → TOTP (MFA) → session токен. Эхний удаа QR-аар authenticator enroll хийнэ.

Алхам BFF route Go endpoint Тайлбар
1. Нэвтрэх POST /api/login POST /v3/admin/auth/login Имэйл/нууц үг шалгах; амжилттай бол mfa-scope токен
2. MFA POST /api/mfa POST /v3/admin/auth/mfa TOTP код → session-scope токен
3. Гарах POST /api/logout POST /v3/admin/auth/logout Cookie устгах (токен stateless)
  • Нууц үг. internal/admin/password.go-оор hash хийж хадгална; алдааг ерөнхийлж ("имэйл эсвэл нууц үг буруу") timing/enumeration-аас хамгаална.
  • TOTP (MFA). RFC 6238, HMAC-SHA1, 30 сек алхам, 6 орон — гадны сангүй өөрсдөө хэрэгжүүлсэн (server/internal/admin/totp.go). Эхний нэвтрэлтэд сервер otpauth:// URI + secret буцаана; login хуудас түүнийг QR болгож Google/Microsoft Authenticator-т нэмнэ. Код ±1 алхмын цонхтой (цагийн зөрүү), ашигласан counter-ийг хадгалж replay хаана (RFC 6238 §5.2).
  • Токен. HMAC-SHA256-аар гарын үсэг зурсан stateless токен (JWT сангүй), <b64url(payload)>.<b64url(HMAC)> (server/internal/admin/token.go). mfa-scope ~5 мин, session-scope ~1 цаг.
  • Cookie. admin_mfa (5 мин, MFA хүлээх) ба admin_session (1 цаг) — хоёул httpOnly, sameSite=strict, production-д secure.
  • Rate limit. login (per-IP+email) ба MFA (per-IP) throttle; хэтэрвэл 429 + Retry-After.
  • Нууц үг солих. POST /v3/admin/auth/password — нэвтэрсэн админ өөрийн нууц үгээ (одоогийнхоор баталгаажуулж) солино. Cap шаардахгүй.

4. RBAC — role ба capability

Route бүр шаардах capability-гаа зарлана; requireCap middleware нэвтэрсэн админы role тухайн cap-тай эсэхийг шалгана (least-privilege). Матриц: server/internal/admin/roles.go.

Capability-ууд: rp:read, rp:write, org:read, org:write, user:read, device:read, device:revoke, cert:read, cert:revoke, session:read, audit:read, admin:manage, config:read, config:write.

Role → capability:

Role Олгосон capability
SUPER_ADMIN бүх capability (admin удирдлага орно)
RP_OPERATOR rp:read rp:write org:read org:write user:read session:read audit:read
SUPPORT rp:read org:read user:read device:read device:revoke cert:read session:read audit:read
AUDITOR rp:read org:read user:read device:read cert:read session:read audit:read config:read
SECURITY_OFFICER org:read user:read device:read device:revoke cert:read cert:revoke session:read audit:read config:read

Cap хүрэлцэхгүй бол Go тал 403 ("энэ үйлдэлд эрх хүрэлцэхгүй") буцаана. Frontend Nav нь бүх хуудсыг харуулдаг ч эрхгүй үйлдэл backend дээр 403-оор хаагдана.

5. Гол чадварууд ба /v3/admin/* endpoint-ууд

Бүгд adminAuth-ийн ард. Хажууд шаардах capability.

Иргэн / төхөөрөмж / сертификат / session (read)

Method + зам Cap Тайлбар
GET /users?q=&limit=&offset= user:read Иргэд хайх (etsi/РД/нэр); олдохгүй бол documentNumber-ээр эзнийг хайна
GET /users/{etsi} user:read Иргэн + төхөөрөмж + сертификат + audit
GET /devices?q=&active= device:read Төхөөрөмж хайх
GET /devices/{documentNumber} device:read Төхөөрөмжийн дэлгэрэнгүй
GET /certificates?q=&status= cert:read Сертификат хайх
GET /users/{etsi}/certificates cert:read Тухайн иргэний сертификатын түүх
GET /sessions/{sessionId} session:read Session-ийн аюулгүй view

Нууц материал ХЭЗЭЭ Ч буцахгүй. View функцууд (userView/deviceView/certView/sessionView, handlers_admin_read.go) HSM handle, Enc(x_client), Paillier modulus, session secret/token, cert-ийн том base64-ийг хасаж зөвхөн аюулгүй талбаруудыг харуулна.

RP (холбогдогч тал)

Method + зам Cap Тайлбар
POST /relying-parties rp:write RP бүртгэх — API secret ЗӨВХӨН энд НЭГ УДАА буцна
GET /relying-parties, GET /relying-parties/{id} rp:read Жагсаалт / дэлгэрэнгүй
PATCH /relying-parties/{id} rp:write Засах
POST /relying-parties/{id}/deactivate | /reactivate rp:write Идэвхгүй / буцааж идэвхжүүлэх
POST /relying-parties/{id}/rotate-secret rp:write Шинэ secret (ЗӨВХӨН энд НЭГ УДАА)

RP дэд систем (subsystem). Дэд системийг RP өөрөө auto-бүртгэдэг (find-or-create); админ зөвхөн жагсаах / нэр засах / идэвхгүйжүүлэх / нэгтгэх боломжтой:

Method + зам Cap Тайлбар
GET /relying-parties/{id}/subsystems rp:read RP доторх дэд системийн жагсаалт
PATCH /relying-parties/{id}/subsystems/{sid} rp:write Дэд системийн нэр (display) засах
POST /relying-parties/{id}/subsystems/{sid}/deactivate | /activate rp:write Идэвхгүй / идэвхжүүлэх
POST /relying-parties/{id}/subsystems/{sid}/merge rp:write Өөр дэд систем рүү нэгтгэх

RP-ийн бүрэн интеграцын гарын авлага: RP_INTEGRATION.md. Дэд системийн загвар / wire: RP_SUBSYSTEMS.md.

Гэрчилгээ цуцлах + PKI

Method + зам Cap Тайлбар
POST /certificates/{serial}/revoke cert:revoke Серийн дугаараар цуцлах (OCSP/CRL + статус + төхөөрөмж идэвхгүй); {reason} 0–10
POST /devices/{documentNumber}/deactivate device:revoke Алдагдсан төхөөрөмж идэвхгүйжүүлэх (default reason=1 keyCompromise)
GET /pki/status config:read CA subject/serial/хугацаа, цуцлалтын тоо, OCSP/CRL URL, Org CA, e-Seal QSCD

KYC / DAN

KYC урсгал нь голдуу мобайл апп + DAN callback-ээр явагддаг (/v3/kyc/*, admin консолын ард биш — server.go mountKyc). GET /v3/kyc/methods нь идэвхтэй KYC аргуудыг (dan / gsign / passport / citizenCard) заана. Системийн GET /v3/admin/system дахь kyc блок KYC provider-ийн НУУЦГҮЙ төлөвийг харуулна.

Method + зам Cap Тайлбар
GET /organizations?q= org:read Жагсаалт/хайлт
GET /organizations/{etsi} org:read Дэлгэрэнгүй + төлөөлөгчид
POST /organizations org:write Бүртгэх (PENDING эсвэл шууд ACTIVE)
PATCH /organizations/{etsi} org:write Нэр / статус (FSM)
POST /organizations/{etsi}/representatives org:write Төлөөлөгч нэмэх
DELETE /organizations/{etsi}/representatives/{id} org:write Төлөөлөл идэвхгүй болгох
POST /organizations/{etsi}/seal-certificate org:write e-Seal (NTRMN) cert гаргах

Байгууллагын онбординг: ORG_ONBOARDING.md.

Audit + статистик

Method + зам Cap Тайлбар
GET /audit?type=&subject=&limit=&offset= audit:read Audit бүртгэл (хуудаслалттай)
GET /audit/export?type=&subject= audit:read CSV export (eIDAS/ISO 27001 тайлан)
GET /stats audit:read Dashboard тоо хэмжээ + чиг хандлага

Систем / HSM статус (read-only)

Method + зам Cap Тайлбар
GET /system config:read Хувилбар, uptime, security/kyc/pki/hsm/push тохиргооны НУУЦГҮЙ төлөв

Нууц гаргахгүй. adminSystemInfo (handlers_admin_system.go) түлхүүр/нууц үг/API key ХЭЗЭЭ Ч гаргахгүй — зөвхөн "тохируулсан эсэх" (жишээ нь swMasterKeyConfigured: true) төдийг заана.

Admin хэрэглэгчийн удирдлага (зөвхөн SUPER_ADMIN)

Method + зам Cap Тайлбар
GET /admins admin:manage Admin жагсаалт (нууцгүй view)
POST /admins admin:manage Шинэ admin (имэйл + 8+ тэмдэгт нууц үг + role)
PATCH /admins/{id} admin:manage Role солих
POST /admins/{id}/deactivate admin:manage Идэвхгүй болгох (устгахын оронд — audit хадгална)

4-eyes зөвшөөрлийн workflow

SMARTID_ADMIN_REQUIRE_4EYES=true үед эмзэг үйлдэл (cert revoke, device deactivate, RP deactivate) шууд гүйцэтгэгдэхгүй — PENDING хүсэлт болж (202), өөр админ баталгаажуулна.

Method + зам Cap Тайлбар
GET /approvals?status= audit:read Хүлээгдэж буй хүсэлтүүд
POST /approvals/{id}/approve (үйлдлийн cap динамик) Зөвшөөрөх
POST /approvals/{id}/reject (үйлдлийн cap динамик) Татгалзах

Зөвшөөрөгч нь (а) тухайн үйлдлийн cap-тай (жишээ: cert revoke → cert:revoke) БА (б) хүсэгчээс өөр байх ёстой — өөрийн хүсэлтийг батлах оролдлого ErrSelfApproval (403)-оор хаагдана (handlers_admin_approval.go).

6. Ажиллуулах

Frontend (admin консол):

cd admin
npm run dev     # порт 3001 (next dev -p 3001)
npm run build
npm run lint
npm run test    # vitest

Нэг гол env: ADMIN_BACKEND_URL (Go backend хаяг, default http://localhost:8080).

Backend (Go admin API)server/-оос ажиллуулна (go run ./cmd/smartid). Admin/RBAC-ийн env (server/internal/config/config.go, бүгд SMARTID_*):

Env Тайлбар
SMARTID_ADMIN_TOKEN_SECRET Session токен HMAC секрет (≥16 тэмдэгт). Хоосон бол admin authn идэвхгүй
SMARTID_ADMIN_SEED_EMAIL Эхний SUPER_ADMIN-ийн имэйл (startup seed, idempotent)
SMARTID_ADMIN_SEED_PASSWORD Эхний admin-ийн нууц үг (зөвхөн seed — дараа нь заавал солино)
SMARTID_ADMIN_SEED_ROLE Seed role (default SUPER_ADMIN)
SMARTID_ADMIN_API_KEY Break-glass X-Admin-Key (RBAC-аас гадуур SUPER_ADMIN; prod-д сонголт)
SMARTID_ADMIN_REQUIRE_4EYES Эмзэг үйлдэлд 2 админы зөвшөөрөл шаардах (default false)

Dev тохиргоо. dev profile дээр SMARTID_ADMIN_API_KEY хоосон бол /v3/admin/* нээлттэй SUPER_ADMIN болно (Bearer шаардахгүй) — зөвхөн локал хөгжүүлэлтэд. staging/prod-д ХЭЗЭЭ Ч тэгэхгүй; SMARTID_ADMIN_TOKEN_SECRET + seed эсвэл break-glass key заавал тохируулна.

7. Холбоос

Эх код: