Bind secrets-engine approval reader to confirmed operator group
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a09cbb-87c6-7900-a145-4ce53ba9f1a6
This commit is contained in:
parent
817c122d07
commit
bbff2bfb93
4 changed files with 200 additions and 121 deletions
58
scripts/apply-ccr0019-binding.py
Normal file
58
scripts/apply-ccr0019-binding.py
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
"""Silent attended CCR-2026-0019 metadata apply and readback; no KV reads."""
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
from datetime import datetime, timezone
|
||||
|
||||
REPO = Path('/home/worsch/railiance-platform')
|
||||
ROLE = 'secrets-engine-approval-client-workload-kv-read'
|
||||
POLICY = 'workload-kv-read-secrets-engine-approval-client'
|
||||
RECEIPT = REPO / 'docs/evidence/2026-09-14-ccr0019-operator-binding.json'
|
||||
|
||||
def run(*args):
|
||||
result = subprocess.run(args, cwd=REPO, capture_output=True, text=True, timeout=60)
|
||||
if result.returncode:
|
||||
raise RuntimeError('command_failed')
|
||||
return result.stdout
|
||||
|
||||
def main():
|
||||
if Path.home().parent.name != '.warden-attended-login' or os.getenv('BAO_TOKEN') or os.getenv('VAULT_TOKEN'):
|
||||
raise RuntimeError('attended_envelope_required')
|
||||
identity = json.loads(run('bao', 'token', 'lookup', '-format=json'))['data']
|
||||
if 'platform-admin' not in identity['policies'] or 'root' in identity['policies']:
|
||||
raise RuntimeError('platform_admin_required')
|
||||
run('python3', 'scripts/credential-change.py', 'applier-apply', 'CCR-2026-0019',
|
||||
'--actor', 'operator via attended Warden platform-admin OIDC',
|
||||
'--confirm', 'DELEGATED APPLY CCR-2026-0019', '--quiet')
|
||||
response = json.loads(run('bao', 'read', '-format=json', 'auth/netkingdom/role/' + ROLE))
|
||||
role = response['data']
|
||||
expected = {
|
||||
'bound_claims': {'groups': ['net-kingdom-admins']},
|
||||
'role_type': 'oidc', 'user_claim': 'sub', 'groups_claim': 'groups',
|
||||
}
|
||||
for key, value in expected.items():
|
||||
if role.get(key) != value:
|
||||
raise RuntimeError('role_readback_mismatch')
|
||||
if role.get('token_policies', role.get('policies')) != [POLICY] or role.get('token_ttl', role.get('ttl')) != 900:
|
||||
raise RuntimeError('policy_or_ttl_mismatch')
|
||||
actual = run('bao', 'policy', 'read', POLICY)
|
||||
source = (REPO / 'openbao/policies' / (POLICY + '.hcl')).read_text()
|
||||
if actual.split() != source.split():
|
||||
raise RuntimeError('policy_readback_mismatch')
|
||||
receipt = {
|
||||
'observed_at': datetime.now(timezone.utc).isoformat(), 'ccr_id': 'CCR-2026-0019',
|
||||
'status': 'metadata_applied_and_readback_verified', 'role': ROLE,
|
||||
'group': 'net-kingdom-admins', 'policy': POLICY, 'ttl_seconds': 900,
|
||||
'role_request_id': response.get('request_id'),
|
||||
'attended_platform_admin': True, 'secret_values_read': False,
|
||||
'frontdoor_activated': False, 'positive_negative_delivery_verified': False,
|
||||
'session_revocation': 'performed separately by enclosing Warden command',
|
||||
}
|
||||
RECEIPT.write_text(json.dumps(receipt, indent=2) + '\n')
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except Exception:
|
||||
raise SystemExit(1) from None
|
||||
Loading…
Add table
Add a link
Reference in a new issue