sbom-nexus/docs/evidence/SBOM-WP-0002-T03-production-history-import-2026-08-22.md
tegwick e83c875150 docs: close production deployment and import gates
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a028f0-a42f-7582-89a8-ebaad7343834
2026-08-22 18:24:44 +02:00

3.6 KiB
Raw Blame History

SBOM-WP-0002 T01–T03 production evidence — 2026-08-22

Dark runtime

SBOM Nexus is deployed privately in namespace sbom-nexus with no Ingress and no admitted caller namespace. The live image is:

forgejo.coulomb.social/coulomb/sbom-nexus@sha256:62929abc91bd7ef2b141f6801171b4d5edae81b625ded4a133196f5da14228f4

Both runtime and migration ExternalSecrets report SecretSynced=True, Alembic revision 0001 is at head, and /state/health reports connected PostgreSQL. rapp-sbom-nexus make verify-live confirmed the digest, health, migration head, and that no secret values were observed.

The first deployment exposed a migration-ownership defect: objects were owned by an expiring migration login, so runtime health failed with PostgreSQL permission denied for table repositories. Because the target was new and had no SBOM snapshots, the four objects were reassigned to the durable sbom_nexus_owner, existing runtime grants were reconciled, and the product was changed to issue SET ROLE sbom_nexus_owner before all future PostgreSQL migrations. Nineteen tests pass with one conditional PostgreSQL skip. The fixed image and package were published and redeployed before projection or history data was loaded.

During the attended OIDC operation, the first OpenBao CLI invocation printed a platform-admin token despite the intended metadata-only flow. That token was immediately revoked with bao token revoke -self before provisioning. A second login used -no-print; only its platform-admin, renewable, and TTL metadata was verified. No token value is retained in Git, State Hub, or this evidence.

Database-owner receipt 6779250b-15a2-4a28-a5fa-7f1e37a97f73 confirms:

  • platform-pg-2 1/1 Ready with continuous archiving healthy;
  • post-migration backup ID 20260822T160352 completed at WAL 00000001000000000000000C;
  • scratch restore became Ready in 51 seconds and matched production schema owner, all four relation owners, runtime SELECT privileges, Alembic revision, row counts, statement timeout, idle transaction timeout, and search path;
  • the actual dynamic runtime lease passed SELECT and denied CREATE TABLE with SQLSTATE 42501;
  • the scratch namespace and copied credential were deleted after proof.

Repository projection

The production projection-only sync selected explicit host id bnt-lap001 and reconciled exactly:

Measure Result
Source/target repositories 120 / 120
Active / inactive 116 / 4
Missing / mismatched / extra 0 / 0 / 0
Snapshots after projection sync 0

The production limit=3 catch-up query selected exactly three repositories in slug order. Checkout availability is false inside the cluster because the workstation paths are projections and are not mounted into the private runtime; future scanners must submit evidence or run where the checkout exists.

Historical import and reconciliation

An empty-target backup existed before import. The read-only preview found 22 snapshots across 18 repositories with 3,123 entries. The production import then reported:

  • 22 imported snapshots;
  • 22/22 legacy snapshot identifiers matched;
  • 3,123/3,123 entries matched;
  • zero missing or mismatched snapshots;
  • all 19 licence groups matched;
  • direct-production copyleft count 4 on both source and target.

The importer was run a second time and returned already_present=22 with the same exact reconciliation, proving production idempotency. Sampled repository views for activity-core, markitect-tool, and railiance-cluster returned their imported latest snapshots. No caller route was switched during T01–T03.