Add docs/PR-staff-role-switcher.md covering role interface, TOTP/enroll, and links to ENROLL, TOTP, and PKI READY packs (PROD-CA cutover, AuthZ enroll design, CRL/OCSP deploy). Link from README Docs table.
5.1 KiB
5.1 KiB
PR: feature/staff-role-switcher (verae-staff-iam)
Repo: verae-staff-iam
Branch: feature/staff-role-switcher → main
Forgejo: https://git.georgelambert.org/marchon/verae-staff-iam
Companion PR: verae-staff-ui same branch (docs/PR-staff-role-switcher.md)
Paste this body (or link this file) when opening the Forgejo pull request.
Summary
Staff IAM gains an active role interface (currentRole on session), product roles catalog for edge dual-staff, first-login mustChangePassword + optional/required TOTP, and an honest device-cert enroll surface: default POST /enroll/csr → 501, opt-in LAB ONLY mint via LAB_CA_ENABLE=1 + lab-test-ca.sh (refused when NODE_ENV=production). Production CA mint is not shipped; ops kits are READY packages only.
Why
- Multi-role staff need one signed-in session and a switchable interface (CS / sales / operator / …) without re-login.
- Edge dual-staff impersonate needs a public starter/ender/admin catalog and per-user roles lookup.
- Security gates (password change, TOTP, mTLS status) must be real in software while production PKI stays external.
What landed (vs main)
Role interface switcher
- Session store carries
currentRole;GET /me,GET /interfaces,POST /session/role GET /roles/catalog→{ roles: ["starter","ender","admin"] }(public)GET /users/:idOrUsername/roles→ roles-only (no secrets); unknown/inactive → 404- App UI: Interface dropdown when capabilities ≥ 2; People & roles for admins
First login + TOTP
- New accounts:
mustChangePassword=true; doors gated403 must_change_passworduntilPOST /password/change - Optional TOTP (
/2fa/setup,/2fa/enable);STAFF_TOTP_REQUIRED=1forces enroll path POST /2fa/skipdenied under required policy;POST /admin/mark-must-changefor invite re-mark- Login UI + My security / enroll-2fa / change-password pages (2026 brand kit)
Enroll / PKI (no production mint)
GET /enroll/status— state, nextSteps,csrSchemaUrl,csrPostStatus,labCa,proxyHeadersSeenGET /enroll/csr/schema— fields-only (mint: false)POST /enroll/csr— PEM shape gate (400 invalid); default 501not_implemented; lab 201 +X-Lab-CA: 1only when lab ready and non-prodscripts/lab-test-ca.sh—init/sign/crl/warn(LAB ONLY)- Audit
csr_attemptwithout storing PEM
Docs
- Operator: ENROLL.md, TOTP.md
- Refuse matrix: PRODUCTION-PKI-REFUSE.md
- Design: TEST-CA-DESIGN.md, CRL-OCSP-DESIGN.md, PKI-MINT-BACKLOG.md
- PKI READY packs (ops kits; no mint code): see below
Link: ENROLL · TOTP · PKI READY packs
| Pack | Path | Role |
|---|---|---|
| ENROLL | ENROLL.md | Device cert mTLS: status, CSR schema, default 501, lab 201 contract |
| TOTP | TOTP.md | Authenticator 2FA + STAFF_TOTP_REQUIRED enroll path |
| PROD-CA cutover (READY) | PROD-CA-CUTOVER-RUNBOOK.md | Production CA mint/renew/revoke cutover (external CA; IAM does not become CA) |
| AuthZ enroll (READY) | AUTHZ-ENROLL-DESIGN.md | Design before dropping default 501 for a real AuthZ mint path |
| CRL/OCSP deploy (READY) | CRL-OCSP-DEPLOY-CHECKLIST.md | Production CRL/OCSP proxy/CA deploy checklist |
| Refuse matrix | PRODUCTION-PKI-REFUSE.md | Lab-only 201 vs production 501; prod never lab |
| Backlog | PKI-MINT-BACKLOG.md | What live production mint still requires |
Invariants held (do not merge if broken):
- Default
POST /enroll/csr→ 501 LAB_CA_ENABLEdefault offNODE_ENV=productionrefuses lab mint even if flag set- No PKCS#12 / private key return; no demo “real” staff cert from IAM
Test plan
cd verae-staff-iam
npm install
npm test
# expect: 19/19 pass (health PKI/lab matrix, password-totp, roles/currentRole)
Manual smoke (optional lab):
npm start # :3028
# login admin / admin-dev-key → change-password if marked → Interface dropdown if multi-role
# GET /roles/catalog ; GET /enroll/status ; POST /enroll/csr → 501
# LAB ONLY: ./scripts/lab-test-ca.sh init --dir ./lab-pki && LAB_CA_ENABLE=1 npm start
Merge notes
- Merge with
verae-staff-uifeature/staff-role-switcher(shared chrome / review template brand). - Edge dual-staff: set
STAFF_IAM_URLand use catalog +/users/:id/roles(see edgeIMPERSONATE-IAM-ROLES.mdwhen present). - Production PKI cutover is human/ops via READY packs — not enabled by this merge.
- Seed passwords are lab-only; rotate before any shared environment.
Out of scope (explicit)
- Live production device-cert mint/renew/revoke inside staff-iam
- Dropping default 501 without a real Signer + AuthZ path
- Production CRL/OCSP served from this process
- Customer portal accounts /
xVerae-token issue (staff_session only)