ops-mason/tests/test_construct_policy.py
tegwick e7a368af0f MASON-IN-0005: restore ops-mason as the OpenBao builder (ops-mason-construct)
Founder decision 2026-10-18, "build, but never log in": a plan-scoped grant
that writes workload-kv-read-* policies, external-secrets-* and AppRole role
definitions, and create-only placeholder KV under platform/{workloads,suppliers},
and denies role-id, secret-id, token creation and all value reads, so the
MASON-IN-0004 chain stays broken. Adds bao-session.sh build, policy tests,
INTENT/AGENTS alignment and MASON-WP-0015. Not installed.

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

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 278674@bnt-lap001
Assistant-Session: 64827407-e196-4ce3-b70c-76e7b537493f
2026-10-18 11:48:27 +02:00

68 lines
2.4 KiB
Python

"""ops-mason-construct can build a lane but never log in as one (MASON-IN-0005)."""
import re
from pathlib import Path
POLICY = Path(__file__).resolve().parents[1] / "policies" / "ops-mason-construct.hcl"
def _stanzas() -> dict[str, str]:
text = "\n".join(line.split("#", 1)[0] for line in POLICY.read_text().splitlines())
return {
m.group(1): m.group(2)
for m in re.finditer(r'path\s+"([^"]+)"\s*\{(.*?)\n?\s*\}\s*(?=path|\Z)', text, re.S)
}
def _caps(body: str) -> set[str]:
m = re.search(r"capabilities\s*=\s*\[([^\]]*)\]", body)
return set(re.findall(r'"(\w+)"', m.group(1))) if m else set()
def test_login_and_value_paths_are_denied():
stanzas = _stanzas()
for path in [
"auth/approle/role/+/role-id",
"auth/approle/role/+/secret-id",
"auth/approle/role/+/secret-id/*",
"auth/approle/role/+/custom-secret-id",
"auth/token/create",
"auth/token/create/*",
"auth/token/create-orphan",
"platform/data/*",
"operators/data/*",
"secret/data/*",
"sys/policies/acl/ops-mason-construct",
"sys/policies/acl/ops-mason-survey",
"sys/policies/acl/default",
"sys/policies/acl/root",
]:
assert _caps(stanzas[path]) == {"deny"}, path
def test_kv_data_is_create_only():
stanzas = _stanzas()
for path in ["platform/data/workloads/*", "platform/data/suppliers/*"]:
assert _caps(stanzas[path]) == {"create"}, path
for path, body in stanzas.items():
if "/data/" in path:
assert not _caps(body) & {"read", "update", "list"}, path
def test_policy_writes_limited_to_workload_read_prefix():
for path, body in _stanzas().items():
if path.startswith("sys/policies/acl/") and _caps(body) & {"create", "update", "delete"}:
assert path == "sys/policies/acl/workload-kv-read-*", path
def test_role_writes_restrict_token_policies():
for path, body in _stanzas().items():
if path.startswith("auth/") and "/role/" in path and _caps(body) & {"create", "update"}:
assert '"token_policies" = ["workload-kv-read-*"]' in body, path
assert re.search(r'denied_parameters\s*=\s*\{\s*"policies"\s*=\s*\[\]', body), path
def test_no_mount_or_auth_method_writes():
for path, body in _stanzas().items():
if path.startswith(("sys/mounts/", "sys/auth/")):
assert _caps(body) <= {"read", "list", "deny"}, path