SuperAdmin Bootstrap Runbook (Staging & Production)¶
Overview¶
In accordance with Codex Security Invariant rules, default migrations and application startup
routines will never automatically provision or seed a SuperAdmin user in any environment.
Public HTTP bootstrap endpoints are strictly prohibited everywhere. Two distinct, separately
guarded CLI paths exist - they are not interchangeable and neither is ever wired into an
automated/unattended deployment pipeline:
| Staging / non-production | Production | |
|---|---|---|
| Flag | --bootstrap-superadmin |
--bootstrap-production-superadmin |
| Refuses to run when | ASPNETCORE_ENVIRONMENT=Production |
SuperAdmin:ProductionBootstrapEnabled is not explicitly true |
| MFA/TOTP secret | Generates a fresh one, prints the secret + provisioning URI to stdout once | Never generates one - the target account must already have a confirmed MFA factor; bootstrap fails closed otherwise |
| Where to run it from | A trusted operator shell with direct access to that environment's console output - never CI | Same - a trusted operator shell, never CI |
| Terminal recording | Must be off for the duration of the command (the secret appears in scrollback exactly once) | Not applicable - no secret is ever printed |
| Authenticator enrollment | Immediately, in the same session, before the terminal is closed or scrolled past | Already done beforehand, via the account's own /api/auth/mfa/setup+/confirm flow |
Staging / Non-Production Bootstrap (--bootstrap-superadmin)¶
This is the manual, operator-run path used to create the first SuperAdmin on a staging
environment (or any non-Production environment) - for example immediately after a fresh
scripts/deploy-staging-vps.sh deployment, once migrations and policy bootstrap have completed.
It is not part of that script and must never be added to it or to any other unattended
pipeline step.
Prerequisites¶
- Direct shell access to the environment running the API container (e.g.
docker compose -p vayzomart-staging exec staging_api ...on the VPS, or an equivalent one-offdocker compose runagainst the same image). ASPNETCORE_ENVIRONMENTfor that container must not beProduction- the command refuses to run otherwise, by design; there is no override flag for this refusal.- Terminal session recording/logging tools (
script, shell history to a shared log, CI job output capture, etc.) must be off before running this command - the TOTP provisioning secret is printed to stdout exactly once and is never persisted anywhere by the CLI itself. - Have an authenticator app ready on a device physically at hand, to scan/enter the secret immediately after the command completes.
Running it¶
(Substitute the real container-exec form appropriate to the environment, e.g. docker compose -p
vayzomart-staging exec staging_api dotnet ECommerce.API.dll --bootstrap-superadmin --email ....)
The command prints the TOTP provisioning secret and enrollment URI to stdout once - capture it into the authenticator app immediately. There is no way to retrieve it again; if it is lost, the account's MFA must be reset and the enrollment step repeated, it is not re-printable.
Immediately after¶
- Enroll the printed secret in an authenticator app before doing anything else in that terminal.
- Clear or close the terminal scrollback once enrollment is confirmed (log in once with a generated code to verify the app is actually in sync before doing this).
- Never paste the printed secret into chat, a ticket, a commit, or any other durable channel - treat it exactly like a password.
This path is intentionally simple and fast (no bootstrap-secret flag, no pre-existing-MFA requirement) because staging data is disposable and re-bootstrapping is cheap - the safeguards that matter here are "never CI" and "never Production", both enforced structurally, not the heavier multi-step guardrails the production path below requires.
Production Bootstrap (--bootstrap-production-superadmin)¶
The production SuperAdmin account must be safely initialized via a one-time operator CLI execution.
Security Invariants & Prerequisites¶
- Explicit Feature Flag:
SuperAdmin:ProductionBootstrapEnabledmust be set totruein environment configuration or configuration provider (e.g. AWS Secrets Manager / Azure Key Vault / HashiCorp Vault).-
Defaults to
false. Iffalseor missing, the bootstrap CLI command terminates immediately with exit code1. -
Bootstrap Authorization Secret:
- A cryptographically strong secret token (
--bootstrap-secret) must be provided at invocation. - It is validated via constant-time comparison against
SuperAdmin:BootstrapSecret. -
Never commit or log this secret.
-
Active Target Account:
- The target email address (
--email) must already exist as a registered, active (IsActive == true) account in the database (e.g., registered via standard administrative provisioning or verified user invite). -
If the account does not exist or is inactive, the bootstrap aborts.
-
Zero Pre-Existing SuperAdmins:
- Bootstrap is strictly a first-time setup procedure.
-
If one or more active MFA-enabled
SuperAdminrole assignments already exist in the database, the command fails closed and exits. Subsequent SuperAdmin assignments must be granted through standard SuperAdmin RBAC delegation by an existing SuperAdmin. -
Pre-Existing, Already-Confirmed MFA Only:
- SuperAdmin privileges require Multi-Factor Authentication.
- This CLI never generates, enables, prints, or silently confirms an MFA factor. The target
account must already have
MfaEnabled = truewith a persisted encrypted MFA secret, established beforehand through the account's own authenticated MFA setup/confirm flow (POST /api/auth/mfa/setupthen/api/auth/mfa/confirm), before it is eligible for this bootstrap. If the account has not already completed MFA enrollment, the bootstrap fails closed with"does not have a confirmed MFA factor". -
No TOTP secret, QR/provisioning URI, or recovery material is ever produced, printed, or logged by this command - there is no "secure MFA enrollment" step to perform after running it.
-
Audit Trail:
- Both
UserRoleAuditandSecurityAuditRecordentries are committed atomically. - The audit log records the actor (
OPERATOR_BOOTSTRAP_CLI), target user, role grant, and operationFirstProductionSuperAdminBootstrap. No secrets or tokens are stored in the audit trail.
Runbook: Step-by-Step Operator Execution¶
Step 1: Pre-Execution Verification¶
- Verify target user exists, is active, and already has MFA enabled (via the account's own
authenticated MFA setup/confirm flow - the bootstrap CLI will refuse to run otherwise):
SELECT Id, Email, IsActive, MfaEnabled, MfaSecretEncrypted IS NOT NULL AS HasMfaSecret FROM Users WHERE Email = 'target-superadmin@vayzomart.com';IsActive,MfaEnabled, andHasMfaSecretmust all be1/true before proceeding. - Verify zero active SuperAdmins exist:
(Result must be
SELECT COUNT(*) FROM UserRoles ur JOIN Roles r ON ur.RoleId = r.Id JOIN Users u ON ur.UserId = u.Id WHERE r.NormalizedName = 'SUPERADMIN' AND ur.IsActive = 1 AND r.IsActive = 1 AND u.IsActive = 1 AND u.MfaEnabled = 1;0).
Step 2: Set Environment Variables / Secrets¶
In the secure deployment container/runner:
export SuperAdmin__ProductionBootstrapEnabled="true"
export SuperAdmin__BootstrapSecret="<GENERATED_HIGH_ENTROPY_SECRET>"
Step 3: Run the Bootstrap CLI¶
Execute the API binary with the bootstrap arguments:
dotnet ECommerce.API.dll \
--bootstrap-production-superadmin \
--email "target-superadmin@vayzomart.com" \
--bootstrap-secret "$SuperAdmin__BootstrapSecret"
Step 4: Confirm Success¶
- The CLI prints only safe metadata - no MFA secret material of any kind:
- There is no secret to scan/enter and no terminal scrollback to clear - the account's existing authenticator enrollment (set up beforehand via the normal MFA setup/confirm flow) is unaffected.
Step 5: Post-Execution Invalidation & Cleanup¶
- Immediately remove or rotate
SuperAdmin__BootstrapSecret. - Ensure
SuperAdmin:ProductionBootstrapEnabledis reverted tofalseor removed from the environment. - Test login with the newly created SuperAdmin account and verify MFA prompt and dynamic RBAC permissions.