feat(NK-WP-0032): admit OpenBao operator loopback callback
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a02b90-83bf-75c2-81c8-aa705414e4d4
This commit is contained in:
parent
6700f1c1c3
commit
61aeafef71
10 changed files with 150 additions and 10 deletions
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
],
|
||||
|
|
|
|||
|
|
@ -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"]
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
],
|
||||
|
|
|
|||
43
sso-mfa/k8s/keycape/test_openbao_client_config.py
Normal file
43
sso-mfa/k8s/keycape/test_openbao_client_config.py
Normal 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()
|
||||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
}
|
||||
|
|
|
|||
87
workplans/NK-WP-0032-openbao-operator-loopback-callback.md
Normal file
87
workplans/NK-WP-0032-openbao-operator-loopback-callback.md
Normal 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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue