Internal staff users, roles, and permissions
  • JavaScript 67.4%
  • HTML 32.6%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
George Lambert 9ce87e8a20 feat: 2026 brand staff IAM — TOTP gate, enroll/status, UI kit
- STAFF_TOTP_REQUIRED enroll path and TOTP helpers
- enroll/status nextSteps, proxyHeadersSeen, ENROLL.md
- Brand kit on login/app public pages
2026-10-13 21:11:59 -04:00
public feat: 2026 brand staff IAM — TOTP gate, enroll/status, UI kit 2026-10-13 21:11:59 -04:00
src feat: 2026 brand staff IAM — TOTP gate, enroll/status, UI kit 2026-10-13 21:11:59 -04:00
test feat: 2026 brand staff IAM — TOTP gate, enroll/status, UI kit 2026-10-13 21:11:59 -04:00
.gitignore feat: 2026 brand staff IAM — TOTP gate, enroll/status, UI kit 2026-10-13 21:11:59 -04:00
ENROLL.md feat: 2026 brand staff IAM — TOTP gate, enroll/status, UI kit 2026-10-13 21:11:59 -04:00
NATS.md Initial import of verae-staff-iam from zapier monorepo 2026-09-11 19:55:17 -04:00
package-lock.json feat: 2026 brand staff IAM — TOTP gate, enroll/status, UI kit 2026-10-13 21:11:59 -04:00
package.json feat: 2026 brand staff IAM — TOTP gate, enroll/status, UI kit 2026-10-13 21:11:59 -04:00
README.md feat: 2026 brand staff IAM — TOTP gate, enroll/status, UI kit 2026-10-13 21:11:59 -04:00
SUMMARY.md feat: 2026 brand staff IAM — TOTP gate, enroll/status, UI kit 2026-10-13 21:11:59 -04:00

verae-staff-iam

standard-readme compliant

Named internal staff accounts with roles and permissions. Source of truth for who may use CS, sales,...

Forgejo: https://git.georgelambert.org/marchon/verae-staff-iam

Port :3028. UI: sign-in, people, roles, audit.

Seed lab users

Username Password Roles
admin admin-dev-key owner (all)
cs cs-dev-key cs
sales sales-dev-key sales
accounting acct-dev-key accounting
operator fleet-dev-key operator

Override with IAM_OWNER_PASSWORD, IAM_CS_PASSWORD, etc. Persist: STAFF_IAM_PATH (users, audit, sessions). Login is rate-limited (8 failures / 10 minutes / IP+username). JSON APIs return 401/403; HTML doors 302 to /login.

Staff security gates (ZP-B0)

Gate Behavior
TOTP Optional per user by default. POST /2fa/setup → enable {code} while signed in. When totpEnabled, login returns 401 {error:"totp_required"} until a valid 6-digit totpCode is sent. UI: My security tab + setup QR/secret.
TOTP required STAFF_TOTP_REQUIRED=1 — seed users stay totpEnabled: false, but after password login full app access is blocked with 403 {error:"totp_enrollment_required"} until they complete /2fa/setup + /2fa/enable. /me, /2fa/*, /logout still work. Disable is refused while the policy is on.
mTLS Copy + status only by default. GET /enroll/status returns updatedAt (ISO), state: not_enrolled | pending_proxy | enrolled | enforce_on, plus note / mint / renew copy, actionable nextSteps[], proxyHeadersSeen boolean summary (verify/verifyOk/dn/pem/any), and a proxy header probe. Enforcement is off unless STAFF_MTLS_ENFORCE=1 and the user has mtlsEnrolled: true (set via PUT /users/:username). Cert crypto stays at the reverse proxy — this service does not mint device certificates. Full header contract: ENROLL.md.
Session Cookie / Bearer staff_session only. Never issues customer xVerae- tokens.

Wire other doors

STAFF_IAM_URL=http://127.0.0.1:3028
STAFF_AUTH=1   # department HTML still redirects if check fails

GET /check?permission=cs.credit — cookie or Authorization: Bearer. Cookie name remains staff_session. Multi-host: STAFF_COOKIE_DOMAIN.

Roles

owner, iam-admin, billing-admin, cs, sales, accounting, operator, viewer. Permissions are listed on /roles.

Install

git clone ssh://git@git.georgelambert.org:2223/marchon/verae-staff-iam.git
cd verae-staff-iam

Usage

npm install
npm start

Contributing

Questions: open an issue at https://git.georgelambert.org/marchon/verae-staff-iam/issues. Pull requests are accepted.

License

UNLICENSED © George Lambert

Active role interface

Sessions carry capabilities (assigned roles) and currentRole (active interface).

  • GET /me / GET /interfaces — capabilities, currentRole, door URLs
  • POST /session/role { "role": "sales" } — switch active role (must be assigned); returns navigate url
  • Staff UIs show a top-right Interface dropdown when a user has two or more capabilities
  • Admins (owner / iam-admin) manage assignments under People & roles on this host

CORS allows credentialed calls from *.zapier.georgelambert.org so department doors can call IAM directly.

First login (force password change + optional authenticator)

New staff accounts are created with mustChangePassword=true (invite OTP is one-time). After /login the session cannot use staff doors (GET /check returns 403 must_change_password) until the user completes:

  1. GET /change-password → POST /password/change { currentPassword, newPassword }
  2. Optional GET /enroll-2fa → POST /2fa/setup → POST /2fa/enable { code }, or POST /2fa/skip

When authenticator is enabled, subsequent logins require totpCode (or 401 totp_required).

Admin: POST /admin/mark-must-change { usernames?: string[] } (defaults to the seven owner invites) re-marks accounts so their invite OTP cannot skip the change-password step.

Account security UI

Signed-in Security tab covers:

  • Change password (/change-password)
  • Optional authenticator enrollment (/enroll-2fa, /2fa/*)
  • Browser client certificate (mTLS) — slot + window.StaffIamSecurity.onCertMount hook reserved for the parallel cert-minting change (POST /certs/mint etc.)