6.9 KiB
id, type, title, domain, repo, status, owner, topic_slug, created, updated
| id | type | title | domain | repo | status | owner | topic_slug | created | updated |
|---|---|---|---|---|---|---|---|---|---|
| KEY-WP-0003 | workplan | Bootstrap Console OIDC Login and MFA Verification | netkingdom | key-cape | finished | codex | netkingdom | 2026-05-24 | 2026-05-24 |
KEY-WP-0003 - Bootstrap Console OIDC Login and MFA Verification
Problem
The NetKingdom security bootstrap console now acts as a local OIDC client callback so the operator can verify the dedicated platform-root login before approving custody mode. The current live KeyCape deployment rejects that flow with:
{
"error": "invalid_profile_usage",
"description": "redirect_uri does not match any registered URI",
"feature": "redirect_uri"
}
That error is correct profile enforcement: KeyCape only accepts exact
registered redirect URIs. The live demo-app registration has not yet been
updated to allow the local bootstrap console callback:
http://127.0.0.1:8876/oidc/callbackhttp://localhost:8876/oidc/callback
After that is fixed, there is a second usability/security gap. KeyCape checks
privacyIDEA MFA after the Authelia callback, but the browser flow currently
expects an mfa_token query parameter instead of presenting a proper OTP
challenge page to the human operator.
Goal
Make the bootstrap console's "Start demo OIDC login" button a real end-to-end verification path for the current lightweight IAM stack:
- KeyCape accepts the bootstrap console callback URI by exact registration.
- The browser leaves KeyCape for the public Authelia login URL.
- After password login, KeyCape presents a minimal MFA challenge when privacyIDEA requires one.
- KeyCape issues an OIDC authorization code to the bootstrap console callback.
- The console can exchange the code and let the operator mark
OIDC login verifiedwithout exposing tokens or secrets.
This keeps KeyCape's security posture intact: no wildcard redirect URIs, no dynamic client registration, no token display, and no storage of OTP material.
Design Notes
- Prefer a dedicated public client named
netkingdom-bootstrap-consolefor long-lived clarity. Reusingdemo-appis acceptable for the immediate unblock only if the deployment/runbook clearly labels it as a bootstrap test client. - The bootstrap callback is local-only and operator-attended. It must be an exact URI in config, not a wildcard or dynamic registration exception.
- Browser-facing Authelia redirects must use the public Authelia base URL
(
https://auth.coulomb.social) so the human login page opens correctly. - KeyCape may still need an internal service URL for back-channel token exchange. If so, split the current single Authelia URL into browser-facing authorize URL and internal token URL instead of making the browser use an in-cluster hostname.
- The MFA prompt should collect only a one-time code, post it back to KeyCape, validate with privacyIDEA, and then continue the normal OIDC code flow.
- This work unblocks the NetKingdom custody gate in
NET-WP-0015-platform-root-custody-and-openbao-identity-bootstrap.
Implementation Notes
2026-05-24: Implemented in source:
- added
netkingdom-bootstrap-consoleas a public OIDC client in the sample KeyCape config, while keeping the local callback registered ondemo-appfor compatibility, - split Authelia browser redirects from server-side token exchange via
browserBaseURLandtokenBaseURL, - added a browser MFA challenge page at
POST /authorize/callbackthat validates the one-time code with privacyIDEA before issuing the downstream OIDC authorization code, - updated NetKingdom's
keycape-configgeneration template and bootstrap console to use the dedicated client, - added regression tests for callback registration, split Authelia URLs, MFA challenge rendering, valid OTP continuation, and invalid OTP failure.
Live use still requires deployment: build/publish the updated KeyCape image,
refresh the live keycape-config Secret through the custodian age-key unlock
ceremony, and restart the KeyCape deployment.
T01 - Register the bootstrap console callback client
id: KEY-WP-0003-T01
status: done
priority: high
Add a KeyCape client registration for the bootstrap console. Either create a
dedicated netkingdom-bootstrap-console public client or update demo-app
temporarily with these exact redirect URIs:
http://127.0.0.1:8876/oidc/callbackhttp://localhost:8876/oidc/callback
Update the sample config, tests, and deployment/runbook references so the registered client is reproducible and not just a live-cluster patch.
Gate: an authorize request using the local callback no longer returns
invalid_profile_usage for redirect_uri.
T02 - Separate browser-facing and internal Authelia URLs if needed
id: KEY-WP-0003-T02
status: done
priority: high
Confirm whether the current authelia.baseURL is safe to use for both browser
redirects and server-side token exchange. If not, add explicit configuration
for the browser authorize base URL and internal token/userinfo base URL.
Gate: the first browser redirect leaves https://kc.coulomb.social for
https://auth.coulomb.social/...; server-side token exchange still works from
inside the deployment.
T03 - Add a browser MFA challenge step
id: KEY-WP-0003-T03
status: done
priority: high
When CheckMFARequired returns true after the Authelia callback, render a
minimal KeyCape MFA challenge page instead of requiring mfa_token in the
callback query string. The page should:
- show the authenticated username and client display name,
- collect only the OTP code,
- preserve the pending OIDC state server-side,
- validate with privacyIDEA,
- continue to issue the normal authorization code on success,
- fail closed with the existing telemetry on invalid MFA.
Gate: a user enrolled in privacyIDEA can complete password + OTP in the browser and is returned to the registered downstream callback.
T04 - Add end-to-end profile tests for the bootstrap login path
id: KEY-WP-0003-T04
status: done
priority: medium
Add tests that cover:
- local bootstrap callback registration,
- rejection of unregistered callbacks remains intact,
- Authelia browser redirect uses the expected public URL,
- MFA-required login presents a challenge instead of immediate failure,
- invalid OTP fails closed,
- valid OTP produces an authorization code bound to the original PKCE session.
Gate: make test passes and the negative redirect URI tests remain green.
T05 - Document the live rollout ceremony
id: KEY-WP-0003-T05
status: done
priority: medium
Document the deployment path for updating live KeyCape config without regenerating unrelated secrets. The runbook must fit the NetKingdom custodian age-key model: decrypt or unlock only during an attended ceremony, apply the updated client registration/config, restart KeyCape, and remove plaintext secret material afterward.
Gate: an operator can update the live keycape-config Secret and verify the
bootstrap console OIDC login without printing or committing secrets.