Allow platform/suppliers/<supplier>/<account> in credential-change applier
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

WARDEN-WP-0043-T02: supplier account credentials (first: IONOS) live on the
platform mount at exactly two segments under suppliers/. Wildcard, parent,
empty-segment and KV-v2 API-path checks are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 469992@bnt-lap001
Assistant-Session: e4b8e420-df0a-441d-83ae-7f19130594d9
This commit is contained in:
codex 2026-10-09 11:47:09 +02:00
parent 1b36e147e3
commit b77cb41275
2 changed files with 47 additions and 6 deletions

View file

@ -838,20 +838,30 @@ def applier_policy_violations(ccr: dict[str, Any]) -> list[str]:
# WARDEN-WP-0028: platform fleet lanes stay under platform/workloads/;
# client/tenant commercial secrets live on mount tenants/ (exact-path policies).
# WARDEN-WP-0043: supplier account credentials live at
# platform/suppliers/<supplier>/<account> (exactly two segments).
allowed_mount_prefixes = {
"platform": "platform/workloads/",
"tenants": "tenants/",
"platform": ("platform/workloads/", "platform/suppliers/"),
"tenants": ("tenants/",),
}
if mount not in allowed_mount_prefixes:
violations.append(
f"openbao.mount must be one of {sorted(allowed_mount_prefixes)}, got {mount}"
)
else:
prefix = allowed_mount_prefixes[mount]
if not kv_path.startswith(prefix):
prefixes = allowed_mount_prefixes[mount]
if not kv_path.startswith(prefixes):
violations.append(
f"openbao.kv_path for mount {mount!r} must stay under {prefix}"
f"openbao.kv_path for mount {mount!r} must stay under "
+ " or ".join(prefixes)
)
elif kv_path.startswith("platform/suppliers/"):
segments = kv_path[len("platform/suppliers/"):].split("/")
if len(segments) != 2 or not all(segments):
violations.append(
"openbao.kv_path under platform/suppliers/ must be exactly "
"<supplier>/<account>"
)
if any(fragment in kv_path for fragment in ("*", "..", "//")):
violations.append("openbao.kv_path must not contain wildcard, parent, or empty segments")
if "/data/" in kv_path or "/metadata/" in kv_path:
@ -1888,7 +1898,7 @@ def decision_templates(ccr: dict[str, Any] | None = None) -> dict[str, str]:
else:
context = {
"id": "<CCR-ID>",
"kv_path": "<platform/workloads/...> or <tenants/<tenant>/...>",
"kv_path": "<platform/workloads/...>, <platform/suppliers/<supplier>/<account>> or <tenants/<tenant>/...>",
"policy_name": "<workload-kv-read-...>",
"auth_role_path": "auth/<mount>/role/<role>",
"decision_link": "<link State Hub decision>",

View file

@ -771,6 +771,37 @@ class CredentialChangeTests(unittest.TestCase):
violations = credential_change.applier_policy_violations(ccr)
self.assertEqual(violations, [], violations)
def _supplier_ccr(self, kv_path: str) -> dict:
ccr, errors, _warnings = credential_change.validate_ccr(self.sample)
self.assertEqual(errors, [])
ccr["status"] = "approved"
ccr["openbao"]["mount"] = "platform"
ccr["openbao"]["kv_path"] = kv_path
ccr["openbao"]["policy_file"] = ""
return ccr
def test_applier_accepts_platform_suppliers_path(self) -> None:
"""WARDEN-WP-0043-T02 — supplier accounts at platform/suppliers/<s>/<a>."""
ccr = self._supplier_ccr("platform/suppliers/ionos/main")
violations = credential_change.applier_policy_violations(ccr)
self.assertEqual(violations, [], violations)
def test_applier_rejects_malformed_platform_suppliers_paths(self) -> None:
for kv_path in (
"platform/suppliers/ionos",
"platform/suppliers/ionos/main/extra",
"platform/suppliers/*/main",
"platform/suppliers/../workloads/x",
"platform/suppliers/ionos//main",
"platform/data/suppliers/ionos/main",
"platform/other/ionos/main",
):
with self.subTest(kv_path=kv_path):
violations = credential_change.applier_policy_violations(
self._supplier_ccr(kv_path)
)
self.assertNotEqual(violations, [], kv_path)
def test_nonprod_applier_policy_remains_metadata_only(self) -> None:
policy = (
REPO_DIR / "openbao/policies/credential-change-nonprod-applier.hcl"