diff --git a/credential-change-requests/CCR-2026-0058-net-kingdom-bind-executor-svc-authelia-write.yaml b/credential-change-requests/CCR-2026-0058-net-kingdom-bind-executor-svc-authelia-write.yaml index 67f904d..60a8e52 100644 --- a/credential-change-requests/CCR-2026-0058-net-kingdom-bind-executor-svc-authelia-write.yaml +++ b/credential-change-requests/CCR-2026-0058-net-kingdom-bind-executor-svc-authelia-write.yaml @@ -3,7 +3,7 @@ kind: credential-change-request schema_version: 1 request_type: workload-kv-write-next-version title: NetKingdom bounded executor writes the next svc-authelia bind version (pilot) -status: approved +status: proposed created: '2026-10-31' updated: '2026-10-31' requester: @@ -87,6 +87,14 @@ agent_fence: data_and_metadata_denied: true note: The svc-authelia data and metadata paths are already denied to coding agents since CCR-2026-0053; setup re-checks the deny before the role is created. +amendments: +- at: '2026-10-31' + by: claude-code + change: 'Policy file corrected: removed required_parameters = ["options"]. OpenBao 2.5.4 + applies it to reads as well, so the executor could not read the version it must name for CAS + (net-kingdom NK-WP-0056-T12 synthetic pilot, docs/evidence/2026-10-31-nk56-t12-synthetic-pilot/). Writes + without options.cas are still refused by cas_required on the key; metadata, delete, sibling and new paths + stay denied (tested). Status reset to proposed: the approved policy file changed, re-approval needed.' lifecycle: role_window: 'Window-scoped (founder decision 2026-10-31, hub c29c6eda): the policy is applied once and grants nothing on its own; the Kubernetes-auth role is created diff --git a/docs/credential-lane-designs/bounded-executor.md b/docs/credential-lane-designs/bounded-executor.md index a3a6ccd..d7de9dc 100644 --- a/docs/credential-lane-designs/bounded-executor.md +++ b/docs/credential-lane-designs/bounded-executor.md @@ -38,7 +38,7 @@ The contract refuses anything wider than: - one exact `platform/workloads/...` path on mount `platform`; no wildcard, no sibling; - policy (generated by `policy_hcl`, artifact `openbao/policies/.hcl`): - `read` + `update` on `platform/data/` only, `required_parameters = ["options"]`, + `read` + `update` on `platform/data/` only (no `required_parameters`: OpenBao applies it to reads too, NK-WP-0056-T12), `allowed_parameters = {data, options}`; plus `lookup-self`/`revoke-self`. No `create` (a missing path is refused, so the executor cannot mint new entries), no `metadata/`, `delete/`, `destroy/`, `undelete/`, list; - key-level `cas_required = true`, set by the attended platform-admin at setup. The engine then refuses diff --git a/openbao/policies/net-kingdom-bind-executor-svc-authelia-write.hcl b/openbao/policies/net-kingdom-bind-executor-svc-authelia-write.hcl index 9b2370f..4c55677 100644 --- a/openbao/policies/net-kingdom-bind-executor-svc-authelia-write.hcl +++ b/openbao/policies/net-kingdom-bind-executor-svc-authelia-write.hcl @@ -1,6 +1,5 @@ path "platform/data/workloads/net-kingdom/directory-binds/svc-authelia" { capabilities = ["read", "update"] - required_parameters = ["options"] allowed_parameters = { "data" = [] "options" = [] diff --git a/scripts/workload_kv_write_next_version.py b/scripts/workload_kv_write_next_version.py index 8572eab..7e6e380 100644 --- a/scripts/workload_kv_write_next_version.py +++ b/scripts/workload_kv_write_next_version.py @@ -34,12 +34,15 @@ DISALLOWED_POLICIES = {"root", "default", "platform-admin"} def policy_hcl(ccr: dict[str, Any]) -> str: - """Exact policy: read and update of one data path; no create, metadata, delete or list.""" + """Exact policy: read and update of one data path; no create, metadata, delete or list. + + No required_parameters: OpenBao applies it to reads as well, so a GET (which carries no `options`) is + refused and the executor cannot learn the version it must name (NK-WP-0056-T12 synthetic pilot, + 2026-10-31). The key's cas_required is what refuses a write without options.cas.""" openbao = ccr["openbao"] suffix = openbao["kv_path"][len("platform/"):] return (f'path "platform/data/{suffix}" {{\n' ' capabilities = ["read", "update"]\n' - ' required_parameters = ["options"]\n' ' allowed_parameters = {\n "data" = []\n "options" = []\n }\n' "}\n\n" 'path "auth/token/lookup-self" {\n capabilities = ["read"]\n}\n\n' diff --git a/tests/test_workload_kv_write_next_version.py b/tests/test_workload_kv_write_next_version.py index a86cb2f..495cfc4 100644 --- a/tests/test_workload_kv_write_next_version.py +++ b/tests/test_workload_kv_write_next_version.py @@ -21,7 +21,10 @@ def test_policy_artifact_matches_contract(): assert path.read_text() == m.policy_hcl(CCR) hcl = m.policy_hcl(CCR) assert '"read", "update"' in hcl and "create" not in hcl and "metadata" not in hcl - assert 'required_parameters = ["options"]' in hcl + # required_parameters would refuse reads too (OpenBao 2.5.4, NK-WP-0056-T12); cas_required on the key + # refuses writes without options.cas + assert "required_parameters" not in hcl + assert '"options" = []' in hcl and '"data" = []' in hcl def test_write_shape_cannot_be_widened():