Authority Bootstrap Modes
Audience: Operators and CI engineers preparing a fresh Stella Ops Authority deployment.
Purpose: Compare the supported ways to provision or recover administrative access, and explain which to choose for production, local, demo, and CI contexts.
Stella Ops Authority needs at least one administrative user before any client can obtain an OIDC token. There are five supported ways to create or recover that access, each appropriate for a different deployment context. Pick one primary bootstrap mode and document the recovery path in your deployment runbook.
| Mode | Target | Trigger | Identity created |
|---|---|---|---|
| Setup wizard | Production / customer install | UI-driven, first browser visit to /setup-wizard/wizard | Operator-chosen username + password |
| Runtime default admin bootstrap | Local / CI clean install | STELLAOPS_ADMIN_PASS at Authority startup | admin in tenant default, password read from private env |
| Demo seed migration | Dev / demo / CI sample data | AUTHORITY_BOOTSTRAP_ENABLED=true at startup | Demo users/clients/ABAC rows only; historical default admin hash is scrubbed |
Driver-script setup | CI / scripted re-bootstrap | bash devops/compose/scripts/stella-connectors.sh setup | API-key-driven POST /internal/users against the running Authority |
| Compose password recovery helper | Local source checkout / compose stack | devops/compose/scripts/authority-password-set.* | Existing Authority user’s password is reset through the Stella CLI hashing path |
The setup wizard is the primary production path. Runtime default admin bootstrap is acceptable for local and scripted clean installs only when STELLAOPS_ADMIN_PASS comes from a private environment file. Demo seed migration is sample-data opt-in and must not be enabled for production.
Mode 1 - Setup Wizard
The wizard is the default production behavior on a fresh install. Authority starts with Bootstrap:Enabled=false and RunSeedMigrations=false; demo user rows are not seeded. The console UI detects the empty authority.users table on first navigation and routes the operator to /setup-wizard/wizard, which collects:
- Admin username + password (no defaults)
- Tenant name (defaults to
default) - Optional MFA enrollment
Submitting the wizard form posts to Authority’s /internal/users endpoint with the bootstrap API key (STELLAOPS_AUTHORITY_AUTHORITY__BOOTSTRAP__APIKEY) sourced from the deployment env. After the first user is created, the wizard endpoint refuses additional creates; subsequent admins must be added via the regular admin console.
Production checklist:
AUTHORITY_BOOTSTRAP_ENABLED=falsein your env file.STELLAOPS_AUTHORITY_AUTHORITY__BOOTSTRAP__APIKEYset to a unique secret and rotated on schedule.- Setup wizard reachable at
https://<your-host>/setup-wizard/wizard.
Mode 2 - Runtime Default Admin Bootstrap
Clean local compose defaults keep AUTHORITY_BOOTSTRAP_ENABLED=false; Seed-category migrations stay manual-only. The standard plugin still bootstraps the structural first administrator when defaultAdminBootstrap.enabled=true in etc/authority/plugins/standard.yaml.
Authority reads the admin password from the environment variable configured by defaultAdminBootstrap.passwordEnvironmentVariable (default STELLAOPS_ADMIN_PASS). If the admin user is missing or has no password hash and the variable is unset or blank, startup fails closed with a clear configuration error. Stella Ops does not provide a repository default password.
The runtime bootstrap also ensures the admin role, full StellaOpsScopes.All permission catalog, and role assignment exist. First-party clients are provisioned from etc/authority/plugins/standard.yaml by StandardPluginBootstrapper.
Clean local/CI checklist:
AUTHORITY_BOOTSTRAP_ENABLED=falsein your env file.STELLAOPS_ADMIN_PASSset to a private value.- After every fresh wipe-and-up, sign in as
adminwith the privateSTELLAOPS_ADMIN_PASSvalue.
Mode 3 - Demo Seed Migration
Set AUTHORITY_BOOTSTRAP_ENABLED=true only when you intentionally want demo/sample Authority rows. Authority’s Program.cs reads this and passes runSeedMigrations: true to AddAuthorityPostgresStorage, which causes the shared StartupMigrationHost to apply migrations in the seed category in addition to the default startup category.
The live seed file is src/Authority/__Libraries/StellaOps.Authority.Persistence/Migrations/S001_v1_authority_operational_baseline.sql — the collapsed pre-1.0 seed chain (S001_demo_seed.sql … S033_*). It is forward-only history and is not edited in place; the originals sit under Migrations/_archived/pre_1.0/mig061/ and are excluded from embedding, so new seed rows go into fresh forward S0xx_*.sql files after the baseline (e.g. S034_registry_read_scope.sql, S036_scope_catalog_parity_repair.sql).
Behaviour folded into that seed baseline (originally shipped as separate migrations, now archived):
- Sprint 20260525.011 (
S999_scrub_demo_admin_password.sql) clears only the known historical demo admin password hash so the runtime default admin bootstrap still owns the real password throughSTELLAOPS_ADMIN_PASS. - Sprint 20260524_002 (
S022_developer_self_service_abac_seed.sql) supersedes the base-seed placeholder behavior for the local demo developer. In dev/demo/CI mode, the demo developer receives explicit developer self-service ABAC attributes:serviceIds,repositoryIds,imageNamespaces,environmentIds,maxEnvironmentType=development, anddirectUpdateAllowed=true. Other seeded non-admin roles remain placeholders unless a later seed or operator action assigns a password.
Production safety properties:
- The seed migration is
INSERT ... ON CONFLICT DO NOTHING. Re-running it on a populated DB is a no-op. RunSeedMigrationsdefaults tofalseinStartupMigrationOptions; the seed applies only when the env flag is explicitly true.StandardUserCredentialStore.EnsureSeededAdminPasswordAsyncremains available only whenseedAdminRecovery.enabled=true. It repairs empty historical seed-admin hashes and never overwrites a non-empty hash.
Demo checklist:
AUTHORITY_BOOTSTRAP_ENABLED=truein your env file.STELLAOPS_ADMIN_PASSset to a private value for the real admin.- Optional demo/developer credentials are demo-only; do not deploy this configuration to production.
Mode 4 - Driver-Script setup
For CI pipelines that wipe and rebuild on every run but cannot or do not want to use runtime default admin bootstrap (for example, they test the setup wizard flow itself or need a different admin username), the driver script ships a setup subcommand:
bash devops/compose/scripts/stella-connectors.sh setup
What it does:
- Counts
authority.usersviapsqlagainststellaops_authority(overridable viaPOSTGRES_AUTH_DB). - If the table is empty, starts a one-shot
curlimages/curlcontainer attached to thestellaopsdocker network and POSTs aBootstrapUserRequestto Authority’s internal port using the bootstrap API key resolved from private env or the running Authority container. - Re-counts and exits non-zero if the row is missing.
stella-connectors.sh login auto-invokes setup once when the token endpoint returns HTTP 400 / invalid_grant / a body mentioning username; this is the self-healing path for CI scripts that do not want to reason about whether the seed migration is on or off.
CI checklist:
AUTHORITY_BOOTSTRAP_ENABLEDmay befalse.- Either
STELLAOPS_BOOTSTRAP_KEYis exported in the CI runner env, or the script’sdocker execlookup of the running Authority container resolves it. - Re-running
setupagainst a populated DB is idempotent.
Mode 5 - Compose Password Recovery Helper
Use the compose recovery helper when a local source-checkout stack already has an Authority admin row, but the password in the operator’s ignored env file is stale, unknown, or the account is locked out. This is not a fresh bootstrap mode; it updates the existing user’s credential through the Stella CLI command and Authority password hashing path from a one-shot compose container.
PowerShell:
$env:STELLAOPS_ADMIN_PASS = '<new-private-password>'
$env:STELLAOPS_ADMIN_PASS |
.\devops\compose\scripts\authority-password-set.ps1 -Username admin -Tenant default -PasswordStdin
Bash:
printf '%s\n' "$STELLAOPS_ADMIN_PASS" |
./devops/compose/scripts/authority-password-set.sh --user admin --tenant default --password-stdin
After recovery, update the ignored local .env value used by the stack, refresh browser sessions, and verify sign-in or POST https://stella-ops.local/connect/token.
The helper publishes the current Stella CLI from source before it runs the one-shot container. If publish fails with MSB3541 and Null character in path, the current helper treats that as corrupt generated MSBuild state, runs publish with build servers disabled, removes only the named generated obj directory inside this repository, and retries once. Do not wipe databases, edit authority.users, or enable demo seed to work around a stale local admin password.
Choosing Between Modes
Mode 2 (runtime default admin bootstrap) is the clean local/CI path. It is appropriate when:
- You want a usable admin without demo data.
- CI has no need to test the setup wizard itself.
- The admin password can come from a private environment variable.
Mode 3 (demo seed migration) is appropriate when:
- You explicitly need sample tenants/users/ABAC rows for demo or regression evidence.
Mode 4 (driver script) is appropriate when:
- CI tests need to exercise the setup wizard end-to-end.
- A deployment needs a different admin username or tenant than the runtime default admin bootstrap.
- A bootstrap run is needed only when the Authority user table is still empty.
Mode 5 (compose password recovery helper) is appropriate when:
- A local compose stack already has
admin, but the password is stale or unknown. - You need to clear local lockout counters while preserving the database and audit chain.
- You are operating from a source checkout and can run the compose recovery helper.
The runtime default admin bootstrap and demo seed can coexist. Demo seed no longer owns the real admin password; STELLAOPS_ADMIN_PASS remains the credential source. If the driver script also runs against a populated DB, it skips with the “admin already exists” message.
The driver-script setup path is not an existing-admin password reset. Once authority.users is populated, use the compose recovery helper instead:
$env:STELLAOPS_ADMIN_PASS = '<new-private-password>'
$env:STELLAOPS_ADMIN_PASS |
.\devops\compose\scripts\authority-password-set.ps1 -Username admin -Tenant default -PasswordStdin
printf '%s\n' "$STELLAOPS_ADMIN_PASS" |
./devops/compose/scripts/authority-password-set.sh --user admin --tenant default --password-stdin
If the helper reports MSB3541 with Null character in path while publishing the local CLI, that is corrupt generated MSBuild state, not an Authority password failure. The current helper runs publish with build servers disabled, removes only the named generated obj directory inside this repository, and retries once. If the retry still fails, treat it as a code or documentation defect and fix the setup path before continuing.
Rotation And Rollback
After any mode creates a usable admin or demo developer, treat the credential as a starting point and rotate immediately. The standard plugin will not overwrite a non-empty password_hash, so an operator-rotated password is safe across restarts even if demo seed remains enabled.
To return a deployment to a “no admin” state before re-running the wizard for a clean install demo:
bash devops/compose/scripts/wipe-postgres.sh --yes(full DB wipe, see Sprint 20260504_007).docker compose ... up -dwith the desired bootstrap mode env vars.- Browse to
/setup-wizard/wizard(Mode 1), setSTELLAOPS_ADMIN_PASSand use runtime bootstrap (Mode 2), enable demo seed (Mode 3), or runstella-connectors.sh setup(Mode 4).
Partial wipes (delete the row only) are not supported. The standard plugin caches user state, and an out-of-band delete will leave dangling sessions and break the audit chain.
See Also
- Break-Glass Account Operations — emergency access when normal authentication is unavailable.
- Authority Backup & Restore Runbook — protect and recover the admin identity and signing keys.
etc/authority/plugins/standard.yaml— runtime plugin config (tenant, allowed audiences, default admin bootstrap, recovery options).docs/INSTALL_GUIDE.md— end-to-end install path covering env file preparation and bootstrap selection.
