Skip to content

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-off docker compose run against the same image).
  • ASPNETCORE_ENVIRONMENT for that container must not be Production - 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

dotnet ECommerce.API.dll --bootstrap-superadmin --email "staging-admin@vayzomart.com"

(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

  1. Enroll the printed secret in an authenticator app before doing anything else in that terminal.
  2. 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).
  3. 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

  1. Explicit Feature Flag:
  2. SuperAdmin:ProductionBootstrapEnabled must be set to true in environment configuration or configuration provider (e.g. AWS Secrets Manager / Azure Key Vault / HashiCorp Vault).
  3. Defaults to false. If false or missing, the bootstrap CLI command terminates immediately with exit code 1.

  4. Bootstrap Authorization Secret:

  5. A cryptographically strong secret token (--bootstrap-secret) must be provided at invocation.
  6. It is validated via constant-time comparison against SuperAdmin:BootstrapSecret.
  7. Never commit or log this secret.

  8. Active Target Account:

  9. 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).
  10. If the account does not exist or is inactive, the bootstrap aborts.

  11. Zero Pre-Existing SuperAdmins:

  12. Bootstrap is strictly a first-time setup procedure.
  13. If one or more active MFA-enabled SuperAdmin role 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.

  14. Pre-Existing, Already-Confirmed MFA Only:

  15. SuperAdmin privileges require Multi-Factor Authentication.
  16. This CLI never generates, enables, prints, or silently confirms an MFA factor. The target account must already have MfaEnabled = true with a persisted encrypted MFA secret, established beforehand through the account's own authenticated MFA setup/confirm flow (POST /api/auth/mfa/setup then /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".
  17. 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.

  18. Audit Trail:

  19. Both UserRoleAudit and SecurityAuditRecord entries are committed atomically.
  20. The audit log records the actor (OPERATOR_BOOTSTRAP_CLI), target user, role grant, and operation FirstProductionSuperAdminBootstrap. No secrets or tokens are stored in the audit trail.

Runbook: Step-by-Step Operator Execution

Step 1: Pre-Execution Verification

  1. 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, and HasMfaSecret must all be 1/true before proceeding.
  2. Verify zero active SuperAdmins exist:
    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;
    
    (Result must be 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:
    Production SuperAdmin bootstrap completed successfully.
      Target user id: ...
      Target user email: target-superadmin@vayzomart.com
      Role: SuperAdmin
      Audit correlation id: ...
      Timestamp (UTC): ...
      Pre-existing MFA factor verified. No MFA secret was generated, displayed, or logged by this bootstrap.
    
  • 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

  1. Immediately remove or rotate SuperAdmin__BootstrapSecret.
  2. Ensure SuperAdmin:ProductionBootstrapEnabled is reverted to false or removed from the environment.
  3. Test login with the newly created SuperAdmin account and verify MFA prompt and dynamic RBAC permissions.