feat(NK-WP-0032): admit OpenBao operator loopback callback
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02b90-83bf-75c2-81c8-aa705414e4d4
This commit is contained in:
tegwick 2026-08-23 13:58:18 +02:00
parent 6700f1c1c3
commit 61aeafef71
10 changed files with 150 additions and 10 deletions

View file

@ -25,7 +25,7 @@ Recursive trust rule: Normal tenant admin (even Coulomb) must never suffice to a
- OIDC Provider: KeyCape (issuer https://kc.coulomb.social; conforms to NetKingdom IAM Profile v0.2).
- KeyCape issues tokens with required claims: tenant, principal_type, groups, roles, scope/scp, assurance.
- Registered clients include: netkingdom-bootstrap-console (for console OIDC login), openbao-admin (for OpenBao OIDC auth).
- Redirects: http://localhost:8250/oidc/callback, http://127.0.0.1:8250/oidc/callback, https://bao.coulomb.social/ui/vault/auth/netkingdom/oidc/callback, https://bao.coulomb.social/ui/vault/auth/keycape/oidc/callback.
- Redirects: http://localhost:8250/oidc/callback, http://127.0.0.1:8250/oidc/callback, http://127.0.0.1:18200/ui/vault/auth/netkingdom/oidc/callback, plus the former public browser callbacks during the bounded listener rollback window.
- Groups/roles for bootstrap: net-kingdom-admins (for platform-admin OpenBao policy), net-kingdom-users (for scoped non-root).
- platform-root / king credential: dedicated LLDAP user (separate from personal accounts like tegwick). Password in operator password safe; TOTP via privacyIDEA; roles include platform-root-custodian, openbao-admin, identity-admin.

View file

@ -95,8 +95,10 @@ See T03 retrospective for past realm drift bumps (now partially automated via ru
- Apply keycape-config Secret, restart KeyCape.
- Register bootstrap clients (netkingdom-bootstrap-console, openbao-admin).
- OpenBao admin redirects: localhost CLI callbacks plus
`https://bao.coulomb.social/ui/vault/auth/netkingdom/oidc/callback` for
preferred browser UI login; `keycape` remains a compatibility auth mount.
`http://127.0.0.1:18200/ui/vault/auth/netkingdom/oidc/callback` for the
preferred operator-tunneled browser UI login. The former public callback is
retained only for the bounded listener rollback window; `keycape` remains a
compatibility auth mount.
- Verify OIDC admin login: platform-root obtains OpenBao platform-admin via KeyCape/MFA.
- Evidence: keycape client gates, openbao_oidc_* , oidc_login_verified.
- Validate related in t02 / console.

View file

@ -132,14 +132,16 @@ browser UI callbacks for `bao.coulomb.social`:
```text
http://localhost:8250/oidc/callback
http://127.0.0.1:8250/oidc/callback
http://127.0.0.1:18200/ui/vault/auth/netkingdom/oidc/callback
https://bao.coulomb.social/ui/vault/auth/netkingdom/oidc/callback
https://bao.coulomb.social/ui/vault/auth/keycape/oidc/callback
```
The browser UI callback is paired with the Railiance Platform OpenBao ingress
at `https://bao.coulomb.social`. The preferred browser auth mount is
`netkingdom`; `keycape` remains a compatibility alias. Keep the localhost
callbacks unless there is a separate decision to retire CLI login.
The preferred browser UI callback is paired with the named Railiance Platform
operator tunnel at `http://127.0.0.1:18200`. The public callback remains during
the bounded listener rollback window. The preferred browser auth mount is
`netkingdom`; `keycape` remains a compatibility alias. Keep the CLI callbacks
unless there is a separate decision to retire CLI login.
To add or refresh only the OpenBao client in a live cluster, do not decrypt the
bootstrap secret bundle and do not re-run the full secret generator. Patch the
@ -168,9 +170,10 @@ bash ./configure-openbao-oidc.sh
That script registers the browser UI callbacks on the OpenBao
`auth/netkingdom/role/platform-admin` role and the compatibility
`auth/keycape/role/platform-admin` role. Browser operators should use the
OpenBao UI at `https://bao.coulomb.social`, leave namespace blank, choose
OIDC, set mount path `netkingdom`, and use role `platform-admin`; root-token
browser use is outside the approved operator path.
OpenBao UI at `http://127.0.0.1:18200` through the named
`openbao-ui-railiance01` tunnel, leave namespace blank, choose OIDC, set mount
path `netkingdom`, and use role `platform-admin`; root-token browser use is
outside the approved operator path.
The script prompts for a root/sudo-capable OpenBao token inside the pod TTY.
OpenBao currently requires `oidc_client_secret` for OIDC auth config, while

View file

@ -41,6 +41,7 @@ OPENBAO_POD="${OPENBAO_POD:-openbao-0}"
"allowed_redirect_uris": [
"http://localhost:8250/oidc/callback",
"http://127.0.0.1:8250/oidc/callback",
"http://127.0.0.1:18200/ui/vault/auth/netkingdom/oidc/callback",
"https://bao.coulomb.social/ui/vault/auth/netkingdom/oidc/callback",
"https://bao.coulomb.social/ui/vault/auth/keycape/oidc/callback"
],

View file

@ -126,6 +126,7 @@ clients:
redirectUris:
- "http://localhost:8250/oidc/callback"
- "http://127.0.0.1:8250/oidc/callback"
- "http://127.0.0.1:18200/ui/vault/auth/netkingdom/oidc/callback"
- "https://bao.coulomb.social/ui/vault/auth/netkingdom/oidc/callback"
- "https://bao.coulomb.social/ui/vault/auth/keycape/oidc/callback"
allowedScopes: ["openid", "profile", "email", "groups"]

View file

@ -26,6 +26,7 @@ OPENBAO_CLIENT = {
"redirectUris": [
"http://localhost:8250/oidc/callback",
"http://127.0.0.1:8250/oidc/callback",
"http://127.0.0.1:18200/ui/vault/auth/netkingdom/oidc/callback",
"https://bao.coulomb.social/ui/vault/auth/netkingdom/oidc/callback",
"https://bao.coulomb.social/ui/vault/auth/keycape/oidc/callback",
],

View file

@ -0,0 +1,43 @@
#!/usr/bin/env python3
"""Focused regression tests for the code-defined OpenBao KeyCape client."""
from __future__ import annotations
import importlib.util
import unittest
from pathlib import Path
MODULE_PATH = Path(__file__).with_name("openbao-client-config.py")
SPEC = importlib.util.spec_from_file_location("openbao_client_config", MODULE_PATH)
assert SPEC and SPEC.loader
MODULE = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(MODULE)
LOOPBACK_CALLBACK = "http://127.0.0.1:18200/ui/vault/auth/netkingdom/oidc/callback"
class OpenBaoClientConfigTest(unittest.TestCase):
def test_operator_tunnel_callback_is_required(self) -> None:
self.assertIn(LOOPBACK_CALLBACK, MODULE.OPENBAO_CLIENT["redirectUris"])
def test_missing_operator_tunnel_callback_fails_verification(self) -> None:
client = dict(MODULE.OPENBAO_CLIENT)
client["redirectUris"] = [
uri for uri in MODULE.OPENBAO_CLIENT["redirectUris"] if uri != LOOPBACK_CALLBACK
]
errors = MODULE.client_errors({"clients": [client]}, MODULE.OPENBAO_CLIENT)
self.assertEqual(
errors,
[f"openbao-admin.redirectUris missing: {LOOPBACK_CALLBACK}"],
)
def test_upsert_preserves_unrelated_clients(self) -> None:
config = {"clients": [{"clientId": "unrelated", "clientType": "public"}]}
updated = MODULE.upsert_client(config, MODULE.OPENBAO_CLIENT)
self.assertEqual(updated["clients"][0]["clientId"], "unrelated")
self.assertIn(LOOPBACK_CALLBACK, updated["clients"][1]["redirectUris"])
if __name__ == "__main__":
unittest.main()

View file

@ -48,6 +48,7 @@ probe_redirect() {
}
probe_redirect "CLI" "http://localhost:8250/oidc/callback"
probe_redirect "operator-tunneled browser UI netkingdom mount" "http://127.0.0.1:18200/ui/vault/auth/netkingdom/oidc/callback"
probe_redirect "browser UI netkingdom mount" "https://bao.coulomb.social/ui/vault/auth/netkingdom/oidc/callback"
probe_redirect "browser UI keycape compatibility mount" "https://bao.coulomb.social/ui/vault/auth/keycape/oidc/callback"

View file

@ -187,6 +187,7 @@ if not target:
required_redirects = {
"http://localhost:8250/oidc/callback",
"http://127.0.0.1:8250/oidc/callback",
"http://127.0.0.1:18200/ui/vault/auth/netkingdom/oidc/callback",
"https://bao.coulomb.social/ui/vault/auth/netkingdom/oidc/callback",
"https://bao.coulomb.social/ui/vault/auth/keycape/oidc/callback",
}

View file

@ -0,0 +1,87 @@
---
id: NK-WP-0032
type: workplan
title: "Admit the operator-tunneled OpenBao browser callback"
domain: infotech
repo: net-kingdom
status: blocked
owner: codex
topic_slug: net-kingdom
created: "2026-08-23"
updated: "2026-08-23"
related:
- RMASTER-WP-0020-T09
- RAILIANCE-WP-0027-T03
origin: routed
origin_ref: "State Hub message 5e56b413-d8ec-4718-b432-2debc40498ca"
---
# NK-WP-0032 — OpenBao operator loopback callback
## Goal
Admit the exact callback derived by the ClusterIP-only OpenBao UI gateway when
operators reach it through the named `openbao-ui-railiance01` tunnel, without
weakening MFA or broadening the OpenBao policy.
## T01 — Update and validate the code-defined callback contract
```task
id: NK-WP-0032-T01
status: done
priority: high
```
Add `http://127.0.0.1:18200/ui/vault/auth/netkingdom/oidc/callback` to the
KeyCape `openbao-admin` public-PKCE client, the OpenBao `platform-admin` role
template, bootstrap validation, live authorization verifier, and operator
documentation. Preserve the former public callbacks only for the bounded
listener rollback window.
Completed 2026-08-23. Three focused regression tests, Python compilation, Bash
syntax validation, and `git diff --check` pass.
## T02 — Apply and prove the live KeyCape client addition
```task
id: NK-WP-0032-T02
status: done
priority: high
```
Patch only the code-defined non-secret client configuration, restart KeyCape,
and prove both the live Secret contract and public authorize endpoint accept
the exact loopback URI. Do not record the Secret contents or an authorization
code.
Completed 2026-08-23 on Railiance01. `sso/keycape-config` was patched without
printing decoded data, `deployment/keycape` rolled out successfully, and the
value-safe verifier proved the live client contract, exact loopback redirect,
legacy rollback redirects, and OIDC discovery endpoint. No authorization code
or Secret value was observed.
## T03 — Apply and prove the live OpenBao role addition
```task
id: NK-WP-0032-T03
status: wait
priority: high
```
An attended platform-admin/root-sudo authority must apply the updated role
template to `auth/netkingdom/role/platform-admin`. Record only that the exact
URI is admitted. Do not record a token, accessor, authorization code, callback
query, browser storage, or role response body.
## T04 — Return attended-login evidence to Railiance Platform
```task
id: NK-WP-0032-T04
status: wait
priority: high
```
After T02 and T03 pass, perform one attended MFA login through
`http://127.0.0.1:18200` and return only the success/failure outcome. This task
does not authorize public Ingress retraction; Railiance Platform retains that
separate guarded hold point.