Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
63 lines
3.9 KiB
Python
63 lines
3.9 KiB
Python
#!/usr/bin/env python3
|
|
"""Reviewed silent metadata apply inside the attended OpenBao envelope."""
|
|
import argparse,json,os,subprocess
|
|
from pathlib import Path
|
|
ROOT=Path(__file__).resolve().parents[1]
|
|
POLICY="workload-kv-read-keycape-factor-read"
|
|
ROLE="keycape-factor-workload-kv-read"
|
|
ROLE_PATH="auth/kubernetes/role/"+ROLE
|
|
POLICY_PATH="sys/policies/acl/"+POLICY
|
|
KV="platform/workloads/net-kingdom/keycape-factor-read"
|
|
ROLE_CONFIG={"bound_service_account_names":["keycape-factor-eso"],"bound_service_account_namespaces":["sso"],"audience":"openbao","token_policies":[POLICY],"token_ttl":900,"token_max_ttl":900,"token_no_default_policy":True}
|
|
|
|
def call(*args,payload=None):
|
|
p=subprocess.run(["bao",*args],input=json.dumps(payload) if payload is not None else None,capture_output=True,text=True,timeout=25)
|
|
if p.returncode:raise RuntimeError("OpenBao metadata command rejected: "+args[0]+" "+args[1])
|
|
return json.loads(p.stdout) if p.stdout.strip() else {}
|
|
|
|
def normalized(value):return "".join(value.split())
|
|
|
|
def policy_text(value):return value.get("data",value).get("policy","")
|
|
|
|
def verify_role(data):
|
|
return all(data.get(k)==v for k,v in ROLE_CONFIG.items())
|
|
|
|
def execute(apply=False):
|
|
mounts=call("secrets","list","-format=json")
|
|
if mounts.get("platform/",{}).get("type")!="kv" or str(mounts["platform/"].get("options",{}).get("version"))!="2":raise RuntimeError("Expected existing KV v2 mount")
|
|
auth=call("auth","list","-format=json")
|
|
if auth.get("kubernetes/",{}).get("type")!="kubernetes":raise RuntimeError("Expected existing Kubernetes auth")
|
|
# Capability checks are individual: the CLI interprets multiple arguments as TOKEN PATH.
|
|
capabilities={p:call("token","capabilities","-format=json",p) for p in [POLICY_PATH,ROLE_PATH]}
|
|
if any(not {"create","update"}.issubset(set(c)) and "root" not in c for c in capabilities.values()):raise RuntimeError("Missing metadata administration capabilities")
|
|
policy=(ROOT/"openbao/policies"/(POLICY+".hcl")).read_text()
|
|
if apply:
|
|
# New dedicated names only. Existing objects must match; never overwrite foreign metadata.
|
|
policies=call("policy","list","-format=json")
|
|
if POLICY in policies:
|
|
current=call("policy","read","-format=json",POLICY)
|
|
if normalized(current.get("data",current).get("policy",""))!=normalized(policy):raise RuntimeError("Existing policy differs")
|
|
else:call("write","-format=json",POLICY_PATH,"-",payload={"policy":policy})
|
|
roles=call("list","-format=json","auth/kubernetes/role")
|
|
role_names=roles if isinstance(roles,list) else roles.get("data",{}).get("keys",[])
|
|
if ROLE in role_names:
|
|
if not verify_role(call("read","-format=json",ROLE_PATH).get("data",{})):raise RuntimeError("Existing role differs")
|
|
else:call("write","-format=json",ROLE_PATH,"-",payload=ROLE_CONFIG)
|
|
if not verify_role(call("read","-format=json",ROLE_PATH).get("data",{})):raise RuntimeError("Role readback differs")
|
|
if normalized(policy_text(call("policy","read","-format=json",POLICY)))!=normalized(policy):raise RuntimeError("Policy readback differs")
|
|
return {"operation":"apply" if apply else "preflight","policy":POLICY,"role":ROLE_PATH,"kv_path":KV,"field":"TOKEN","metadata_verified":apply,"secret_values_read":False,"secret_values_written":False}
|
|
|
|
def main():
|
|
parser=argparse.ArgumentParser();parser.add_argument("--apply",action="store_true");parser.add_argument("--receipt",type=Path,required=True);args=parser.parse_args()
|
|
if any(os.environ.get(k) for k in ["OPENBAO_TOKEN","BAO_TOKEN","VAULT_TOKEN"]):return 2
|
|
fd=os.open(args.receipt,os.O_WRONLY|os.O_CREAT|os.O_EXCL,0o600)
|
|
result={"success":False,"phase":"metadata"}
|
|
try:
|
|
result.update(execute(args.apply));result["success"]=True;return 0
|
|
except RuntimeError as exc:
|
|
result["failure"]=str(exc);return 1
|
|
except Exception as exc:
|
|
result["failure_type"]=type(exc).__name__;return 1
|
|
finally:
|
|
os.write(fd,json.dumps(result,indent=2).encode());os.close(fd)
|
|
if __name__=="__main__":raise SystemExit(main())
|