# Evidence: Authority default-tenant bootstrap (AUTH-SEED-002) - **Sprint**: `docs/implplan/SPRINT_20260422_005_Authority_default_tenant_bootstrap.md` - **Task**: AUTH-SEED-002 (fresh-volume verification that the setup-wizard admin flow succeeds without manual SQL inserts). - **Date (UTC)**: 2026-04-22 - **Host**: local dev (Docker Desktop) - **Image rebuilt**: `stellaops/authority:dev` (SHA 01d8c359fb92) — contains new `003_seed_default_tenants.sql` embedded resource. ## Verification summary | # | Step | Status | Artifact | |---|------|--------|----------| | 1 | `docker compose -f docker-compose.stella-ops.yml down -v` (destroy volumes) | PASS | stack stopped, 20 volumes removed incl. `compose_postgres-data` | | 2 | `docker compose -f docker-compose.stella-ops.yml up -d` (fresh volumes) | PASS | 62 containers started, authority healthy in ~15s | | 3 | Authority startup applies migration 003 automatically | PASS | see `06-authority-migration-logs.txt`, `07-schema-migrations.txt` | | 4 | `POST /api/v1/setup/sessions` + `.../steps/admin/execute` with `admin / Admin@Stella2026!` | PASS | see `01-create-session.json`, `03-pre-admin-steps.json`, `04-admin-execute.json` | | 5 | `POST /connect/token` returns 200 + JWT (not `invalid_grant`) | PASS | see `05-connect-token.json` | | 6 | Authority restart against same volume is a clean no-op | PASS | log line `Migration: Database is up to date for Authority.` | ## Key log excerpts ### 3) Migration runner applies 003 on the fresh DB (authority container startup) ``` [14:32:39 INF] Migration: 3 pending startup migration(s) for Authority. [14:32:39 INF] Migration: Applying 001_initial_schema.sql (Startup)... [14:32:39 INF] Migration: 001_initial_schema.sql completed in 144ms. [14:32:39 INF] Migration: Applying 002_drop_deprecated_audit_tables.sql (Startup)... [14:32:39 INF] Migration: 002_drop_deprecated_audit_tables.sql completed in 13ms. [14:32:39 INF] Migration: Applying 003_seed_default_tenants.sql (Startup)... [14:32:39 INF] Migration: 003_seed_default_tenants.sql completed in 7ms. [14:32:39 INF] Migration: Applied 3 migration(s) for Authority in 694ms. ``` ### 3) `authority.schema_migrations` ledger after fresh bring-up ``` migration_name | category | applied_at | duration_ms --------------------------------------+----------+-------------------------------+------------- 001_initial_schema.sql | startup | 2026-04-22 14:32:39.066637+00 | 132 002_drop_deprecated_audit_tables.sql | startup | 2026-04-22 14:32:39.199035+00 | 4 003_seed_default_tenants.sql | startup | 2026-04-22 14:32:39.21278+00 | 3 ``` ### 3) `authority.tenants` rows present after auto-migrate (no manual inserts) ``` tenant_id | name | display_name | status --------------+--------------+---------------------+-------- default | Default | Default Tenant | active installation | Installation | Installation Tenant | active (2 rows) ``` ### 4) Admin bootstrap succeeds via the public setup-wizard HTTP surface Prerequisite steps (`database`, `valkey`, `migrations`) completed cleanly, then: ``` POST /api/v1/setup/sessions/setup-installation-20260422143427/steps/admin/execute → HTTP 200 "stepId":"admin","status":"completed", "message":"Step applied successfully.", validationResults:[{ "checkId":"check.auth.admin.exists","status":"passed", "message":"Bootstrap administrator 'admin' ensured successfully." }] ``` Admin user persisted under the seeded `default` tenant (the FK the setup wizard requires): ``` id | tenant_id | username | status | enabled --------------------------------------+-----------+----------+--------+--------- 07b6e4c4-2a3a-42f0-ae1f-6b3ed4b5ca97 | default | admin | active | t ``` ### 5) `/connect/token` password grant returns a live admin JWT ``` POST https://stella-ops.local/connect/token grant_type=password client_id=stellaops-cli username=admin password=Admin@Stella2026! scope=ui.admin openid → HTTP 200 { "access_token": "eyJ...", "token_type": "Bearer", "expires_in": 1800, ... } ``` Decoded claims show `sub`, `preferred_username=admin`, `role=admin`, `stellaops:tenant=default`, `client_id=stellaops-cli`. ### 6) Authority restart is a pure no-op ``` [14:35:44 INF] Migration: Starting migration check for Authority... [14:35:45 INF] Migration: 1 optional seed migration(s) are pending for Authority. They remain manual-only and will not run at startup. [14:35:45 INF] Run manually when needed: stella system migrations-run --module Authority --category seed [14:35:45 INF] Migration: Database is up to date for Authority. ``` Confirms migration 003 is idempotent (checksum matched, ledger accepted, zero rows changed on replay — the `INSERT ... ON CONFLICT DO NOTHING` protects the seed). ## Artifacts - `01-create-session.json` — `POST /api/v1/setup/sessions` response - `02-admin-execute.json` — first admin-step attempt before prereqs (documents the "Blocked by incomplete dependencies: Migrations" gate that forces the wizard to run the DB/valkey/migrations steps first) - `03-pre-admin-steps.json` — database / valkey / migrations step responses - `04-admin-execute.json` — successful admin-step apply - `05-connect-token.json` — admin token issuance - `06-authority-migration-logs.txt` — full `Migration:` log timeline - `07-schema-migrations.txt` — `authority.schema_migrations` ledger - `08-tenants.txt` — `authority.tenants` contents after fresh bring-up - `09-admin-user.txt` — admin row with `tenant_id='default'` FK reference ## Conclusion The fresh-volume setup flow now completes without any manual SQL insert into `authority.tenants`. The regression that forced two FE-QA agents (`fe-qa-006-relsec`, `fe-qa-007-evidops`) to hand-seed `default` / `installation` during SPRINT_20260421_006/007 is resolved by migration `003_seed_default_tenants.sql`, applied by the Authority persistence assembly's startup migration runner (wired in SPRINT_20260422_003 / AUTH-MIGRATE-002, so no new runtime wiring was required — only the additional embedded SQL resource).