RPF-WP-0057: capabilities-self grant for the hub-writer caller and UI workload role choice (NK-WP-0051-T06)
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s

credential-change.py generates sys/capabilities-self (update) when
openbao.token_capabilities_self is true. Proposed CCR-2026-0045 sets it
for workload-kv-read-reuse-surface-runtime so the ops-mason proof stops
calling sys/capabilities with a root token. The OpenBao login page keeps
its platform-admin button and adds an allow-listed workload role choice.
Repo only; nothing applied to OpenBao or the cluster.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 1041694@bnt-lap001
Assistant-Session: 7af0bb68-ac4a-4ce3-8639-24ddd84c0b52
This commit is contained in:
codex 2026-10-14 23:45:00 +02:00
parent bb6838f588
commit 0f0282a436
12 changed files with 462 additions and 19 deletions

View file

@ -253,6 +253,8 @@ def validate_workload_kv_read(ccr: dict[str, Any], errors: list[str], warnings:
errors.append("openbao.token_self_lifecycle must be boolean")
if "token_revoke_self" in openbao and not isinstance(openbao["token_revoke_self"], bool):
errors.append("openbao.token_revoke_self must be boolean")
if "token_capabilities_self" in openbao and not isinstance(openbao["token_capabilities_self"], bool):
errors.append("openbao.token_capabilities_self must be boolean")
if "kv_metadata" in openbao:
validate_kv_metadata(openbao["kv_metadata"], errors)
fields = [str(field) for field in require_list(openbao.get("fields"), "openbao.fields", errors)]
@ -621,6 +623,11 @@ def generated_policy_hcl(ccr: dict[str, Any]) -> str:
'\npath "auth/token/revoke-self" {\n capabilities = ["update"]\n}\n')
elif openbao.get("token_revoke_self", False):
body += '\npath "auth/token/revoke-self" {\n capabilities = ["update"]\n}\n'
if openbao.get("token_capabilities_self", False):
# NK-WP-0051-T06: the caller proves its own reach. capabilities-self is a
# POST, so the grant is "update"; it reveals capabilities, never values.
body += ('\npath "sys/capabilities-self" {\n'
' capabilities = ["update"]\n}\n')
return body

View file

@ -113,6 +113,11 @@ require_pattern \
"$presets_json" \
'"role"[[:space:]]*:[[:space:]]*"platform-admin"'
require_pattern \
"presets.json offers the workload role selection (NK-WP-0051-T06)" \
"$presets_json" \
'"workloadRoles"'
require_pattern \
"overlay.css hides namespace picker" \
"$overlay_css" \