RPF-WP-0035-T02: CCR-2026-0038 service-JWT login lane for secrets-engine-openbao
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Package the reviewed keycape-services JWT mount, secrets-engine-openbao role
and secrets-engine-login-self policy as CCR-2026-0038 and teach the delegated
applier a narrow service-jwt-login request type: fixed mount, generated
login-self policy, allow-listed role/config keys, bounded TTL/uses, refusal on
a foreign mount type and a value-free readback compare. The policy now denies
the client-secret data/metadata paths explicitly (MASON-WP-0009 invariant ii).
Proposed only; founder approval and delegated apply pending.

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

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 327203@bnt-lap001
Assistant-Session: 55028ae3-4914-4bd1-8f5c-815f3527aef0
This commit is contained in:
codex 2026-10-09 00:31:47 +02:00
parent 2e7701f155
commit 0b2e7ddb5f
8 changed files with 680 additions and 15 deletions

View file

@ -516,6 +516,8 @@ def validate_ccr(path: Path) -> tuple[dict[str, Any], list[str], list[str]]:
owner = importlib.util.module_from_spec(spec)
spec.loader.exec_module(owner)
errors.extend(owner.validate_contract(ccr))
elif request_type == "service-jwt-login":
errors.extend(service_jwt_lane().validate(ccr, REPO_DIR))
else:
errors.append("unsupported request_type")
return ccr, errors, warnings
@ -527,14 +529,14 @@ def render_summary(ccr: dict[str, Any], warnings: list[str]) -> str:
frontdoor = ccr["access_frontdoor"]
risk = ccr["risk"]
verification = ccr["verification"]
fields = ", ".join(openbao["fields"])
fields = ", ".join(openbao.get("fields", []))
lines = [
f"Request: {ccr['title']}",
f"CCR: {ccr['id']} ({ccr['status']})",
f"Type: {ccr['request_type']}",
f"Target: {ccr['target']['tenant']}/{ccr['target']['workload']} ({ccr['target']['environment']})",
"Mount/path/field:",
f" {openbao['kv_path']}",
f" {openbao.get('kv_path', '-')}",
f" {fields}",
"Policy:",
f" {openbao.get('policy_name', 'none (attended host delivery)')}",
@ -804,6 +806,19 @@ def string_values(value: Any) -> list[str]:
return []
def service_jwt_lane():
"""Lazy-load scripts/service_jwt_lane.py (request_type service-jwt-login)."""
import importlib.util
spec = importlib.util.spec_from_file_location("service_jwt_lane", REPO_DIR / "scripts/service_jwt_lane.py")
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
def is_service_jwt(ccr: dict[str, Any]) -> bool:
return ccr.get("request_type") == "service-jwt-login"
def applier_policy_violations(ccr: dict[str, Any]) -> list[str]:
violations: list[str] = []
if ccr.get("request_type") != "workload-kv-read":
@ -921,6 +936,8 @@ def applier_policy_violations(ccr: dict[str, Any]) -> list[str]:
def applier_readiness_blockers(ccr: dict[str, Any]) -> list[str]:
if is_service_jwt(ccr):
return service_jwt_lane().readiness_blockers(ccr, REPO_DIR, APPLIER_DRY_RUN_ALLOWED_STATUSES)
blockers: list[str] = []
status = ccr.get("status")
if status not in APPLIER_DRY_RUN_ALLOWED_STATUSES:
@ -935,6 +952,8 @@ def applier_readiness_blockers(ccr: dict[str, Any]) -> list[str]:
def applier_dry_run_payload(ccr: dict[str, Any], warnings: list[str]) -> dict[str, Any]:
if is_service_jwt(ccr):
return service_jwt_lane().dry_run_payload(ccr, REPO_DIR, warnings)
openbao = ccr["openbao"]
auth = openbao["auth"]
auth_path = f"auth/{auth['mount']}/role/{auth['role']}"
@ -1023,6 +1042,8 @@ def applier_confirmation_phrase(ccr: dict[str, Any]) -> str:
def delegated_apply_details(ccr: dict[str, Any], actor: str) -> list[str]:
if is_service_jwt(ccr):
return service_jwt_lane().apply_details(ccr, actor)
openbao = ccr["openbao"]
auth = openbao["auth"]
return [
@ -1183,6 +1204,13 @@ def render_runbook(payload: dict[str, Any]) -> str:
def run_bao_metadata_apply(ccr: dict[str, Any], bao_bin: str, quiet: bool = False) -> None:
if is_service_jwt(ccr):
lane = service_jwt_lane()
try:
lane.run_apply(ccr, REPO_DIR, bao_bin, quiet=quiet)
except (lane.BaoError, subprocess.CalledProcessError) as exc:
fail(str(exc))
return
openbao = ccr["openbao"]
auth = openbao["auth"]
auth_path = f"auth/{auth['mount']}/role/{auth['role']}"
@ -1272,7 +1300,7 @@ def record_evidence_state_hub(
openbao = ccr["openbao"]
summary = (
f"CCR {ccr['id']} evidence {kind}/{result} by {actor}: "
f"status={ccr['status']} path={openbao['kv_path']} "
f"status={ccr['status']} path={openbao.get('kv_path') or 'auth/' + openbao['auth']['mount']} "
f"policy={openbao['policy_name']}; "
+ "; ".join(details)
)
@ -1451,7 +1479,7 @@ def record_lifecycle_state_hub(
summary = (
f"CCR {ccr['id']} lifecycle {action} by {actor}: "
f"status={ccr['status']} readiness={frontdoor.get('readiness')} "
f"resolvable={frontdoor.get('resolvable') is True} path={openbao['kv_path']} "
f"resolvable={frontdoor.get('resolvable') is True} path={openbao.get('kv_path', '-')} "
f"policy={openbao['policy_name']}; reason={reason}; "
+ "; ".join(details)
)
@ -1687,9 +1715,9 @@ def status_payload(ccr: dict[str, Any], warnings: list[str]) -> dict[str, Any]:
"frontdoor_blockers": frontdoor_blocked_by,
"warnings": warnings,
"openbao": {
"mount": openbao["mount"],
"kv_path": openbao["kv_path"],
"fields": openbao["fields"],
"mount": openbao.get("mount"),
"kv_path": openbao.get("kv_path"),
"fields": openbao.get("fields", []),
"policy_name": openbao.get("policy_name"),
"auth_mount": auth.get("mount"),
"auth_method": auth.get("method"),
@ -1845,7 +1873,7 @@ def decision_template_context(ccr: dict[str, Any]) -> dict[str, str]:
state_hub = ccr.get("state_hub", {})
return {
"id": ccr["id"],
"kv_path": openbao["kv_path"],
"kv_path": openbao.get("kv_path") or f"auth/{auth['mount']}",
"policy_name": openbao.get("policy_name"),
"auth_role_path": f"auth/{auth['mount']}/role/{auth['role']}",
"decision_link": state_hub.get("decision_api_url")
@ -2159,7 +2187,7 @@ def command_decision(args: argparse.Namespace, status: str) -> int:
{
"summary": (
f"CCR {ccr['id']} decision {status} by {args.reviewer}: "
f"path={openbao['kv_path']} policy={openbao['policy_name']} "
f"path={openbao.get('kv_path', '-')} policy={openbao['policy_name']} "
f"fields={','.join(openbao['fields'])} "
f"auth_role=auth/{auth['mount']}/role/{auth['role']}; "
f"{args.comment}"