verae-staff-iam/docs/PR-staff-role-switcher.md
George Lambert 5922dc704b docs: PR body for feature/staff-role-switcher
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.
2026-10-14 04:34:25 -04:00

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 gated 403 must_change_password until POST /password/change
  • Optional TOTP (/2fa/setup, /2fa/enable); STAFF_TOTP_REQUIRED=1 forces enroll path
  • POST /2fa/skip denied under required policy; POST /admin/mark-must-change for 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, proxyHeadersSeen
  • GET /enroll/csr/schema — fields-only (mint: false)
  • POST /enroll/csr — PEM shape gate (400 invalid); default 501 not_implemented; lab 201 + X-Lab-CA: 1 only when lab ready and non-prod
  • scripts/lab-test-ca.sh — init / sign / crl / warn (LAB ONLY)
  • Audit csr_attempt without storing PEM

Docs

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_ENABLE default off
  • NODE_ENV=production refuses 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-ui feature/staff-role-switcher (shared chrome / review template brand).
  • Edge dual-staff: set STAFF_IAM_URL and use catalog + /users/:id/roles (see edge IMPERSONATE-IAM-ROLES.md when 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)