NK-WP-0056-T10: set cas_required by metadata write (platform-admin has no patch)

First attended setup stopped at cas_required: platform-admin holds
create/read/update/delete/list on platform/*, not patch, so 'kv metadata
patch' was denied. Policies were already applied; nothing after. Now a
metadata write naming only cas_required (KV v2 keeps unnamed fields; checked
on the pinned OpenBao image), guarded by a before/after comparison of
max_versions, delete_version_after and custom_metadata. Receipt of the
stopped attempt kept as evidence.

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

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 5502@bnt-lap001
Assistant-Session: 68b3b02f-5d0f-4e71-8421-796f62e50196
This commit is contained in:
tegwick 2026-10-31 19:42:40 +01:00
parent 634b3a41df
commit 12c9b2df43
3 changed files with 44 additions and 7 deletions

View file

@ -61,7 +61,8 @@ for _lane in LANES.values():
_lane.update(role=_lane['policy'], service_account=SA, namespace=NS,
data_path=_lane['kv'].replace('platform/', 'platform/data/', 1),
metadata_path=_lane['kv'].replace('platform/', 'platform/metadata/', 1))
CAS_KEY = ['-mount=platform', 'workloads/net-kingdom/directory-binds/svc-authelia']
CAS_KEY = 'platform/metadata/workloads/net-kingdom/directory-binds/svc-authelia'
KEPT_METADATA = ('max_versions', 'delete_version_after', 'custom_metadata')
class Refused(Exception):
@ -114,8 +115,22 @@ def policy_check(lane):
return check
def key_metadata():
return data(bao(['read', '-format=json', CAS_KEY]))['data']
def cas_required():
return data(bao(['kv', 'metadata', 'get', '-format=json', *CAS_KEY]))['data'].get('cas_required') is True
return key_metadata().get('cas_required') is True
def set_cas_required():
"""A metadata write that names only cas_required. platform-admin holds update, not patch, on platform/*.
KV v2 changes only the fields a write names (checked on the pinned OpenBao, 2026-10-31); the other settings
are compared before and after anyway."""
before = {k: key_metadata().get(k) for k in KEPT_METADATA}
bao(['write', CAS_KEY, '-'], payload={'cas_required': True})
after = key_metadata()
if {k: after.get(k) for k in KEPT_METADATA} != before: raise Refused('metadata_changed_beyond_cas_required')
def write_role_absent():
@ -137,7 +152,7 @@ def setup(digests, receipt):
ensure('sys/policies/acl/' + lane['policy'], {'policy': lane['policy_text']}, policy_check(lane))
receipt['phase'] = 'cas_required'
if not cas_required():
bao(['kv', 'metadata', 'patch', '-cas-required=true', *CAS_KEY])
set_cas_required()
if not cas_required(): raise Refused('cas_required_not_set')
receipt['phase'] = 'journey_role'
journey = LANES['journey']