Fix OpenBao role payload handoff
This commit is contained in:
@@ -104,18 +104,31 @@ Role payload:
|
||||
}
|
||||
```
|
||||
|
||||
Equivalent CLI command from an approved OpenBao operator context:
|
||||
Equivalent CLI command from an approved OpenBao operator shell:
|
||||
|
||||
```bash
|
||||
bao write auth/netkingdom/role/whynot-design-workload-kv-read \
|
||||
'bound_claims={"groups":["whynot-design"]}' \
|
||||
groups_claim=groups \
|
||||
policies=workload-kv-read-whynot-design-npm-publish \
|
||||
role_type=oidc \
|
||||
ttl=15m \
|
||||
user_claim=sub
|
||||
role_payload_file="$(mktemp)"
|
||||
trap 'rm -f "$role_payload_file"' EXIT
|
||||
cat >"$role_payload_file" <<'JSON'
|
||||
{
|
||||
"bound_claims": {
|
||||
"groups": [
|
||||
"whynot-design"
|
||||
]
|
||||
},
|
||||
"groups_claim": "groups",
|
||||
"policies": "workload-kv-read-whynot-design-npm-publish",
|
||||
"role_type": "oidc",
|
||||
"ttl": "15m",
|
||||
"user_claim": "sub"
|
||||
}
|
||||
JSON
|
||||
bao write auth/netkingdom/role/whynot-design-workload-kv-read @"$role_payload_file"
|
||||
```
|
||||
|
||||
The OpenBao Web UI console may treat `bound_claims={...}` as a string. Use a
|
||||
raw JSON/API role editor when staying in the UI, or use the shell form above.
|
||||
|
||||
## Non-Secret Reads
|
||||
|
||||
These commands should succeed from an operator-capable identity and do not print
|
||||
|
||||
@@ -375,26 +375,12 @@ def render_plan(ccr: dict[str, Any]) -> str:
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def shell_kv_arg(key: str, value: Any) -> str:
|
||||
if isinstance(value, (dict, list)):
|
||||
encoded = json.dumps(value, sort_keys=True, separators=(",", ":"))
|
||||
elif isinstance(value, bool):
|
||||
encoded = "true" if value else "false"
|
||||
elif value is None:
|
||||
encoded = ""
|
||||
else:
|
||||
encoded = str(value)
|
||||
return shlex.quote(f"{key}={encoded}")
|
||||
|
||||
|
||||
def render_operator_commands(ccr: dict[str, Any]) -> str:
|
||||
openbao = ccr["openbao"]
|
||||
auth = openbao["auth"]
|
||||
auth_path = f"auth/{auth['mount']}/role/{auth['role']}"
|
||||
payload = auth_payload(ccr)
|
||||
role_args = " ".join(
|
||||
shell_kv_arg(key, payload[key]) for key in sorted(payload)
|
||||
)
|
||||
role_payload = json.dumps(payload, indent=2, sort_keys=True)
|
||||
secret_args = " ".join(
|
||||
shlex.quote(f"{field}=<enter-through-approved-custody>")
|
||||
for field in openbao["fields"]
|
||||
@@ -404,7 +390,12 @@ def render_operator_commands(ccr: dict[str, Any]) -> str:
|
||||
"# Run from the railiance-platform repo with an approved OpenBao operator token.",
|
||||
"set -euo pipefail",
|
||||
f"bao policy write {shlex.quote(openbao['policy_name'])} {shlex.quote(openbao['policy_file'])}",
|
||||
f"bao write {shlex.quote(auth_path)} {role_args}",
|
||||
'role_payload_file="$(mktemp)"',
|
||||
'trap \'rm -f "$role_payload_file"\' EXIT',
|
||||
'cat >"$role_payload_file" <<\'JSON\'',
|
||||
role_payload,
|
||||
"JSON",
|
||||
f"bao write {shlex.quote(auth_path)} @\"$role_payload_file\"",
|
||||
"",
|
||||
"# Secret provisioning remains under approved OpenBao/operator custody.",
|
||||
"# Do not paste secret values into Git, State Hub, workplans, logs, or chat.",
|
||||
@@ -414,7 +405,6 @@ def render_operator_commands(ccr: dict[str, Any]) -> str:
|
||||
]
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def validate_or_exit(path: Path) -> tuple[dict[str, Any], list[str]]:
|
||||
ccr, errors, warnings = validate_ccr(path)
|
||||
for warning in warnings:
|
||||
|
||||
@@ -144,8 +144,10 @@ class CredentialChangeTests(unittest.TestCase):
|
||||
"bao write auth/netkingdom/role/whynot-design-workload-kv-read",
|
||||
rendered,
|
||||
)
|
||||
self.assertIn('role_payload_file="$(mktemp)"', rendered)
|
||||
self.assertIn('"bound_claims": {', rendered)
|
||||
self.assertIn(
|
||||
'bound_claims={"groups":["whynot-design"]}',
|
||||
'bao write auth/netkingdom/role/whynot-design-workload-kv-read @"$role_payload_file"',
|
||||
rendered,
|
||||
)
|
||||
self.assertIn(
|
||||
|
||||
Reference in New Issue
Block a user