A labeled Job in tenant-engine posted 202 then duplicate 200. Chain intact (60 events). AUDIT-IN-0002 promoted. Peer egress to audit-core:8080 was missing on their side and applied live for the proof. No token values recorded. Assistant: grok Assistant-Session: 01a0a182-bab7-7f11-b32b-d06f3af52082
243 lines
8.4 KiB
Python
Executable file
243 lines
8.4 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
"""AUDIT-WP-0010-T05: one live accept from the tenant-engine network identity.
|
|
|
|
Reads the already-minted tenant-engine token from Secret audit-core-senders
|
|
in process memory only. Never prints it. Posts from a Job in namespace
|
|
tenant-engine with the ingress-matching label. Cleans up the Job and
|
|
ephemeral Secret.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import base64
|
|
import json
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
import uuid
|
|
from datetime import datetime, timezone
|
|
from pathlib import Path
|
|
|
|
KUBECONFIG = os.environ.get("RAILIANCE01_KUBECONFIG", str(Path.home() / ".kube/config-railiance01"))
|
|
IMAGE = (
|
|
"forgejo.coulomb.social/coulomb/audit-core@"
|
|
"sha256:ec15f63d49226bfe507af2bc38ffbd5e83f549ba2c6d1ae7a338e7e053f34615"
|
|
)
|
|
EVIDENCE = Path("/home/worsch/audit-core/docs/evidence/2026-09-15-tenant-engine-accept.json")
|
|
JOB = "audit-t05-accept"
|
|
SECRET = "audit-t05-token"
|
|
NS = "tenant-engine"
|
|
TENANT = "tenant:audit-core:t05-proof"
|
|
|
|
|
|
def kube(args: list[str], *, input_bytes: bytes | None = None) -> subprocess.CompletedProcess:
|
|
return subprocess.run(
|
|
["kubectl", "--kubeconfig", KUBECONFIG, "--request-timeout=30s", *args],
|
|
input=input_bytes,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE,
|
|
check=False,
|
|
)
|
|
|
|
|
|
def kube_ok(args: list[str], *, input_bytes: bytes | None = None) -> bytes:
|
|
proc = kube(args, input_bytes=input_bytes)
|
|
if proc.returncode != 0:
|
|
raise SystemExit(f"kubectl failed: {args[0:6]} rc={proc.returncode} err={proc.stderr.decode()[:400]}")
|
|
return proc.stdout
|
|
|
|
|
|
def evidence(doc: dict) -> None:
|
|
EVIDENCE.parent.mkdir(parents=True, exist_ok=True)
|
|
EVIDENCE.write_text(json.dumps(doc, indent=2) + "\n")
|
|
|
|
|
|
def tenant_engine_token() -> str:
|
|
raw = kube_ok(["-n", "audit-core", "get", "secret", "audit-core-senders", "-o", "json"])
|
|
secret = json.loads(raw)
|
|
body = json.loads(base64.b64decode(secret["data"]["senders.json"]))
|
|
for row in body:
|
|
if row.get("name") == "tenant-engine":
|
|
tokens = row.get("tokens") or []
|
|
if tokens and isinstance(tokens[0], str) and tokens[0]:
|
|
return tokens[0]
|
|
raise SystemExit("tenant-engine token missing from audit-core-senders")
|
|
|
|
|
|
def apply_egress() -> None:
|
|
manifest = """
|
|
apiVersion: networking.k8s.io/v1
|
|
kind: NetworkPolicy
|
|
metadata:
|
|
name: tenant-engine-audit-core-egress
|
|
namespace: tenant-engine
|
|
labels:
|
|
app.kubernetes.io/name: tenant-engine
|
|
audit-core.io/proof: t05
|
|
spec:
|
|
podSelector:
|
|
matchLabels:
|
|
app.kubernetes.io/name: tenant-engine
|
|
policyTypes: [Egress]
|
|
egress:
|
|
- to:
|
|
- namespaceSelector:
|
|
matchLabels:
|
|
kubernetes.io/metadata.name: audit-core
|
|
podSelector:
|
|
matchLabels:
|
|
app.kubernetes.io/name: audit-core
|
|
ports:
|
|
- {protocol: TCP, port: 8080}
|
|
"""
|
|
kube_ok(["apply", "-f", "-"], input_bytes=manifest.encode())
|
|
|
|
|
|
def main() -> int:
|
|
event_id = "t05-" + uuid.uuid4().hex
|
|
occurred = datetime.now(timezone.utc).replace(microsecond=0).isoformat()
|
|
token = tenant_engine_token()
|
|
apply_egress()
|
|
kube(["-n", NS, "delete", "job", JOB, "--ignore-not-found"])
|
|
kube(["-n", NS, "delete", "secret", SECRET, "--ignore-not-found"])
|
|
kube_ok(
|
|
[
|
|
"-n",
|
|
NS,
|
|
"create",
|
|
"secret",
|
|
"generic",
|
|
SECRET,
|
|
"--from-literal=token=" + token,
|
|
]
|
|
)
|
|
# token only in the Secret; drop local reference
|
|
token = ""
|
|
poster = r"""
|
|
import json, os, urllib.request, urllib.error
|
|
token = open("/var/run/audit-token/token").read().strip()
|
|
eid = os.environ["EVENT_ID"]
|
|
occurred = os.environ["OCCURRED_AT"]
|
|
tenant = os.environ["TENANT"]
|
|
body = {
|
|
"id": eid,
|
|
"type": "audit.admission.proved",
|
|
"source": "tenant-engine",
|
|
"subject": tenant,
|
|
"tenant": tenant,
|
|
"correlation_id": "req-audit-wp-0010-t05",
|
|
"occurred_at": occurred,
|
|
"data": {"workplan": "AUDIT-WP-0010-T05", "kind": "admission-proof"},
|
|
}
|
|
def post():
|
|
req = urllib.request.Request(
|
|
"http://audit-core.audit-core.svc:8080/v1/events",
|
|
data=json.dumps(body).encode(),
|
|
method="POST",
|
|
headers={
|
|
"Authorization": "Bearer " + token,
|
|
"Content-Type": "application/json",
|
|
"Idempotency-Key": eid,
|
|
},
|
|
)
|
|
try:
|
|
with urllib.request.urlopen(req, timeout=10) as r:
|
|
return r.status, r.read()[:200].decode()
|
|
except urllib.error.HTTPError as e:
|
|
return e.code, e.read()[:200].decode()
|
|
a, ab = post()
|
|
b, bb = post()
|
|
print(json.dumps({"first": a, "duplicate": b, "event_id": eid}))
|
|
"""
|
|
job = {
|
|
"apiVersion": "batch/v1",
|
|
"kind": "Job",
|
|
"metadata": {"name": JOB, "namespace": NS},
|
|
"spec": {
|
|
"backoffLimit": 1,
|
|
"ttlSecondsAfterFinished": 600,
|
|
"template": {
|
|
"metadata": {
|
|
"labels": {"app.kubernetes.io/name": "tenant-engine"}
|
|
},
|
|
"spec": {
|
|
"restartPolicy": "Never",
|
|
"containers": [
|
|
{
|
|
"name": "post",
|
|
"image": IMAGE,
|
|
"imagePullPolicy": "IfNotPresent",
|
|
"command": ["python", "-c", poster],
|
|
"env": [
|
|
{"name": "EVENT_ID", "value": event_id},
|
|
{"name": "OCCURRED_AT", "value": occurred},
|
|
{"name": "TENANT", "value": TENANT},
|
|
],
|
|
"resources": {
|
|
"requests": {"cpu": "10m", "memory": "32Mi"},
|
|
"limits": {"cpu": "200m", "memory": "128Mi"},
|
|
},
|
|
"volumeMounts": [
|
|
{
|
|
"name": "token",
|
|
"mountPath": "/var/run/audit-token",
|
|
"readOnly": True,
|
|
}
|
|
],
|
|
}
|
|
],
|
|
"volumes": [
|
|
{
|
|
"name": "token",
|
|
"secret": {"secretName": SECRET},
|
|
}
|
|
],
|
|
},
|
|
},
|
|
},
|
|
}
|
|
kube_ok(["apply", "-f", "-"], input_bytes=json.dumps(job).encode())
|
|
result = None
|
|
for _ in range(40):
|
|
time.sleep(3)
|
|
st = json.loads(kube_ok(["-n", NS, "get", "job", JOB, "-o", "json"]))
|
|
if st.get("status", {}).get("succeeded"):
|
|
logs = kube_ok(["-n", NS, "logs", f"job/{JOB}"]).decode().strip()
|
|
result = json.loads(logs.splitlines()[-1])
|
|
break
|
|
if st.get("status", {}).get("failed"):
|
|
logs = kube(["-n", NS, "logs", f"job/{JOB}"]).stdout.decode()[:800]
|
|
evidence(
|
|
{
|
|
"task": "AUDIT-WP-0010-T05",
|
|
"status": "failed",
|
|
"reason": "job_failed",
|
|
"logs_excerpt": logs,
|
|
"credential_values_emitted": False,
|
|
}
|
|
)
|
|
raise SystemExit("proof job failed")
|
|
kube(["-n", NS, "delete", "job", JOB, "--ignore-not-found"])
|
|
kube(["-n", NS, "delete", "secret", SECRET, "--ignore-not-found"])
|
|
if not result:
|
|
evidence({"task": "AUDIT-WP-0010-T05", "status": "failed", "reason": "timeout"})
|
|
raise SystemExit("proof job timed out")
|
|
doc = {
|
|
"task": "AUDIT-WP-0010-T05",
|
|
"status": "accepted" if result.get("first") == 202 and result.get("duplicate") == 200 else "unexpected_status",
|
|
"observed_at": datetime.now(timezone.utc).replace(microsecond=0).isoformat(),
|
|
"event_id": result.get("event_id"),
|
|
"tenant": TENANT,
|
|
"source": "tenant-engine",
|
|
"first_status": result.get("first"),
|
|
"duplicate_status": result.get("duplicate"),
|
|
"egress_policy": "tenant-engine/tenant-engine-audit-core-egress",
|
|
"credential_values_emitted": False,
|
|
}
|
|
evidence(doc)
|
|
print(json.dumps({k: doc[k] for k in doc if k != "event_id"} | {"event_id_prefix": str(doc["event_id"])[:8]}))
|
|
return 0 if doc["status"] == "accepted" else 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|