kanidm: OAuth2 clients and account policy are not declared in the provisioning state #275
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#275
Läser in…
Hänvisa till i nytt ärende
Ingen beskrivning angiven.
Ta bort grenen "%!s()"
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?
Two categories of Kanidm state are absent from the provisioning state, so live values are whatever
was set by hand or shipped as an upstream default. Neither is visible to a converge, and neither is
reviewable in git.
1. OAuth2 clients are not declared
roles/kanidm/templates/kanidm-state.json.j2declares an empty map:and the provisioning run passes
--no-auto-remove(roles/kanidm/tasks/main.yml:355), with therole's own comment acknowledging the gap:
So every OAuth2 client is created by hand via
kanidm system oauth2 createand tracked only in therunbook. Consequences:
declares what the client set should be. An undeclared client is indistinguishable from an
intentional one.
(
forgejo,bitborg-web,grafana); confirming that is what actually exists requires queryingthe live server.
their Kanidm landing page and where authorization codes may be sent — exactly the properties that
benefit from review in a PR rather than being set once at a terminal.
Declaring clients means their secrets have to come from vault, so this is not a trivial change —
which is presumably why it was deferred. Worth doing deliberately rather than left implicit.
2. No account policy is declared
The state template declares only
persons,groups, andsystems. There is no account policy,so every policy value is Kanidm's upstream default. Confirmed on the live server:
mfais the upstream default and is a reasonable value — this is not a misconfiguration. Theproblem is that it is not a recorded decision:
for every person, with no diff anywhere in this repo.
auth-expiry,privilege-expiry,password-minimum-length,webauthn-attestation-ca-list,allow-primary-cred-fallback, and the search limits.Note when changing
credential_type_minimum: the CLI shipsreset-*subcommands for the otherpolicy attributes but not for this one, and Kanidm has treated downgrading it as a security
concern. Treat a change as close to one-way and decide the target value deliberately.
Done when
scope maps and redirect URIs, and an undeclared client is visible as drift.
shows up as a diff.
Checked what
kanidm-provisionv1.3.0 can actually express before implementing. The two halves ofthis issue turn out to be very different problems.
Account policy CANNOT be declared — do not add it to the state file
Upstream
src/state.rs:There is no account-policy support anywhere — not on
Group, not onPerson, not inSystems.And since
Statehas no#[serde(deny_unknown_fields)], anaccountPolicykey would be parsedand silently thrown away, producing a state file that looks like it declares the policy while
changing nothing.
That is precisely the failure this role already documents for the dead
service-accountsblock. Sothe naive fix here is actively harmful: it would create a second false declaration.
Real options:
entryManagedBy(d732602). Most consistent with how this repo handles upstream gaps, but it isanother patch to maintain.
kanidm group account-policy credential-type-minimum ….Needs a read-then-set to stay idempotent, since the CLI has setters only —
kanidm group getparses the current value.
is undetected.
Given
credential_type_minimumcurrently equals the upstream default (mfa) and there is noreset-credential-type-minimumsubcommand, option 2 or 3 is proportionate. Option 1 is only worth itif more policy knobs get managed.
OAuth2 clients CAN be declared — including removal
Two consequences worth noting:
present: falseremoves a client declaratively. So the stray dev client can be retired througha reviewed diff and a converge, rather than a manual
kanidm system oauth2 delete— much bettergiven
--no-auto-removemeans nothing else will ever clean it up.enable_localhost_redirectsis a declared boolean, andscope_mapsgovern which groups see anapplication. These are exactly the properties that should be reviewable in a PR rather than set once
at a terminal.
Declaring the three legitimate clients (
forgejo,bitborg-web,grafana) additionally needsbasic_secret_filewired from vault, and a mistake there breaks SSO for the affected service. Thatdeserves its own change with a careful dry-run — it should not ride along with the dev-client removal.
Suggested split
present: falseand let a converge remove it. Small, reviewable,immediately valuable. Blocked on confirming the client's real id via
kanidm system oauth2 list— the display name is "Bitborg Portal (dev)" but the state key is theclient id.
redirect URIs explicit.