fix(kanidm): remove the silently-discarded service-accounts block; correct the claim #267
Inga granskare
Etiketter
Inga etiketter
area/backups
area/ci
area/control-panel
area/identity
area/infra
area/observability
area/payments
area/security
area/storage
area/web
blocked
needs-info
needs-triage
ready-for-implementation
type
bug
type
chore
type
docs
type
epic
type
feature
type
task
wontfix
Ingen milstolpe
Inget projekt
Inga tilldelade
1 deltagare
Notiser
Förfallodatum
Inget förfallodatum satt.
Beroenden
Inga beroenden satta
Referens
bitborg/bitborg-infra!267
Läser in…
Hänvisa till i nytt ärende
Ingen beskrivning angiven.
Ta bort grenen "fix/kanidm-state-dead-service-accounts"
Borttagning av en gren är permanent. Även om den borttagna grenen kan fortsätta existera en kort tid innan den faktiskt tas bort, kan det INTE ångras i de flesta fall. Vill du fortsätta?
kanidm-state.json.j2declared a"service-accounts"block, and the role defaults stated "Theaccount + its group memberships are declared in kanidm-state.json.j2 so kanidm-provision manages
them."
Half of that was false. The block was dead. Verified against upstream v1.3.0
src/state.rs:Three fields, and no
#[serde(deny_unknown_fields)]— so serde parsed"service-accounts", foundno matching field, and discarded it without a warning. Service-account support is upstream PR #29,
unreviewed for 12 months.
The template's own comment already flagged it as unresolved — "⚠️ VERIFY the exact key name
service-accountsand the object shape against kanidm-provision's schema". That verification wasnever done, and the answer turns out to be "it does not exist".
What is actually true
_sa_group_membersmerges it into thegroupsblockThis is the same shape of latent gap as the
entry-managed-bydelegation that broke sign-up for 13days: something assumed declarative that never was. Better removed than left looking managed.
Two things now documented in the runbook
groupsnames the account as a member, a fresh host must havethe service account created before this role provisions, or those member writes reference a
nonexistent entity. Full rebuild sequence added (recover idm_admin → create SA + token →
set-entry-manager→ apply → drill)."present": falsedeletes regardless of--no-auto-remove. That flag only gates removal oforphans — entities dropped from the state file. Nothing here uses
present: falsetoday; the noteexists so nobody reaches for it expecting the flag to protect them.
Verification
Rendered the template offline with representative vars (ansible's bundled Jinja2 + PyYAML):
Top-level keys now match upstream's struct exactly, so nothing is silently dropped any more, and the
memberships that are managed still are.
--syntax-checkpasses;ansible-lintclean atproduction;markdownlintclean.Note: an earlier attempt to verify this from the
--check --diffoutput failed, because a unified diffcontains only changed hunks — parsing its
+lines as standalone JSON cannot work. Rendering thetemplate is the correct test.
`kanidm-state.json.j2` declared a `"service-accounts"` block, and the role defaults stated "The account + its group memberships are declared in kanidm-state.json.j2 so kanidm-provision manages them." Half of that was false. The block was DEAD. Verified against upstream v1.3.0 `src/state.rs`: #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] pub struct State { pub groups: …, pub persons: …, pub systems: … } Three fields, and no `#[serde(deny_unknown_fields)]` — so serde parsed `"service-accounts"`, found no matching field, and discarded it without a warning. Service-account support is upstream PR #29, unreviewed for 12 months. The template's own comment already flagged this as unresolved: "⚠️ VERIFY the exact key name "service-accounts" and the object shape against kanidm-provision's schema". That verification was never done, and the answer was "it does not exist". What is actually true: - The service account's GROUP MEMBERSHIPS are managed — _sa_group_members merges it into the `groups` block, and the rendered state declares gitborg-web-provision as a member of idm_people_on_boarding, idm_people_admins and idm_gitborg_ent_managers. - The ACCOUNT OBJECT is not. It is a manual bootstrap, created by hand at the same time as its API token. This is the same shape of latent gap as the entry-managed-by delegation that broke sign-up for 13 days: something assumed declarative that never was. Worth removing rather than leaving in place looking managed. Also documents two things in the runbook: - A rebuild-ordering hazard: because `groups` names the account as a member, a fresh host must have the service account created BEFORE this role provisions, or those member writes reference a nonexistent entity. Full rebuild sequence added. - `"present": false` DELETES regardless of `--no-auto-remove` — that flag only gates removal of orphans (entities dropped from the state file). Nothing here uses present:false today; the note exists so nobody reaches for it expecting protection. Verified by rendering the template offline with representative vars: the output is valid JSON, its top-level keys are exactly groups/persons/systems (matching upstream's struct, so nothing is silently dropped any more), `service-accounts` is gone, and the service account is still declared as a member of the three privilege groups.7a3ae4d0bdfbd691a515