"""Offline guard for the ops-mason builder identity (MASON-IN-0006 choice (b)). Parses the GitOps manifests and asserts the founder's 2026-10-22 boundary: the five granted rules only, no forbidden resources, no escalate/bind/impersonate, no wildcards, a User subject with no ServiceAccount, and a manual, pinned Application. """ from pathlib import Path import re import yaml ROOT = Path(__file__).resolve().parents[1] ADDON = ROOT / "argocd/platform-addons/ops-mason-builder" APP = ROOT / "argocd/railiance01/applications/ops-mason-builder.application.yaml" WRITE_VERBS = ["create", "get", "list", "watch", "update", "patch", "delete"] READ_VERBS = ["get", "list", "watch"] FORBIDDEN_RESOURCES = { "secrets", "pods", "serviceaccounts/token", "configmaps", "roles", "rolebindings", "clusterroles", "clusterrolebindings", "nodes", "nodes/proxy", "pods/exec", "pods/log", } FORBIDDEN_VERBS = {"escalate", "bind", "impersonate"} EXPECTED_RULES = [ {"apiGroups": [""], "resources": ["namespaces"], "verbs": WRITE_VERBS}, {"apiGroups": [""], "resources": ["serviceaccounts"], "verbs": WRITE_VERBS}, {"apiGroups": ["networking.k8s.io"], "resources": ["networkpolicies"], "verbs": WRITE_VERBS}, {"apiGroups": [""], "resources": ["services"], "verbs": READ_VERBS}, {"apiGroups": ["authorization.k8s.io"], "resources": ["selfsubjectaccessreviews", "selfsubjectrulesreviews"], "verbs": ["create"]}, ] def _docs(): kust = yaml.safe_load((ADDON / "kustomization.yaml").read_text()) docs = [] for res in kust["resources"]: docs.extend(d for d in yaml.safe_load_all((ADDON / res).read_text()) if d) return docs def _one(kind): found = [d for d in _docs() if d["kind"] == kind] assert len(found) == 1, kind return found[0] def test_only_expected_kinds_no_secret(): kinds = sorted(d["kind"] for d in _docs()) assert kinds == ["ClusterRole", "ClusterRoleBinding"] for path in ADDON.iterdir(): if path.is_file(): assert "kind: Secret" not in path.read_text(), path def test_cluster_role_exact_rules_no_wildcards(): role = _one("ClusterRole") assert role["metadata"]["name"] == "ops-mason-builder" assert "aggregationRule" not in role assert role["rules"] == EXPECTED_RULES granted = set() for rule in role["rules"]: values = [*rule["verbs"], *rule.get("apiGroups", []), *rule.get("resources", [])] assert not any("*" in v for v in values), rule assert FORBIDDEN_VERBS.isdisjoint(rule["verbs"]), rule for resource in rule["resources"]: assert resource not in FORBIDDEN_RESOURCES, resource granted.add(resource) assert granted == { "namespaces", "serviceaccounts", "networkpolicies", "services", "selfsubjectaccessreviews", "selfsubjectrulesreviews", } by_resource = {r["resources"][0]: r["verbs"] for r in role["rules"] if len(r["resources"]) == 1} assert by_resource["namespaces"] == WRITE_VERBS assert by_resource["serviceaccounts"] == WRITE_VERBS assert by_resource["networkpolicies"] == WRITE_VERBS assert by_resource["services"] == READ_VERBS review = next(r for r in role["rules"] if "selfsubjectaccessreviews" in r["resources"]) assert review["verbs"] == ["create"] assert review["resources"] == ["selfsubjectaccessreviews", "selfsubjectrulesreviews"] def test_binding_targets_only_the_user(): binding = _one("ClusterRoleBinding") assert binding["roleRef"]["name"] == "ops-mason-builder" assert binding["roleRef"]["kind"] == "ClusterRole" assert binding["subjects"] == [{"kind": "User", "name": "ops-mason-builder", "apiGroup": "rbac.authorization.k8s.io"}] assert all(s["kind"] != "ServiceAccount" for s in binding["subjects"]) def test_application_manual_and_pinned(): app = yaml.safe_load(APP.read_text()) spec = app["spec"] assert spec["project"] == "railiance-platform-addons" assert spec["source"]["path"] == "argocd/platform-addons/ops-mason-builder" assert re.fullmatch(r"[0-9a-f]{40}", spec["source"]["targetRevision"]) assert "automated" not in spec.get("syncPolicy", {}) assert "finalizers" not in app["metadata"]