From f135c0af35edf06cda335a1b3fc60df15b567028 Mon Sep 17 00:00:00 2001 From: codex Date: Sat, 22 Aug 2026 20:56:58 +0200 Subject: [PATCH] Bind audit E2 retry projection to new engagement Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a02669-87ee-7a31-b111-edc95a16e0fa --- .../whitehat-audit-e2-projection-02.yaml | 54 +++++++++++++++++++ .../external-secrets-whitehat-audit-e2-02.hcl | 21 ++++++++ .../audit-core-whitehat-e2-credentials-02.py | 12 +++-- ...t_audit_core_whitehat_e2_credentials_02.py | 14 +++++ 4 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 manifests/whitehat-audit-e2-projection-02.yaml create mode 100644 openbao/policies/external-secrets-whitehat-audit-e2-02.hcl diff --git a/manifests/whitehat-audit-e2-projection-02.yaml b/manifests/whitehat-audit-e2-projection-02.yaml new file mode 100644 index 0000000..2ff8cc2 --- /dev/null +++ b/manifests/whitehat-audit-e2-projection-02.yaml @@ -0,0 +1,54 @@ +# Ephemeral, exact-path projection for WH-ENG-20260822-AUDIT-E2-02. +# Apply only through scripts/audit-core-whitehat-e2-credentials-02.py during +# the approved window. No value is present in this file. +--- +apiVersion: external-secrets.io/v1 +kind: ClusterSecretStore +metadata: + name: openbao-whitehat-audit-e2-02 + labels: + app.kubernetes.io/part-of: railiance-platform + railiance-platform/engagement: WH-ENG-20260822-AUDIT-E2-02 +spec: + provider: + vault: + server: http://openbao.openbao.svc:8200 + path: platform + version: v2 + auth: + kubernetes: + mountPath: kubernetes + role: external-secrets-whitehat-audit-e2-02 + serviceAccountRef: + name: external-secrets + namespace: external-secrets + conditions: + - namespaces: + - whitehat +--- +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: whitehat-e2-audit-credentials + namespace: whitehat + labels: + app.kubernetes.io/part-of: railiance-platform + railiance-platform/engagement: WH-ENG-20260822-AUDIT-E2-02 +spec: + refreshInterval: 1m + secretStoreRef: + kind: ClusterSecretStore + name: openbao-whitehat-audit-e2-02 + target: + name: whitehat-e2-audit-credentials + creationPolicy: Owner + deletionPolicy: Delete + data: + - secretKey: token-a + remoteRef: + key: engagements/WH-ENG-20260822-AUDIT-E2-02/audit-core/token-a + property: token + - secretKey: token-b + remoteRef: + key: engagements/WH-ENG-20260822-AUDIT-E2-02/audit-core/token-b + property: token diff --git a/openbao/policies/external-secrets-whitehat-audit-e2-02.hcl b/openbao/policies/external-secrets-whitehat-audit-e2-02.hcl new file mode 100644 index 0000000..6218ab0 --- /dev/null +++ b/openbao/policies/external-secrets-whitehat-audit-e2-02.hcl @@ -0,0 +1,21 @@ +# Ephemeral read policy for WH-ENG-20260822-AUDIT-E2-02. +# +# The External Secrets Operator may read exactly two per-engagement values. +# It cannot read the audit-core sender registry, the expired -01 engagement, +# or any other engagement path. + +path "platform/data/engagements/WH-ENG-20260822-AUDIT-E2-02/audit-core/token-a" { + capabilities = ["read"] +} + +path "platform/metadata/engagements/WH-ENG-20260822-AUDIT-E2-02/audit-core/token-a" { + capabilities = ["read"] +} + +path "platform/data/engagements/WH-ENG-20260822-AUDIT-E2-02/audit-core/token-b" { + capabilities = ["read"] +} + +path "platform/metadata/engagements/WH-ENG-20260822-AUDIT-E2-02/audit-core/token-b" { + capabilities = ["read"] +} diff --git a/scripts/audit-core-whitehat-e2-credentials-02.py b/scripts/audit-core-whitehat-e2-credentials-02.py index 6fbca9e..a921228 100755 --- a/scripts/audit-core-whitehat-e2-credentials-02.py +++ b/scripts/audit-core-whitehat-e2-credentials-02.py @@ -41,14 +41,14 @@ IDENTITIES = { "tenant": "tenant:trial:whitehat-b-20260822-02", }, } -POLICY = "external-secrets-whitehat-audit-e2" -ROLE = "external-secrets-whitehat-audit-e2" -STORE = "openbao-whitehat-audit-e2" +POLICY = "external-secrets-whitehat-audit-e2-02" +ROLE = "external-secrets-whitehat-audit-e2-02" +STORE = "openbao-whitehat-audit-e2-02" SECRET = "whitehat-e2-audit-credentials" CONFIRM = f"{ENGAGEMENT}:attended" ROOT = Path(__file__).resolve().parents[1] -POLICY_FILE = ROOT / "openbao" / "policies" / "external-secrets-whitehat-audit-e2.hcl" -MANIFEST_FILE = ROOT / "manifests" / "whitehat-audit-e2-projection.yaml" +POLICY_FILE = ROOT / "openbao" / "policies" / "external-secrets-whitehat-audit-e2-02.hcl" +MANIFEST_FILE = ROOT / "manifests" / "whitehat-audit-e2-projection-02.yaml" class ProcedureError(RuntimeError): @@ -185,6 +185,8 @@ def projection_manifest() -> str: rendered = MANIFEST_FILE.read_text(encoding="utf-8") if "data:" not in rendered or "token-a" not in rendered or "token-b" not in rendered: raise ProcedureError("projection manifest is incomplete") + if ENGAGEMENT not in rendered or "WH-ENG-20260822-AUDIT-E2-01" in rendered: + raise ProcedureError("projection manifest is not bound exclusively to this engagement") return rendered diff --git a/tests/test_audit_core_whitehat_e2_credentials_02.py b/tests/test_audit_core_whitehat_e2_credentials_02.py index 57e9963..081ba76 100644 --- a/tests/test_audit_core_whitehat_e2_credentials_02.py +++ b/tests/test_audit_core_whitehat_e2_credentials_02.py @@ -45,6 +45,20 @@ class CredentialProcedureTests(unittest.TestCase): self.assertEqual(2, manifest.count("secretKey: token-")) self.assertNotIn("workloads/audit-core/senders", manifest) self.assertIn("conditions:\n - namespaces:\n - whitehat", manifest) + self.assertIn(module.ENGAGEMENT, manifest) + self.assertNotIn("WH-ENG-20260822-AUDIT-E2-01", manifest) + self.assertIn(module.STORE, manifest) + self.assertIn(module.ROLE, manifest) + + def test_policy_is_bound_only_to_new_exact_paths(self) -> None: + policy = module.POLICY_FILE.read_text(encoding="utf-8") + self.assertEqual(4, policy.count('path "platform/')) + self.assertIn(module.ENGAGEMENT, policy) + self.assertNotIn("WH-ENG-20260822-AUDIT-E2-01", policy) + for path in module.TOKEN_PATHS.values(): + relative = path.removeprefix("platform/") + self.assertIn(f"platform/data/{relative}", policy) + self.assertIn(f"platform/metadata/{relative}", policy) if __name__ == "__main__":