RPF-IN-0002: declare tenant-engine audit-core sender ESO policy, role apply script, test
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: sonnet Assistant-Process: 292700@bnt-lap001 Assistant-Session: 42de6b79-9019-4cfd-b49a-6db3bbfe9341
This commit is contained in:
parent
2ec3596c3c
commit
8c44256699
4 changed files with 116 additions and 0 deletions
|
|
@ -26,3 +26,26 @@ resolution: >-
|
|||
Repointed the one live coordinate (scripts/create-t03-approval-requests.py, /home/worsch/flex-auth/examples -> /home/worsch/access-engine/examples), commit d32baa9; file verified present. Runtime/product vocabulary retained.
|
||||
state_hub_intake_id: "01a0f26d-0c87-791e-8cc6-8d09cd794160"
|
||||
```
|
||||
|
||||
## RPF-IN-0002 — tenant-engine audit-core sender token: ESO Kubernetes-auth policy and role
|
||||
|
||||
```yaml
|
||||
id: RPF-IN-0002
|
||||
kind: intake
|
||||
title: "tenant-engine audit-core sender token: ESO Kubernetes-auth policy and role"
|
||||
status: open
|
||||
origin: cross-repo
|
||||
origin_ref: TEN-IN-0005
|
||||
priority: medium
|
||||
owner: railiance-platform
|
||||
requested_by: tenant-engine
|
||||
description: >-
|
||||
Declared 2026-10-03 (founder-approved ops-mason plan
|
||||
tenant-engine-audit-core-sender-projection, rows 2-3):
|
||||
openbao/policies/workload-kv-read-tenant-engine-audit-core-sender-eso.hcl and
|
||||
the attended apply script scripts/openbao-tenant-engine-audit-core-sender-eso-attended.sh
|
||||
(policy + role tenant-engine-audit-core-sender-eso; SA tenant-engine/tenant-engine-eso,
|
||||
audience openbao, 15m ttl/max/explicit max, no default policy). Not applied.
|
||||
Open: attended apply, then the founder-attended KV seed (plan row 7).
|
||||
No RBAC change needed here (see message).
|
||||
```
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
# RPF-IN-0002 (tenant-engine TEN-IN-0005): ESO delivery for ClusterSecretStore
|
||||
# openbao-tenant-engine-audit-core-sender via Kubernetes auth role
|
||||
# tenant-engine-audit-core-sender-eso (SA tenant-engine/tenant-engine-eso).
|
||||
# One exact KV data read.
|
||||
|
||||
path "platform/data/workloads/tenant-engine/audit-core-sender" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
|
||||
path "auth/token/lookup-self" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
|
||||
path "auth/token/revoke-self" {
|
||||
capabilities = ["update"]
|
||||
}
|
||||
47
scripts/openbao-tenant-engine-audit-core-sender-eso-attended.sh
Executable file
47
scripts/openbao-tenant-engine-audit-core-sender-eso-attended.sh
Executable file
|
|
@ -0,0 +1,47 @@
|
|||
#!/bin/sh
|
||||
# RPF-IN-0002: write policy + Kubernetes-auth role for tenant-engine's audit-core
|
||||
# sender ESO lane. Attended, silent, idempotent. Run from a checkout at the
|
||||
# reviewed commit:
|
||||
# BAO_ADDR=http://127.0.0.1:18200 VAULT_ADDR=http://127.0.0.1:18200 \
|
||||
# warden access openbao-platform-admin-login --exec -- \
|
||||
# sh scripts/openbao-tenant-engine-audit-core-sender-eso-attended.sh
|
||||
# Prints nothing (warden fails closed on child output). Exit codes:
|
||||
# 0 ok / already present and identical; 3 existing object differs;
|
||||
# 4 write failed; 5 verify failed. Does not read or write any KV value.
|
||||
exec >/dev/null 2>&1
|
||||
set -u
|
||||
P=workload-kv-read-tenant-engine-audit-core-sender-eso
|
||||
R=tenant-engine-audit-core-sender-eso
|
||||
F="$(dirname "$0")/../openbao/policies/$P.hcl"
|
||||
|
||||
cur=$(bao policy read "$P" 2>/dev/null) || cur=""
|
||||
if [ -n "$cur" ]; then
|
||||
[ "$cur" = "$(cat "$F")" ] || exit 3
|
||||
else
|
||||
bao policy write "$P" "$F" || exit 4
|
||||
fi
|
||||
|
||||
if bao read -format=json "auth/kubernetes/role/$R" >/tmp/.te-role.$$ 2>/dev/null; then
|
||||
python3 - /tmp/.te-role.$$ "$P" <<'PY' || { rm -f /tmp/.te-role.$$; exit 3; }
|
||||
import json,sys
|
||||
d=json.load(open(sys.argv[1]))['data']
|
||||
ok=(d.get('bound_service_account_names')==['tenant-engine-eso']
|
||||
and d.get('bound_service_account_namespaces')==['tenant-engine']
|
||||
and d.get('audience')=='openbao' and d.get('token_policies')==[sys.argv[2]]
|
||||
and d.get('token_ttl')==900 and d.get('token_max_ttl')==900
|
||||
and d.get('token_explicit_max_ttl')==900 and d.get('token_no_default_policy') is True)
|
||||
sys.exit(0 if ok else 1)
|
||||
PY
|
||||
else
|
||||
bao write "auth/kubernetes/role/$R" \
|
||||
bound_service_account_names=tenant-engine-eso \
|
||||
bound_service_account_namespaces=tenant-engine \
|
||||
audience=openbao token_policies="$P" \
|
||||
token_ttl=15m token_max_ttl=15m token_explicit_max_ttl=15m \
|
||||
token_no_default_policy=true || exit 4
|
||||
fi
|
||||
rm -f /tmp/.te-role.$$
|
||||
|
||||
[ "$(bao policy read "$P")" = "$(cat "$F")" ] || exit 5
|
||||
bao read "auth/kubernetes/role/$R" || exit 5
|
||||
exit 0
|
||||
30
tests/test_tenant_engine_audit_core_sender_eso.py
Normal file
30
tests/test_tenant_engine_audit_core_sender_eso.py
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
from pathlib import Path
|
||||
import unittest
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
NAME = 'workload-kv-read-tenant-engine-audit-core-sender-eso'
|
||||
|
||||
|
||||
class TenantEngineSenderPolicyTests(unittest.TestCase):
|
||||
def test_policy_is_one_exact_read_plus_token_self(self):
|
||||
text = (ROOT / 'openbao/policies' / (NAME + '.hcl')).read_text()
|
||||
self.assertEqual(text.count('path "'), 3)
|
||||
for bad in ('*', '/metadata/', '"list"', '"create"', '"delete"', 'senders'):
|
||||
self.assertNotIn(bad, text)
|
||||
self.assertIn('path "platform/data/workloads/tenant-engine/audit-core-sender"', text)
|
||||
self.assertIn('path "auth/token/lookup-self"', text)
|
||||
self.assertIn('path "auth/token/revoke-self"', text)
|
||||
|
||||
def test_attended_script_is_silent_and_binds_one_identity(self):
|
||||
s = (ROOT / 'scripts/openbao-tenant-engine-audit-core-sender-eso-attended.sh').read_text()
|
||||
self.assertIn('exec >/dev/null 2>&1', s)
|
||||
for frag in ('bound_service_account_names=tenant-engine-eso',
|
||||
'bound_service_account_namespaces=tenant-engine',
|
||||
'audience=openbao', 'token_explicit_max_ttl=15m',
|
||||
'token_no_default_policy=true'):
|
||||
self.assertIn(frag, s)
|
||||
self.assertNotIn('kv put', s)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue