Removes the premise Stage 1's bring-your-own credential design was built
on. Confirmed with the user directly: this operator creates and owns
every TerdutServer it manages; there is no hand-deployed or chart-deployed
install it's expected to target or migrate.
- §1: states this explicitly -- the root the rest of this commit hangs off.
- §4.1: spec.credentialsSecretRef (bring-your-own input) removed entirely,
not kept as unused flexibility. status.credentialsSecretRef stays as
pure output.
- §6: self-registration is now the *only* bootstrap path, not one of two --
and, since it's now load-bearing rather than a fallback with an easy
escape hatch, closed the two real crash windows in it properly rather
than leaving them as theoretical gaps: a checkpoint Secret for the raw
admin key between /api/bootstrap and minting the service account, and
adopt-on-409 (§5's general rule) if a prior interrupted attempt already
got that far. A checkpoint lost after being used crosses into the same
fail-closed territory §5's webhook-Secret-loss rule already established
-- same recovery (delete and recreate), not a new, one-off workaround.
- §10: dropped the migrate-an-existing-install narrative and the
chart-Job-vs-operator bootstrap race question entirely -- both
presupposed an install the operator might adopt or race against, which
doesn't exist. Kept the installer-chart framing on its own.
- §13: dropped the now-stale "Helm chart migration execution" deferred item.
§8 (Postgres) needed no change -- it already described both the DSN and
Zalando paths as co-equal, full-design detail, with no sequencing between
them to remove.
It's always the operator's own namespace by construction now (§6), never
anything else, so there was nothing for the field to vary -- key varies
instead (fixed 'token' when self-generated, whatever a human chose when
adopted from spec.credentialsSecretRef).
Traced the actual flow against terdut-server's real source before writing
any Stage 1 controller code, rather than trusting this section's own prior
description of it:
- internal/api/middleware.go's AuthMiddleware hard-rejects with 401 any
request carrying neither a Bearer token nor a session cookie, before
handleListServiceAccounts' own (more permissive) internal check ever
runs. So "on 403, self-lookup via GET /api/service-accounts?name=" --
this section's described fallback -- cannot work unauthenticated; an
earlier draft of this section assumed otherwise.
- That only actually matters in the rare case where this TerdutServer's
own controller loses the /api/bootstrap race... except Stage 1's own
setup (ROADMAP.md) guarantees it loses every time: terdut-server is
deployed via its existing chart, which runs its own bootstrap Job,
before the TerdutServer CR or its controller exist at all. The
self-registration flow was never going to complete for the one scenario
Stage 1 actually exercises.
Fix: spec.credentialsSecretRef (§4.1), bring-your-own -- a human mints an
instance-scoped service account once, manually, with their own admin
session, and hands the controller that Secret directly. This is now the
primary, expected path; self-registration on a genuinely fresh install
(where this controller might actually win the race) stays as the
fallback it was always meant to be, not the only path.
Also corrected: this section's opening paragraph still said "v1-blocking,
not v1-shippable" pending SERVICE-ACCOUNTS.md landing -- confirmed shipped
(internal/api/service_accounts.go, migration 014) since Stage 0's work on
this repo; stale framing removed.
- Add .gitignore (build artifacts, editor swapfiles, envtest testbin).
- Remove the stray .DESIGN.md.swp that was sitting untracked in the repo.
- Carries the DESIGN.md §5/§9/§13 edits from the secret-loss discussion:
fail-closed (not self-healed) TerdutAlertSource webhook Secret loss, and
the corrected RBAC section (the webhook Secret lives in the CR's tenant
namespace, not the operator's own namespace as an earlier draft claimed).
/api/bootstrap is single-shot per install (gated on COUNT(*) FROM
users, confirmed against internal/api/users.go and the chart's
bootstrap-job.yaml), not per identity — the two-identity bootstrap
plan and the delete-Secret-to-rotate runbook this section described
don't work against that. Rewrites §6 points 1/5/6 around a dedicated,
repeatable service-account credential instead (proposed server-side in
terdut-server's new SERVICE-ACCOUNTS.md), notes in §9 that Secret
mirroring is RBAC-sound but still hands out a server-admin-equivalent
credential per consenting namespace, and flags in §10 that chart-vs-
operator bootstrap ownership blocks §6 and needs deciding first.
Updates §13 to mark the service-account type as v1-blocking rather
than a someday improvement, and adds a version-discovery endpoint to
the same list (both this operator and terdut-tui currently detect
server capability by route-probing).