Two bugs surfaced live on otech113 2026-05-05 blocking Self-Sovereignty
Cutover end-to-end. Fix both in lockstep:
Bug 1 — bp-self-sovereign-cutover Step 02 (harbor-projects) Job in
`catalyst` namespace was hitting `secret "harbor-core" not found` for
11+ retries because the upstream Harbor `harbor-core` Secret only
exists in the `harbor` namespace and Kubernetes forbids cross-namespace
secretKeyRef. Step 02 was stuck in CreateContainerConfigError forever.
Fix: bp-harbor 1.2.13 → 1.2.14 ships a Catalyst-curated `harbor-admin`
Secret in the `harbor` namespace with Reflector mirror annotations
(allowed-namespaces=catalyst, auto-enabled). The same Secret name
auto-materialises in `catalyst` so the cutover Job's secretKeyRef
resolves natively. Password is randomly generated on first install
(32-char alphanum, 190 bits entropy per feedback_passwords.md) and
preserved across reconciles via `lookup`. The upstream Harbor subchart
consumes it via `existingSecretAdminPassword: harbor-admin`.
bp-self-sovereign-cutover 0.1.16 → 0.1.17 updates
`harbor.adminSecretRef.name` from `harbor-core` to `harbor-admin`.
Bug 2 — The 0.1.16 auto-trigger Helm post-install Job (#933) POSTed
/api/v1/sovereign/cutover/start which sits behind RequireSession
middleware. The Job has no human session cookie — every request 401'd
forever and cutover never started.
Fix: new catalyst-api endpoint POST /api/v1/internal/cutover/trigger
lives OUTSIDE RequireSession and validates the bearer token via the
apiserver's TokenReview API + checks the resolved username matches
the canonical `bp-self-sovereign-cutover-runner` SA. Same engine,
same idempotency, same state machine — different auth surface.
The auto-trigger Job now mounts its projected SA token at
/var/run/secrets/kubernetes.io/serviceaccount/token and sends it
as `Authorization: Bearer <token>`. SA username + accepted list are
runtime-overridable per Inviolable Principle #4.
Tests
- 6 Go unit tests for HandleCutoverInternalTrigger covering happy
path, missing bearer (401), TokenReview rejection (502), wrong SA
(403), idempotency (no Jobs created when complete), wrong method
(405). All pass.
- bp-harbor admin-secret contract test (5 cases) — Secret renders,
HARBOR_ADMIN_PASSWORD key present, Reflector annotations, keep
policy, upstream consumes via existingSecretAdminPassword.
- bp-self-sovereign-cutover cutover-contract test extended with 3
new cases — auto-trigger uses /internal/cutover/trigger, sends
SA bearer token, references harbor-admin (not harbor-core).
- All 12 cutover-contract gates green; all 4 observability-toggle
gates green; helm template + helm lint clean on both charts.
Bootstrap-kit slot pins
- clusters/_template/bootstrap-kit/19-harbor.yaml: 1.2.13 → 1.2.14
- clusters/_template/bootstrap-kit/06a-bp-self-sovereign-cutover.yaml:
0.1.16 → 0.1.17
Closes#935
Co-authored-by: hatiyildiz <269457768+hatiyildiz@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>