Skip to content

feat(reseller-admin): cross-tenant admin (Lars) — /admin session + allowlist + TOTP - #275

Merged
MoltyCel merged 1 commit into
mainfrom
feat/reseller-admin
Jul 19, 2026
Merged

feat(reseller-admin): cross-tenant admin (Lars) — /admin session + allowlist + TOTP#275
MoltyCel merged 1 commit into
mainfrom
feat/reseller-admin

Conversation

@MoltyCel

Copy link
Copy Markdown
Owner

Cross-tenant reseller-admin gated on existing /admin session + RESELLER_ADMIN_USERS allowlist (fail-closed) + mandatory TOTP step-up. POST /admin/reseller re-gated off X-Admin-Key. Append-only audit. Privilege boundary proven by test (7/7).

…ssion + allowlist + TOTP

One all-powerful reseller-admin role, gated on THREE factors, none skippable:
 (1) existing moltrust.ch/admin session (app.admin_auth, no second password),
 (2) RESELLER_ADMIN_USERS allowlist (env, FAIL-CLOSED: empty => nobody),
 (3) confirmed TOTP, verified at a step-up that mints a short-lived elevated
     token — data/actions require that token, so 2FA cannot be bypassed.
Enrollment (no secret yet) is protected by (1)+(2) — the verified existing admin
auth; re-enroll of a confirmed secret needs a current code. TOTP secret encrypted
at rest (pgcrypto) under RESELLER_ADMIN_TOTP_KEY (fail-closed if unset). Every
admin write -> append-only reseller_admin_audit (content-hash, immutable).

Endpoints /admin/reseller/*: 2fa status/enroll/confirm, elevate, list, tenant
detail, create, assign agent, draft invoice (test-key-only; live faktura flag off).
POST /admin/reseller re-gated OFF the X-Admin-Key onto this session+allowlist+TOTP
path (no weaker second door). Tenant isolation for reseller logins untouched;
cross-tenant reads are a separate code path. Migration additive+reversible.
Privilege boundary proven by test (7/7): reseller-token !-> admin, unlisted->403,
listed-no-TOTP->enroll-only, wrong code->deny, fail-closed on empty allowlist/no key.
Not deployed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@MoltyCel
MoltyCel merged commit c22d1c5 into main Jul 19, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant