net-kingdom/sso-mfa/k8s/bounded-executor/test_rbac.py
tegwick 2387409d08
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
NK-WP-0056-T03 done: executor identity and authority ceiling, in source
Executor credentials declared (planned) with executor_subject; service-identity
gains convention executor (SI-15: approved-only grants, no person, not
interactive) and --admissions, checking that an admission's ceiling lies inside
the executor's declared grants (pilot covered). RBAC in sso-mfa/k8s/bounded-executor
(not applied): ServiceAccount without automount, a Role limited to the authelia
Deployment and ExternalSecret, no read of credential objects; tests tie Role,
declaration and pilot ceiling. The pilot example's delivery check now reads the
ExternalSecret status. railiance-apps and glas-harness answers recorded (T02).

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

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 994874@bnt-lap001
Assistant-Session: 6017c416-d619-47eb-bd1a-f670a02d7d87
2026-10-31 14:21:04 +01:00

67 lines
3.2 KiB
Python

"""The bounded executor's Kubernetes authority is exactly the pilot's (NK-WP-0056-T03). Source only, no cluster."""
from __future__ import annotations
import pathlib
import unittest
import yaml
HERE = pathlib.Path(__file__).resolve().parent
ROOT = HERE.parents[2]
DOCS = list(yaml.safe_load_all((HERE / "rbac.yaml").read_text()))
DECLARATION = yaml.safe_load((ROOT / "tools/service-identity/declarations/bounded-executor.yaml").read_text())
PILOT = yaml.safe_load((ROOT / "examples/bounded-execution-admission/bind-rotation-svc-authelia.yaml").read_text())
KIND_SCOPE = {("apps", "deployments"): "deployment", ("external-secrets.io", "externalsecrets"): "externalsecret"}
FORBIDDEN_RESOURCES = {"secrets", "configmaps", "pods", "pods/exec", "pods/log", "serviceaccounts", "serviceaccounts/token",
"roles", "rolebindings", "clusterroles", "clusterrolebindings", "*"}
def by_kind(kind):
return [d for d in DOCS if d["kind"] == kind]
def role_scopes():
(role,) = by_kind("Role")
return {f"k8s/sso/{KIND_SCOPE[(group, resource)]}/{name}"
for rule in role["rules"] for group in rule["apiGroups"] for resource in rule["resources"]
for name in rule["resourceNames"]}
class RbacTests(unittest.TestCase):
def test_only_namespaced_objects_in_sso(self):
self.assertEqual(sorted(d["kind"] for d in DOCS), ["Role", "RoleBinding", "ServiceAccount"])
self.assertTrue(all(d["metadata"]["namespace"] == "sso" for d in DOCS))
def test_service_account_does_not_automount(self):
(sa,) = by_kind("ServiceAccount")
self.assertEqual(sa["metadata"]["name"], "nk-bind-executor")
self.assertIs(sa["automountServiceAccountToken"], False)
def test_every_rule_is_named_and_narrow(self):
(role,) = by_kind("Role")
for rule in role["rules"]:
with self.subTest(rule=rule["resources"]):
self.assertTrue(rule.get("resourceNames"), "every rule names its objects")
for field in ("apiGroups", "resources", "verbs", "resourceNames"):
self.assertNotIn("*", rule[field])
self.assertLessEqual(set(rule["verbs"]), {"get", "watch", "patch"})
self.assertFalse(set(rule["resources"]) & FORBIDDEN_RESOURCES)
self.assertTrue(set(rule["resources"]) <= {r for _, r in KIND_SCOPE})
def test_binding_binds_only_the_executor(self):
(binding,) = by_kind("RoleBinding")
self.assertEqual(binding["roleRef"], {"apiGroup": "rbac.authorization.k8s.io", "kind": "Role", "name": "nk-bind-executor"})
self.assertEqual(binding["subjects"], [{"kind": "ServiceAccount", "name": "nk-bind-executor", "namespace": "sso"}])
def test_role_equals_declaration_equals_pilot_ceiling(self):
(sa_identity,) = [i for i in DECLARATION["identities"] if i["name"] == "nk-bind-executor"]
declared = {g["scope"] for g in sa_identity["grants"]}
ceiling = {g["scope"] for g in PILOT["spec"]["scope_ceiling"] if g["scope"].startswith("k8s/")}
self.assertEqual(role_scopes(), declared)
self.assertEqual(declared, ceiling)
self.assertEqual(PILOT["spec"]["executor"]["identity"], sa_identity["executor_subject"])
if __name__ == "__main__":
unittest.main()