Setup Wizard - Capability Specification
Audience: engineers and product owners implementing or extending the Stella Ops Setup Wizard across the CLI and Console. For the user-facing flow, see setup-wizard-ux.md; for the validation/remediation contract, see setup-wizard-doctor-contract.md.
This document defines the functional requirements for the Stella Ops Setup Wizard, covering both CLI and UI implementations.
Source of truth (verified against
src/). The backend-authoritative step contract isSetupStepDefinitions.Allinsrc/Platform/StellaOps.Platform.WebService/Contracts/SetupWizardModels.cs. It defines exactly six steps:Database,Valkey,Migrations,Admin,Crypto(required) andSources(optional). The Platform setup API (SetupEndpoints.cs) andPlatformSetupService.ProbeStepCoreAsyncreject any other step id with “is not part of the installation bootstrap contract”. Sections in this doc that describe additional steps (Vault, Settings Store, SCM, Registry, Notifications, Identity, Environments, Agents, Assurance) are onboarding/handoff capability notes, not setup-wizard steps — they are not accepted by the current setup APIs or thestella setupcommand group. Where this doc disagrees with the code, the code wins.
1. Overview
The Setup Wizard provides a guided, step-by-step configuration experience that:
- Validates infrastructure dependencies (PostgreSQL, Valkey)
- Runs database migrations
- Bootstraps the initial admin, crypto/compliance profile, and optional advisory/VEX source configuration
- Exposes a truthful required-readiness summary for setup completion
- Hands tenant onboarding to authenticated
/setup/*and integration command surfaces instead of pretending they are bootstrap steps
2. Completion Thresholds
2.1 Operational (Minimum Required)
The system enters “Operational” state when the required platform dependencies report ready. PlatformHealthService.BuildReadinessAsync (src/Platform/StellaOps.Platform.WebService/Services/PlatformHealthService.cs) builds the readiness summary from five setup-step-derived dependencies plus two live HTTP probes, and PlatformSetupService.FinalizeSessionAsync blocks finalize unless ReadyToProceed is true (or Force=true):
| Readiness dependency | Description | Source signal |
|---|---|---|
database (Database) | PostgreSQL reachable; Database setup step passed | setup step state + check.database.connectivity / check.database.version probe |
cache (Cache) | Valkey/Redis reachable; Valkey setup step passed | setup step state + check.services.valkey.connectivity probe |
migrations (Migrations) | Required modules (Platform, ReleaseOrchestrator) converged | setup step state + check.database.migrations.pending / .applied probe |
admin-bootstrap (Admin Bootstrap) | Bootstrap admin ensured via Authority; Admin step passed | setup step state + check.authority.admin.exists / check.auth.password.policy probe |
crypto-profile (Crypto Profile) | Regional crypto/compliance profile saved; Crypto step passed | setup step state + check.crypto.profile probe |
front-door (Front Door) | Platform front-door HTTP probe succeeds | live reachability probe |
authority (Authority) | Authority service health endpoint responds | live AuthorityInternal health probe |
Reconciled: the previous “Doctor Check” column listed IDs such as
check.services.core.healthy,check.crypto.profile.valid, andcheck.auth.admin.exists. These are not the IDs emitted by the setup probes, and the readiness gate is not a Doctor-plugin run — it is the step-derived dependency summary above. Setup-step Doctor check IDs are listed per step in §4; the Doctor module’s own catalog (src/Doctor/**) uses unrelated namespaces (check.agent.*,check.scanner.*,check.notify.*, …).
Gating Behavior: Setup status and finalize gate only on this operational threshold. Optional post-boot services may still be degraded and are surfaced through health diagnostics instead of blocking bootstrap completion.
2.2 Production-Ready (Recommended)
Roadmap / out of scope for the wizard. None of the items below are required-readiness signals in the current code, and none of the
check.*IDs in this table exist insrc/. They describe operator best-practice that is configured through authenticated post-bootstrap surfaces (Integrations, Identity & Access, Notifications, Trust & Signing, Orchestrator), not the setup wizard. Treat this section as a hardening checklist, not a contract.
A production deployment is typically configured with:
| Recommendation | Description | Where configured |
|---|---|---|
| OIDC/LDAP configured | External identity provider integrated | Authority / /setup/identity-access |
| Vault connected | At least one secrets provider | Integrations / Secrets surfaces |
| SCM integrated | At least one SCM (GitHub/GitLab) | Integrations |
| Notifications configured | At least one notification channel | Notify / /setup/notifications |
| Feed sync enabled | Vulnerability advisory/VEX mirroring active | optional sources step or Integrations → Advisory & VEX Sources |
| Environment defined | At least one environment created | ReleaseOrchestrator environments |
| Agent registered | At least one healthy agent | Orchestrator agent registration |
| TLS hardened | All endpoints using TLS 1.2+ | reverse proxy / gateway deployment |
3. Step Catalog
3.1 Core Steps
The backend-authoritative inventory is SetupStepDefinitions.All (SetupWizardModels.cs). It is exactly the following six steps; the API projects these (and only these) to the Console and CLI:
| Step ID (frontend) | SetupStepId | Name (backend Title) | Required | Skippable | Category | Depends on |
|---|---|---|---|---|---|---|
database | Database | Database Setup | Yes | No | Infrastructure | — |
cache | Valkey | Valkey/Redis Setup | Yes | No | Infrastructure | — |
migrations | Migrations | Database Migrations | Yes | No | Infrastructure | database |
admin | Admin | Admin Bootstrap | Yes | No | Security | migrations |
crypto | Crypto | Cryptography | Yes | No | Security | admin |
sources | Sources | Advisory & VEX Sources | No | Yes | Release Control Plane | admin |
Notes verified against src/:
- The frontend step id for the Valkey step is
cache(seeToFrontendStepId/TryParseStepIdinSetupEndpoints.cs); theSetupStepIdenum value isValkey. - The Web wizard model (
setup-wizard.models.ts) exposes awelcomeintroductory step increateTruthfulSetupSteps(); it carries no validation checks and is not a backend step. - There is no
assurancestep. It is absent fromSetupStepDefinitions.All, from the WebSetupStepIdunion, and from the CLISetupStepCatalog. Theassurancerows and thecheck.assurance.*identifiers previously documented here do not exist in code — see §4.5.2.
The integration and orchestration catalogs below are historical handoff targets and are not accepted by the current Platform setup API (PlatformSetupService.ProbeStepCoreAsync rejects them) nor surfaced by the stella setup command group’s backend-authoritative flow.
3.2 Integration Handoffs (Not current setup steps)
The Platform backend rejects these step ids. Note that the CLI still ships matching ISetupStep implementations in src/Cli/StellaOps.Cli/Commands/Setup/Steps/Implementations/ (e.g. VaultSetupStep, ScmSetupStep, NotifySetupStep, RegistrySetupStep, SettingsStoreSetupStep, LlmSetupStep, TelemetrySetupStep), and the Web DEFAULT_SETUP_STEPS fallback list still enumerates them — but Identity as a standalone step is not in either inventory (OIDC/LDAP is configured via the authority/admin provider selection and post-bootstrap Identity & Access surfaces).
| Step ID | Name | Required | Skippable | Category | Where actually implemented |
|---|---|---|---|---|---|
vault | Secrets Provider | No | Yes | Integration | CLI step + Web fallback list (not Platform API) |
settingsstore | Settings Store | No | Yes | Integration | CLI step + Web fallback list (not Platform API) |
scm | Source Control | No | Yes | Integration | CLI step + Web fallback list (not Platform API) |
registry | Container Registry | No | Yes | Integration | CLI step + Web fallback list (not Platform API) |
notify / notifications | Notification Channels | No | Yes | Integration | CLI step id is notify; Web fallback uses notify (not Platform API) |
identity | Identity Provider (OIDC/LDAP) | No | Yes | Security | Not implemented as a step; configured via Authority provider + Identity & Access |
3.3 Orchestration Handoffs (Not current setup steps)
The Platform backend rejects these step ids. The CLI registers EnvironmentsSetupStep / AgentsSetupStep and the Web DEFAULT_SETUP_STEPS fallback enumerates them, but they are not part of the backend bootstrap contract.
| Step ID | Name | Required | Skippable | Category | Where actually implemented |
|---|---|---|---|---|---|
environments | Environment Definition | No | Yes | Orchestration | CLI step + Web fallback list (not Platform API) |
agents | Agent Registration | No | Yes | Orchestration | CLI step + Web fallback list (not Platform API) |
4. Step Specifications
Sections 4.1–4.5.1 describe the current installation-scoped setup steps that the Platform API accepts (Database, Valkey, Migrations, Admin, Crypto, Sources). §4.5.2 (Assurance) is not a step — see the annotation there.
Sections 4.6 and later are capability notes, not Platform setup steps. The Platform API rejects these step ids (
ProbeStepCoreAsync→ “is not part of the installation bootstrap contract”). Their inputs belong to: (a) the CLI setup steps undersrc/Cli/StellaOps.Cli/Commands/Setup/Steps/Implementations/, which the CLI runner can execute independently, and (b) authenticated post-bootstrap surfaces (Integrations, Notify, Trust & Signing, Identity & Access, ReleaseOrchestrator). Field/connector tables below were not re-verified line-by-line against each connector implementation; treat them as design reference, and verify against the owning module before relying on a specific field name or default.
4.1 Database Setup (database)
Purpose: Configure PostgreSQL connection and verify accessibility.
Inputs (config keys consumed by ProbeDatabaseAsync / ResolveDatabaseConnectionString):
| Config key | Type | Required | Default | Description |
|---|---|---|---|---|
database.connectionString | secret | No | - | Full Npgsql connection string; takes precedence if provided |
database.host | string | Conditional | - | PostgreSQL host (used with the other discrete fields) |
database.port | number | No | 5432 | PostgreSQL port |
database.database | string | Conditional | - | Database name |
database.user | string | Conditional | - | Database user |
database.password | secret | Conditional | - | Database password |
When no override is supplied, the probe falls back to the platform’s configured Platform:Storage:PostgresConnectionString.
Reconciled: the previously documented
sslModeandpoolSizeinputs are not read by the setup probe (the discrete-field fallback buildsHost=…;Port=…;Database=…;Username=…;Password=…;Timeout=5). SSL/pool tuning is a machine-bootstrap connection-string concern.
Outputs / Validation (reconciled):
- Opens an
NpgsqlConnectionand readsPostgreSqlVersion(this is the connectivity + version check). There is noSELECT 1, no settings-store write of the connection string, and noCREATE SCHEMApermission probe in the current code.
Doctor Checks:
- Step definition (
SetupStepDefinitions) declares:check.database.connectivity,check.database.permissions,check.database.version. - Probe (
ProbeDatabaseAsync) actually emits:check.database.connectivityandcheck.database.version(reports the server version; it does not gate on>= 16and does not run a separatecheck.database.permissionsprobe — connectivity opens anNpgsqlConnection).
Persistence (reconciled):
- The wizard does not persist the database connection string from the step.
ApplyStepCoreAsyncforDatabasereturns “PostgreSQL connectivity verified. Runtime database configuration remains a machine bootstrap concern.” The connection string is resolved fromPlatform:Storage:PostgresConnectionString(machine bootstrap), with optional in-session override fields (database.host/port/database/user/password) used only for the probe. - Sensitive draft values (anything matching password/secret/token/
*.connectionstring) are stored viaPlatformSetupSecretStore, never echoed back, and stripped from applied config.
4.2 Valkey/Redis Setup (valkey)
Purpose: Configure Valkey/Redis for caching, queues, and session storage.
Inputs (config keys consumed by ProbeCacheAsync):
| Config key | Type | Required | Default | Description |
|---|---|---|---|---|
cache.host | string | No | cache.stella-ops.local | Valkey host |
cache.port | number | No | 6379 | Valkey port |
Reconciled: the previously documented
password,database,useTls, andabortOnConnectFailinputs are not read by the setup probe. The quick-check path additionally derivescache.host/cache.portfrom the runtimeConnectionStrings:Redis/Router:Messaging:valkey:ConnectionString/STELLAOPS_VALKEY_URLvalues (BuildCacheConfigFromRuntime).
Outputs / Validation (reconciled):
- Performs a raw TCP
ConnectAsynctohost:port. There is no AUTH, no PING command, and no connection-string write to the settings store. Apply returns “Cache connectivity verified. Runtime cache configuration remains a machine bootstrap concern.”
Doctor Checks:
check.services.valkey.connectivity(the only check emitted; the previously documentedcheck.services.valkey.pingdoes not exist)
4.3 Database Migrations (migrations)
Purpose: Converge the required platform schemas (no pending startup or release migrations).
Inputs (reconciled):
- The migrations step takes no operator inputs.
ProbeMigrationsAsync/ApplyMigrationsAsyncoperate over a fixed setRequiredMigrationModules = ["Platform", "ReleaseOrchestrator"]and callmigrationAdminService.RunAsync(module, category: null, dryRun: false, timeoutSeconds: null). - The previously documented
modules,dryRun, andforceinputs are not part of the setup contract.
Behavior:
- Probe: for each required module, reads status and fails if
PendingReleaseCount + PendingStartupCount > 0or there are checksum errors. - Apply: runs the migration for any module with pending migrations, then re-reads status to confirm convergence. (Migrations is the one step where apply runs even if the probe reported pending — running it is the corrective action.)
Doctor Checks (reconciled):
- Step definition declares:
check.database.migrations.pending. - Probe emits:
check.database.migrations.pending(andcheck.database.migrations.modulewhen a module is missing). - Apply emits:
check.database.migrations.applied. - The previously documented
check.database.migrations.checksumsandcheck.database.schema.versionare not emitted; checksum errors are reported through thepending/appliedchecks.
4.4 Admin Bootstrap (admin)
Purpose: Ensure the bootstrap administrator exists via the Authority service.
Inputs (config keys consumed by ProbeAdminAsync / ApplyAdminAsync):
| Config key | Type | Required | Default | Description |
|---|---|---|---|---|
users.superuser.username | string | Yes | - | Admin username |
users.superuser.email | string | Yes | - | Admin email |
users.superuser.password | secret | Yes | - | Admin password |
users.superuser.displayName | string | No | - | Display name |
authority.provider | string | No | - | Authority provider override passed to the bootstrap request (see normalization below) |
users.additional.{i}.username | string | No | - | Username for optional additional user i (0-based) |
users.additional.{i}.email | string | No | - | Email for additional user i |
users.additional.{i}.password | secret | Conditional | - | Initial password for additional user i (required when a username is present) |
users.additional.{i}.role | string | No | role/service-release-contributor | Authority role bundle for additional user i |
Behavior:
- Apply POSTs the super user to the Authority internal endpoint
internal/userswithRoles: ["admin"]andRequirePasswordReset: false(via theAuthorityInternalHTTP client). - Provider normalization: the wizard surfaces the built-in local provider as
sql(SQL / Local Users), but Authority registers that plugin under the descriptor namestandard(devops/etc/authority.yaml→plugins.descriptors.standard,defaultIdentityProvider: "standard"). Apply mapssql/local/standard→standardbefore forwarding; an empty value defers to Authority’sDefaultIdentityProvider. Without this, the bootstrap fails withSpecified identity provider was not found.. - Additional users: each non-empty
users.additional.{i}row is provisioned with its owninternal/usersPOST carryingRoles: [<role>](defaultrole/service-release-contributor). A row with a username but no password fails the step with a clear message; empty rows are skipped.
Validation (reconciled):
- Username, email, and password are required (presence checks).
- Password minimum length is 12 characters — that is the only complexity rule enforced here. The previously documented “mixed case, numbers, symbols” rule and the “email format” / “username uniqueness” checks are not enforced by the setup probe (uniqueness/idempotency is delegated to Authority’s
internal/usersendpoint). - The probe also calls the Authority
healthendpoint before declaring readiness.
Doctor Checks:
check.auth.admin.existsandcheck.auth.password.policy(payload validation).check.authority.admin.exists(Authority health probe; this is also the single check id declared in the step definition).
4.5 Cryptography (crypto)
Purpose: Choose a regional cryptography profile and prepare optional compliance evidence support (NIS2 / DORA / CRA). This is a required step in the backend contract (the Web shell labels it “Compliance” and treats it as the final touch after the other required steps).
Reconciled — this step does not configure signing keys. The previously documented
profileType(local/kms/hsm/sigstore),keyAlgorithm,keyId,certificatePath,privateKeyPathinputs, the “key material accessible / certificate chain valid” validation, and thecheck.crypto.profile.valid/check.crypto.signing.testchecks do not exist inProbeCryptoAsync/ApplyCryptoAsync/ResolveCryptoSettingsAsync. The step writes a regional profile + compliance flags to the environment settings store; signing-key material is a Trust & Signing / Signer concern outside the setup wizard.
Inputs (config keys consumed by ResolveCryptoSettingsAsync):
| Config key (aliases) | Type | Required | Default | Description |
|---|---|---|---|---|
Crypto:Region (crypto.region, crypto.provider) | enum | No | international | Regional profile; normalized to one of international, eidas, russian, chinese. Aliases such as fips/world/eu/gost/sm/cryptopro are mapped. |
Crypto:FipsMode (crypto.fipsMode, crypto.fips.enabled, fips.enabled) | boolean | No | true only when region alias is fips, else false | FIPS-140 mode (only meaningful for the International profile) |
Compliance:Nis2:Enabled (compliance.nis2.enabled) | boolean | No | false | Enable NIS2 evidence support |
Compliance:Dora:Enabled (compliance.dora.enabled) | boolean | No | false | Enable DORA evidence support |
Compliance:Cra:Enabled (compliance.cra.enabled) | boolean | No | false | Enable CRA evidence support |
When a compliance flag is enabled, the probe additionally looks for prerequisite settings and emits warnings (not failures) if they are missing — e.g. NIS2 checks for an Authority compliance-profile URL, DORA for a Notify channel, CRA for a manufacturer mailbox + intake key fingerprint.
Note: the Web
CRYPTO_PROVIDERScatalog also lists akorean(KCMVP) profile and marksrussianas disabled under European Edition. The backendNormalizeCryptoRegioncurrently maps tointernational/eidas/russian/chineseonly —koreanis a frontend-only option pending backend support.
Outputs:
ApplyCryptoAsyncwrites the canonical settings (Crypto:Region,Crypto:FipsMode,Compliance:Nis2:Enabled,Compliance:Dora:Enabled,Compliance:Cra:Enabled) to the environment settings store.
Doctor Checks (reconciled):
check.crypto.profile— selected regional profile.check.crypto.fips— FIPS-140 mode state (warns if enabled for a non-International profile).check.compliance.nis2.prerequisitescheck.compliance.dora.prerequisitescheck.compliance.cra.prerequisites
4.5.1 Advisory & VEX Sources (sources)
Purpose: Optionally enable advisory and VEX aggregation during bootstrap without forcing operators through the full integrations catalog on first run.
Flow: The Platform step is a thin pass-through. ProbeSourcesAsync / ApplySourcesAsync forward the sources.*-prefixed config to Concelier’s internal setup endpoints (POST internal/setup/advisory-sources/probe and /apply, retried while Concelier reports transient 502/503/504), which own source validation and persistence (ConfiguredAdvisorySourceService).
Inputs (config keys, sources.-prefixed at the wire — verified in Concelier ConfiguredAdvisorySourceService):
| Config key | Type | Required | Default | Description |
|---|---|---|---|---|
sources.mode | enum | Yes | mirror | mirror enables StellaOps Mirror only; manual exposes explicit source selection |
sources.mirror.url | string | When mode=mirror | StellaOps Mirror base endpoint | StellaOps Mirror base URL |
sources.mirror.apiKey | secret | No | - | Optional StellaOps Mirror API key |
sources.enabled | string[] | When mode=manual | [] | Advisory/VEX source IDs to enable |
Reconciled: the previous unprefixed names (
mode,mirror.url, …) are the conceptual fields; the wire keys aresources.*. Onlysources.*keys are forwarded byFilterConfigForStep(Sources, …).
Outputs:
- Selected sources are persisted through Concelier durable source storage (mirror id is
stella-mirror) mirrormode enables onlystella-mirrormanualmode enables only the explicitly selected upstream sources
Validation (enforced in Concelier):
- Mirror URL is normalized/validated as an absolute URI
- Manual mode must select at least one real source
stella-mirroris reserved for mirror mode
Doctor Checks:
check.sources.feeds.configuredcheck.sources.feeds.connectivity
Skip behavior:
- Skipping this optional step leaves advisory and VEX aggregation off
- The integrations Advisory & VEX Sources page must surface that off-state and offer later enablement without rerunning bootstrap
4.5.2 Assurance Packs (assurance) — NOT IMPLEMENTED as a setup step
NOT IMPLEMENTED. There is no
assurancesetup step. It is absent from the backendSetupStepDefinitions.All, from the WebSetupStepIdunion andDEFAULT_SETUP_STEPS, and from the CLISetupStepCatalog. Thecheck.assurance.packs.optional,check.assurance.nis2.soa.prerequisites, andcheck.assurance.cra.publication.preflightidentifiers do not appear anywhere insrc/. The wizard does not probe, apply, skip, or report assurance-pack state.What does exist: (1) the Crypto step (§4.5) carries the optional NIS2 / DORA / CRA compliance evidence enable flags and their prerequisite warnings; (2) Assurance Packs are a post-bootstrap capability surfaced by the Console Compliance feature (
src/Web/StellaOps.Web/src/app/features/compliance/**,assurance-packs.client.ts) and routed through Authority / ExportCenter / Notify / Trust //assurance. The text below is retained only as a forward- looking description of that post-setup capability — it is not a setup-wizard contract.
Intended post-bootstrap behavior (roadmap / Compliance surfaces, not the wizard):
- No Assurance pack is enabled by default; review is non-blocking.
- Enabling a pack configures evidence support and workflow readiness. It is not a legal compliance certification.
- Operators are routed to Authority, ExportCenter, Notify, Trust, and
/assurancesurfaces.
Pack lines (capability notes):
| Pack | Readiness line | Prerequisite groups |
|---|---|---|
| NIS2 Evidence Pack | SoA live-export readiness | Authority compliance profile URL/availability, ExportCenter SoA storage root, signing provider/key, tenant export trust roots |
| CRA Product Security Pack | Local signed export readiness | ExportCenter storage/signing and evidence bundle references |
| CRA Product Security Pack | Live public publication readiness | product-security mailbox delivery/access, non-expired encryption-capable intake key, rotation roles, support lifecycle/publication metadata |
4.6 Vault Integration (vault)
Purpose: Configure secrets management provider.
Multi-Connector Support: Yes - users can add multiple vault integrations.
Connector Options:
| Connector | Default | Description |
|---|---|---|
| HashiCorp Vault | Yes (if detected) | KV v2 secrets engine |
| Azure Key Vault | Yes (if Azure env) | Azure-native secrets |
| AWS Secrets Manager | Yes (if AWS env) | AWS-native secrets |
| File Provider | Fallback | Local file-based secrets |
Inputs (HashiCorp Vault):
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
address | string | Yes | - | Vault server URL |
authMethod | enum | Yes | token | token, approle, kubernetes |
mountPoint | string | No | secret | KV mount point |
token | secret | Conditional | - | Vault token |
roleId | string | Conditional | - | AppRole role ID |
secretId | secret | Conditional | - | AppRole secret ID |
Default Selection Logic:
- If
VAULT_ADDRenv var set → HashiCorp Vault - If Azure IMDS available → Azure Key Vault
- If AWS metadata available → AWS Secrets Manager
- Otherwise → Prompt user
Doctor Checks:
check.integration.vault.connectedcheck.integration.vault.authcheck.integration.vault.secrets.access
4.7 Settings Store Integration (settingsstore)
Purpose: Configure application settings and feature flag providers.
Multi-Connector Support: Yes - users can add multiple settings stores for different purposes.
Connector Options:
| Connector | Priority | Write | Watch | Feature Flags | Labels |
|---|---|---|---|---|---|
| Consul KV | P0 | Configurable | Yes | No | No |
| etcd | P0 | Configurable | Yes | No | No |
| Azure App Configuration | P1 | Read-only | Yes | Yes (native) | Yes |
| AWS Parameter Store | P1 | Configurable | No | No | Via path |
| AWS AppConfig | P2 | Read-only | Yes | Yes (native) | Yes |
| ZooKeeper | P2 | Configurable | Yes | No | No |
| GCP Runtime Config | P2 | Read-only | Yes | No | No |
Inputs (Consul KV):
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
address | string | Yes | - | Consul server URL |
token | secret | No | - | ACL token |
tokenSecretRef | string | No | - | Vault path to ACL token |
writeEnabled | boolean | No | false | Enable write operations |
Inputs (etcd):
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
address | string | Conditional | - | Single endpoint URL |
endpoints | string[] | Conditional | - | Multiple endpoint URLs |
username | string | No | - | Authentication username |
password | secret | No | - | Authentication password |
passwordSecretRef | string | No | - | Vault path to password |
writeEnabled | boolean | No | false | Enable write operations |
Default Selection Logic:
- If
CONSUL_HTTP_ADDRenv var set -> Consul KV - If
ETCD_ENDPOINTSenv var set -> etcd - If Azure IMDS + App Config connection available -> Azure App Configuration
- If AWS metadata +
/stellaops/path exists -> AWS Parameter Store - Otherwise -> Prompt user
Doctor Checks:
check.integration.settingsstore.connectivitycheck.integration.settingsstore.authcheck.integration.settingsstore.readcheck.integration.settingsstore.write(if write enabled)check.integration.settingsstore.latency
4.8 SCM Integration (scm)
Purpose: Configure source control management integrations.
Multi-Connector Support: Yes - users can add GitHub AND GitLab simultaneously.
Connector Options:
| Connector | Description |
|---|---|
| GitHub App | GitHub.com or GHES via App installation |
| GitLab Server | GitLab.com or self-hosted |
| Bitbucket | Bitbucket Cloud or Server |
| Gitea | Self-hosted Gitea |
| Azure DevOps | Azure Repos |
Inputs (GitHub App):
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
appId | string | Yes | - | GitHub App ID |
installationId | string | Yes | - | Installation ID |
privateKey | secret | Yes | - | App private key (PEM) |
apiUrl | string | No | https://api.github.com | API endpoint |
Doctor Checks:
check.integration.scm.github.authcheck.integration.scm.github.permissions
4.9 Notification Channels (notifications)
Purpose: Configure notification delivery channels.
Multi-Connector Support: Yes - multiple channels per type allowed.
Channel Options:
| Channel | Description |
|---|---|
| Slack | Incoming webhook |
| Teams | Incoming webhook |
| SMTP server | |
| Webhook | Generic HTTP POST |
| PagerDuty | Incident alerts |
Inputs (Slack):
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | Yes | - | Channel display name |
webhookUrl | secret | Yes | - | Slack incoming webhook URL |
channel | string | No | - | Default channel override |
username | string | No | StellaOps | Bot username |
iconEmoji | string | No | :shield: | Bot icon |
Doctor Checks:
check.notify.channel.configuredcheck.notify.slack.webhookcheck.notify.delivery.test
4.10 Environment Definition (environments)
Purpose: Define deployment environments (dev, staging, prod).
Inputs:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | Yes | - | Environment slug (lowercase) |
displayName | string | Yes | - | Display name |
orderIndex | number | Yes | - | Pipeline position (0=first) |
isProduction | boolean | No | false | Production flag |
requiredApprovals | number | No | 0 | Approval count |
requireSeparationOfDuties | boolean | No | false | SoD enforcement |
autoPromoteFrom | string | No | - | Auto-promote source |
Validation:
- Production environments require
requiredApprovals >= 1 autoPromoteFrommust reference existing environment with lower orderIndex- Name must match
^[a-z][a-z0-9-]{1,31}$
Doctor Checks:
check.orchestrator.environment.existscheck.orchestrator.environment.valid
4.11 Agent Registration (agents)
Purpose: Register deployment agents with the orchestrator.
Inputs:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | Yes | - | Agent name |
capabilities | string[] | Yes | - | docker, compose, ssh, winrm |
labels | map | No | {} | Agent labels for selection |
Outputs:
- Registration token (one-time, 24-hour expiry)
- Agent installation command
Generated Command:
stella-agent register --token <token> --name <name> --orchestrator-url <url>
Doctor Checks:
check.orchestrator.agent.registeredcheck.orchestrator.agent.healthycheck.orchestrator.agent.certificate
5. Multi-Connector Model
Scope note: the multi-connector model below applies to the CLI/integration connector catalogs and post-bootstrap Integrations surfaces, not to the six-step Platform setup contract. The Platform setup session stores draft values and secret-draft metadata per step (
SetupSession.DraftValues/SecretDrafts); it does not implement per-category connector instances orlastConnectorspreference persistence. Treat instance limits and selection heuristics as design intent unless verified in the owning module.
5.1 Connector Categories
Each integration category supports multiple instances:
| Category | Max Instances | Use Case |
|---|---|---|
| Vault | 5 | Separate vaults per environment |
| Settings Store | 5 | Config from Azure App Config + feature flags from Consul |
| SCM | 10 | GitHub + GitLab + internal Gitea |
| Registry | 10 | ECR + Harbor + internal registry |
| Notifications | 20 | Slack per team + email + PagerDuty |
5.2 Default Connector Selection
The wizard suggests a default connector based on:
Environment Detection:
VAULT_ADDR-> HashiCorp VaultCONSUL_HTTP_ADDR-> Consul KVETCD_ENDPOINTS-> etcd- Azure IMDS -> Azure Key Vault / Azure App Configuration
- AWS metadata -> AWS Secrets Manager / AWS Parameter Store
GITHUB_TOKEN-> GitHubGITLAB_TOKEN-> GitLab
Configuration Files:
- Existing
etc/*.yamlsamples - Docker Compose environment files
- Existing
Repository Defaults:
- Harbor (most commonly used registry)
- Slack (most common notification)
5.3 Last Selected Connector Persistence
The wizard stores user preferences in the settings store:
{
"setupWizard": {
"lastConnectors": {
"vault": "hashicorp-vault",
"settingsstore": "consul-kv",
"scm": "github-app",
"registry": "harbor",
"notifications": "slack"
},
"completedAt": "2026-01-13T10:30:00Z",
"skippedSteps": ["sources"]
}
}
Reconciled:
identityis not a setup step, so it cannot appear inskippedSteps(only the optionalsourcesstep is skippable in the Platform contract). ThislastConnectorsshape is illustrative for the connector catalogs; the Platform setup session does not persist it.
6. Resume/Re-run Behavior
6.1 Idempotency Requirements
All steps must be safe to re-run:
| Step | Re-run Behavior |
|---|---|
database | Verify connection; no changes if already configured |
migrations | Skip already-applied; apply only pending |
admin | Skip if admin exists; offer password reset |
vault | Add new integration; don’t duplicate |
settingsstore | Add new integration; don’t duplicate |
scm | Add new integration; don’t duplicate |
6.2 Re-run and Reconfigure Access (reconciled)
The CLI setup command group (SetupCommandGroup.cs) exposes these subcommands — there is no --reconfigure flag:
stella setup run— run from the beginning or continue from the last checkpoint (--step <database|cache|migrations|admin|crypto>,--skip <step…>,--dry-run,--forceto re-run completed steps,--config,--non-interactive/-y).stella setup resume [--session <id>]stella setup status [--session <id>] [--json]stella setup reset [--step <id> | --all] [--force]stella setup validate --config <path>
On the server side, re-running is supported because steps are idempotent and a session can be re-created with ForceRestart (preserving prior draft values). The Console exposes the wizard at the setup-wizard route; “Settings > Configuration Wizard” is descriptive, not a verified menu label.
7. Security Posture
7.1 Secret Storage
| Secret Type | Storage Location |
|---|---|
| Database password | Vault (if configured) or local keyring |
| Valkey password | Vault (if configured) or local keyring |
| API tokens | Vault integration |
| Private keys | File system with 0600 permissions |
7.2 Redaction Rules
The wizard must never display:
- Full passwords
- API tokens
- Private key contents
- Vault tokens
Display format for sensitive fields:
- Masked:
******** - Partial:
ghp_****1234(first 4 + last 4)
7.3 Audit Trail (reconciled)
Mutating setup endpoints are decorated with .Audited(AuditModules.Platform, AuditActions.Platform.<action>, "setup") — e.g. CreateSetupSession, ExecuteSetupStep, SkipSetupStep, FinalizeSetup (see SetupEndpoints.cs). Admin bootstrap is performed through the Authority internal/users endpoint, so the admin-creation audit lives in Authority.
Reconciled: the previously documented “Timeline service with HLC timestamps” and “Doctor run history for check results” are not the mechanism for setup-action auditing in the current code. Setup uses the Platform audit emission decorator above.
8. Error Handling
8.1 Validation Errors
| Error Type | Behavior |
|---|---|
| Invalid input | Inline error message; prevent progression |
| Connection failure | Show error; offer retry with different params |
| Permission denied | Show required permissions; offer skip (if skippable) |
| Timeout | Show timeout; offer retry with increased timeout |
8.2 Partial Completion
If wizard exits mid-flow:
- Completed steps are persisted
- Resume shows current state
- Doctor checks identify incomplete setup
9. Exit Criteria
9.1 Successful Completion
FinalizeSessionAsync completes the session (Completed) only when:
- All required steps (
Database,Valkey,Migrations,Admin,Crypto) arePassed, otherwise finalize throws unlessForce=true. - The platform readiness summary reports
ReadyToProceed(required dependenciesready), otherwise finalize throws with the blocking dependencies unlessForce=true.
A skipped optional Sources step does not block completion.
9.2 Completion Actions (reconciled)
On finalize success, the code performs:
- Mark the session
Completed(setsCompletedAtUtc). - Delete the session’s secret drafts (
secretStore.DeleteSessionAsync). - Write
SetupComplete=trueto the environment settings store and invalidate the cache, so/platform/envsettings.jsonreportssetup: "complete"and the frontend stops redirecting to the wizard. - Return
nextStepspointing to/setup/integrationsand the Secrets/Integrations surfaces (restartRequired: false).
Reconciled / NOT IMPLEMENTED: the finalize path does not run a full Doctor diagnostic, does not generate a Markdown setup report (
FinalizeSetupSessionResponse.ReportPathisnull), and does not emit asetup.completedtimeline event. Completion is signalled by theSetupCompleteenv-settings flag (SetupStateDetector.SetupCompleteKey). A separatePOST /api/v1/setup/quick-checkshortcut probes database/cache/migrations/authority and sets the same flag without walking the wizard.
Related Documents
- setup-wizard-ux.md — user-experience flows for the CLI and Console wizard (the canonical UX boundary).
- setup-wizard-doctor-contract.md — per-step validation, check IDs, and remediation guidance.
- setup-wizard-inventory.md — orientation map of the setup-related source under
src/. - setup-wizard-sprint-plan.md — implementation plan and milestones.
