feat: compile security zone declarations
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a0291a-1e87-7151-9934-fcbfe3f65eb1
This commit is contained in:
parent
a51039330c
commit
9b6ada7c89
5 changed files with 433 additions and 9 deletions
128
tests/test_resolve_zones.py
Normal file
128
tests/test_resolve_zones.py
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
import unittest
|
||||
|
||||
import yaml
|
||||
|
||||
from tools.resolve_zones import resolve_paths
|
||||
|
||||
|
||||
def declaration(*, service="flex-auth", zone="z2-protected", maturity="M2"):
|
||||
return {
|
||||
"schema_version": "0.1",
|
||||
"framework": "netkingdom-tenancy-posture",
|
||||
"service": service,
|
||||
"role": "policy-decision-point",
|
||||
"workload_identity": {
|
||||
"name": service,
|
||||
"kind": "platform-service",
|
||||
"responsible_repo": service,
|
||||
"identity_bindings": [
|
||||
{
|
||||
"scheme": "kubernetes-service-account",
|
||||
"authority": "railiance01",
|
||||
"subject": f"system:serviceaccount:{service}:{service}",
|
||||
"principal_type": "service",
|
||||
}
|
||||
],
|
||||
},
|
||||
"tenancy": {},
|
||||
"zones": {
|
||||
"standard": "security-zones_v0.1",
|
||||
"membership": zone,
|
||||
"responsible_party": service,
|
||||
"justification": "fixture",
|
||||
"context": {
|
||||
"maturity": maturity,
|
||||
"criticality": "high",
|
||||
"data_classification": "internal",
|
||||
},
|
||||
"evidence": [{"ref": "fixture", "supports": [maturity]}],
|
||||
"reviewed": "2026-08-22",
|
||||
"review_due": "2026-11-22",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
class ResolveZonesTest(unittest.TestCase):
|
||||
def resolve(self, document):
|
||||
with TemporaryDirectory() as directory:
|
||||
path = Path(directory) / "tenancy.yaml"
|
||||
path.write_text(yaml.safe_dump(document, sort_keys=False))
|
||||
return resolve_paths([path])
|
||||
|
||||
def test_satisfied_membership_selects_zone_control_profile(self):
|
||||
result = self.resolve(declaration())
|
||||
self.assertTrue(result["ok"])
|
||||
record = result["records"][0]
|
||||
self.assertEqual(record["admission"], "satisfied")
|
||||
self.assertEqual(record["effective_zone"], "z2-protected")
|
||||
pre_sign = next(c for c in record["controls"] if c["id"] == "flex-auth/pre-sign")
|
||||
self.assertEqual(pre_sign["stance"], "enforced")
|
||||
self.assertEqual(pre_sign["failure_mode"], "fail_open")
|
||||
self.assertTrue(record["membership_revision"].startswith("sha256:"))
|
||||
|
||||
def test_below_floor_is_unsatisfied_and_uses_unknown_profile(self):
|
||||
result = self.resolve(declaration(maturity="M1"))
|
||||
self.assertTrue(result["ok"])
|
||||
record = result["records"][0]
|
||||
self.assertEqual(record["admission"], "unsatisfied")
|
||||
self.assertEqual(record["effective_zone"], "unknown")
|
||||
pre_sign = next(c for c in record["controls"] if c["id"] == "flex-auth/pre-sign")
|
||||
self.assertEqual(pre_sign["stance"], "advisory")
|
||||
|
||||
def test_zone_below_context_floor_is_unsatisfied_even_with_high_maturity(self):
|
||||
document = declaration(zone="z1-operational", maturity="M2")
|
||||
result = self.resolve(document)
|
||||
self.assertTrue(result["ok"])
|
||||
record = result["records"][0]
|
||||
self.assertEqual(record["admission"], "unsatisfied")
|
||||
self.assertEqual(record["admission_reason"], "z1-operational_below_M2_context_floor")
|
||||
|
||||
def test_continuity_zone_requires_dependency_and_recovery_evidence(self):
|
||||
document = declaration(zone="z2-continuity")
|
||||
result = self.resolve(document)
|
||||
self.assertTrue(result["ok"])
|
||||
self.assertEqual(result["records"][0]["admission"], "unsatisfied")
|
||||
document["zones"]["evidence"][0]["supports"].extend(
|
||||
["continuity-dependency", "recovery"]
|
||||
)
|
||||
result = self.resolve(document)
|
||||
self.assertEqual(result["records"][0]["admission"], "satisfied")
|
||||
|
||||
def test_public_floor_stays_unknown(self):
|
||||
document = declaration()
|
||||
document["zones"]["context"]["data_classification"] = "public"
|
||||
result = self.resolve(document)
|
||||
self.assertTrue(result["ok"])
|
||||
self.assertEqual(result["records"][0]["admission"], "unknown")
|
||||
self.assertEqual(
|
||||
result["records"][0]["admission_reason"],
|
||||
"public_data_classification_floor_unresolved",
|
||||
)
|
||||
|
||||
def test_missing_membership_returns_unknown_without_inference(self):
|
||||
document = declaration()
|
||||
document.pop("zones")
|
||||
document.pop("workload_identity")
|
||||
result = self.resolve(document)
|
||||
self.assertTrue(result["ok"])
|
||||
self.assertEqual(result["records"][0]["effective_zone"], "unknown")
|
||||
|
||||
def test_zone_requires_identity_bound_to_service(self):
|
||||
document = declaration()
|
||||
document["workload_identity"]["name"] = "guessed-from-path"
|
||||
result = self.resolve(document)
|
||||
self.assertFalse(result["ok"])
|
||||
self.assertIn("must equal service", result["errors"][0]["error"])
|
||||
|
||||
def test_n_a_data_classification_requires_reason(self):
|
||||
document = declaration()
|
||||
document["zones"]["context"]["data_classification"] = "n/a"
|
||||
result = self.resolve(document)
|
||||
self.assertFalse(result["ok"])
|
||||
self.assertIn("data_classification_reason is required", result["errors"][0]["error"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue