ADRs
ADR-0079: Operator session RS256 dual-verify and TOTP step-up
Architecture decision record 0079.
ADR-0079: Operator session RS256 dual-verify and TOTP step-up
- Status: Accepted
- Date: 2026-09-15
- Authors: IBEX Harness team
Context
4.P.0 shipped provisional HS256 session cookies in services/api. Gate G1 (4.P.1) requires Auth-owned session issuance, step-up for high-impact operator actions, and a migration path that does not break local/dev HS256 smoke.
Decision
- RS256 issuer in Auth —
JWT_PRIVATE_KEY_PEMsigns operator access/refresh/step-up JWTs via stdlib RSA + JSON (services/auth/internal/sessionjwt). Claims align withSessionClaims(sub,org_id,permissions,session_kind,iss,aud,jti). - API dual-verify — Prefer RS256 using
DASHBOARD_JWT_PUBLIC_KEYS_PEM; on HS256 success logprovisional_hs256_verify=1. Do not remove HS256 in this milestone. - Bespoke TOTP — Auth RPCs
BeginTotpEnrollment/ConfirmTotpEnrollment/CreateStepUpTokenbehindIBEX_AUTH_TOTP_ENABLED(default false). Library:github.com/pquerna/otp. Secrets sealed with the credentials master key envelope. - Step-up transport — High-impact API routes accept
X-IBEX-Step-Up; missing/expired/wrong-org → typed deny without existence leak. - Non-goals — OIDC/ACR federation, org switching, dual-approval UI, and preview-token issuer remain out of scope.
Consequences
Positive
- Auth owns signing keys; API never sees
JWT_PRIVATE_KEY_PEM. - Operators can migrate gradually while HS256 remains for local smoke.
- Step-up is enforceable in
authz.pyviaRequiresStepUpbits (ADR-0009 amendment).
Negative / residual
- Dual-verify window keeps HS256 attack surface until cutover.
- Dual-approval and preview issuance are hooks/schema only until later milestones.
Was this page helpful?
Edit on GitHub
Last updated on