2 Commits

Author SHA1 Message Date
shankar0123 75097909e9 2026-05-05 18:18:29 +00:00
shankar0123 66d2af36a7 domain, migrations: IntermediateCA type + intermediate_cas + Issuer.HierarchyMode
Rank 8 of the 2026-05-03 deep-research deliverable, commit 1 of 5
(cowork/rank-8-intermediate-ca-hierarchy-prompt.md). Closes the multi-
level CA hierarchy gap for FedRAMP boundary-CA, financial-services
policy-CA, and OT network-CA deployments where regulator-mandated
certificate-policy separation requires multiple layers (root → policy
→ issuing).

This commit lands ONLY the foundation — schema, types, repository
interface, postgres implementation. No service / connector / handler
wiring yet. The 5-commit chain is bisectable: this commit can ship
with no operator-visible behavior change until commits 2-5 wire the
service layer + the local-connector tree-mode + admin API + GUI tree
view + operator runbook. The default value for issuers.hierarchy_mode
is 'single' so every existing operator's behavior is byte-identical
post-migration.

Existing scaffolding REUSED (not redefined):
  - internal/crypto/signer.Driver seam — every IntermediateCA carries
    a key_driver_id pointing at the signer.Driver instance that owns
    its private key. Defense in depth: NEVER persist key bytes in a
    row. FileDriver is the production default; future PKCS11Driver /
    CloudKMSDriver close the disk-exposure leg via the same seam.
  - issuers.id row — the new intermediate_cas FK references it.

Files added:
  internal/domain/intermediate_ca.go              — IntermediateCA type,
                                                     IntermediateCAState
                                                     closed enum (active /
                                                     retiring / retired),
                                                     IsValidIntermediateCAState
                                                     + IsTerminal helpers,
                                                     NameConstraint struct
                                                     (RFC 5280 §4.2.1.10
                                                     permitted+excluded
                                                     subtree subset
                                                     semantics for service-
                                                     layer enforcement),
                                                     HierarchyModeSingle /
                                                     HierarchyModeTree
                                                     constants.
  internal/repository/postgres/intermediate_ca.go — IntermediateCARepository
                                                     impl: Create (ica-<slug>
                                                     ID gen, JSONB +
                                                     nullable-column round-
                                                     trip, lib/pq 23505 →
                                                     ErrAlreadyExists),
                                                     Get, ListByIssuer,
                                                     ListChildren,
                                                     UpdateState,
                                                     GetActiveRoot,
                                                     WalkAncestry (recursive
                                                     CTE — single SQL
                                                     round-trip, O(depth)
                                                     rows, leaf-first
                                                     ordering).
  migrations/000028_intermediate_ca_hierarchy.{up,down}.sql
                                                  — idempotent schema.
                                                     issuers.hierarchy_mode
                                                     VARCHAR(20) DEFAULT
                                                     'single'. New
                                                     intermediate_cas table
                                                     with FKs to
                                                     issuers / self
                                                     (parent_ca_id) +
                                                     CHECK constraints
                                                     (closed-enum state,
                                                     not_after >
                                                     not_before, no self-
                                                     parent) + 6 indexes
                                                     (partial-unique
                                                     active root per
                                                     issuer, partial-
                                                     unique name per
                                                     issuer, owning
                                                     issuer, parent,
                                                     state, expiring).

Files modified:
  internal/domain/connector.go      — adds Issuer.HierarchyMode field
                                       with full doc comment + JSON tag.
                                       Empty string ≡ single mode for
                                       back-compat.
  internal/repository/interfaces.go — adds IntermediateCARepository
                                       interface (7 methods).

Verified locally:
  gofmt: clean.
  go vet ./internal/domain/... ./internal/repository/...: exit 0.
  go build ./internal/domain/... ./internal/repository/...: exit 0.

Out of scope for this commit (lands in commits 2-5):
  - service/intermediate_ca.go (CreateRoot / CreateChild / Retire /
    LoadHierarchy / AssembleChain + RFC 5280 §4.2.1.9 path-len +
    §4.2.1.10 NameConstraints subset enforcement + 9 service tests).
  - local connector rewrite + byte-equivalence pin
    (TestLocal_HierarchyMode_SingleVsTree_ByteIdentical — the load-
    bearing backwards-compat refusal-to-ship test).
  - 4 admin-gated handler endpoints + OpenAPI extension + handler tests.
  - web/src/pages/IssuerHierarchyPage.tsx.
  - docs/intermediate-ca-hierarchy.md sysadmin runbook + connectors.md
    row + WORKSPACE-ROADMAP follow-ons.

Reference: cowork/rank-8-intermediate-ca-hierarchy-prompt.md.
2026-05-04 01:53:56 +00:00