Deployment Prerequisites

Audience: operators installing a Stella Ops deployment or planning to add tenants to one.

This runbook defines the operator prerequisites for adding tenants under a single operator trust boundary. It is anchored in ADR-005.

Trust Boundary

Run Stella Ops inside one operator trust boundary. All tenants in a deployment must share the same operator, security team, incident-response authority, and data-residency posture. Do not expose tenant self-service signup, and do not use one deployment as shared SaaS infrastructure for unrelated tenants.

Tenant Inventory Expectations

Tenants are expected to represent environments, business units, sub-organizations, or other logical scopes under the same operator. When you add a tenant, prove that both stores agree: Authority’s tenant catalog and Platform’s shared.tenants projection must list the same tenant. The QA reference shape for this is the tenant-fairness fixture FIXTURE-T7-001.

Resource Headroom

Operators must monitor shared deployment resources at the deployment level: PostgreSQL volume free space, RustFS or object-store capacity, and router QPS. Stella Ops does not currently enforce per-tenant storage quota, per-tenant object-store quota, or tenant-partitioned router rate limits.

Offboarding

Tenant offboarding is soft-suspend only today through Authority’s POST /console/admin/tenants/{tenantId}/suspend. Hard tenant-delete is manual and cross-database: every service owns its own database, so tenant data sits in each of them. There is no supported product endpoint that deletes all tenant data, validates every database, and records a dry-run audit. The QA plan tracks the hard-delete test shape as TOPO-124.

Release-bundle install sequence

Verified 2026-09-26 against 942a18727c, in devops/release/bundle/install.sh and its PowerShell twin install.ps1, which run the same steps. The bundle README is the customer-facing version.

  1. Check prerequisites. Docker with the Compose v2 plugin, a reachable daemon and openssl (Linux and macOS; PowerShell uses .NET). The installer warns below 4 vCPU, 16 GiB RAM or 50 GB free disk. On Linux, a non-root install that is not uid 10001 also needs setfacl. The bundle must contain docker-compose.pinned.yml, the digest-pinned stack written at release; the installer starts that file only and stops when it is absent (PCD-1, 2026-09-26). The tag-form docker-compose.yml resolves every image to STELLA_VERSION, which is not the tag every service is pinned at, so it is never the start path.
  2. Verify the bundle. When release-manifest.yaml.sig, a public key and cosign are present, the signature must verify or the install stops. Every file checksum in the manifest is then checked; a mismatch stops the install.
  3. Generate .env. From .env.example, each GENERATED_* placeholder gets its own random value, and each STELLAOPS_POSTGRES_<SERVICE>_CONNECTION line gets its own password. The administrator password is drawn to satisfy Authority’s shipped password policy (config/etc/authority/plugins/standard.yaml). A re-run keeps an existing .env and refuses a hand-set administrator password that breaks the policy.
  4. Generate installation key material. Signing keys, the gateway certificate, the per-install CA bundles and the agent CA passphrase; see Installation Secrets.
  5. Prepare runtime directories, then stop here when run with --no-start (-NoStart). That run prints the start command: docker compose --env-file .env -f docker-compose.pinned.yml -f secrets/docker-compose.installation.yml up -d.
  6. Pull images by the pinned references, or use local images with --offline (-Offline).
  7. Start the stack and wait for health. First start runs every service’s own migrations. The installer also stops with Authority’s own reason when Authority logs that it could not create the administrator.
  8. Import the offline vulnerability-data seed. When the bundle carries data/vulnerabilities/mirror-seed.v1.ndjson.sha256, the installer checks the seed bytes against it and imports them into the Vulnerabilities hub through the hub’s own import route. The outcome is recorded in state/vulnerability-seed-import.json; a re-run skips a seed already imported. The seed is third-party data under its sources’ terms, and the installer prints the pointer to third-party-licenses/DATA-NOTICES.md (“Hub mirror seeds”).
  9. Print the console address. The URL uses STELLA_PUBLIC_HOST, the origin Authority registers for the console. With STELLA_BIND_ADDRESS=0.0.0.0 and no public host, the installer warns that browser sign-in will fail.

What the first start configures without an operator step:

Installation Secrets

A release-bundle install generates its per-installation secrets before the first start, and never ships them. install.sh and install.ps1 write them into the bundle directory, where the bundle’s compose file mounts them. A re-run keeps every key file and passphrase that already exists, so a secret is never replaced by accident. The CA bundles under secrets/ca/ are the exception: they are rebuilt on every run from the shipped bundle plus the installation’s gateway certificate. The full list is in the bundle README, section “Secrets and keys the installer generates” (devops/release/bundle/README.md). Three of them decide whether a service starts:

To supply your own custody-managed material instead, place it at the same path before running the installer. The installer keeps it.

What This Deployment Is NOT

Where To Read More