docs(canon): reconcile workload and tenant grouping semantics
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02929-244b-7391-b933-c04010e8eedb
This commit is contained in:
tegwick 2026-08-22 14:53:31 +02:00
parent ad2057acff
commit bee22db620
21 changed files with 1118 additions and 59 deletions

View file

@ -1,6 +1,7 @@
from __future__ import annotations
import importlib.util
import json
import pathlib
import unittest
@ -10,6 +11,7 @@ SPEC = importlib.util.spec_from_file_location("tenancy_posture_validate", MODULE
assert SPEC and SPEC.loader
VALIDATE = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(VALIDATE)
SCHEMA = json.loads(VALIDATE.SCHEMA.read_text(encoding="utf-8"))
def declaration() -> dict:
@ -30,10 +32,38 @@ def declaration() -> dict:
}
def zone_declaration() -> dict:
return {
"standard": "security-zones_v0.1",
"membership": "z2-continuity",
"responsible_party": "ops-warden",
"justification": "foundational access path",
"context": {
"maturity": "M2",
"criticality": "high",
"data_classification": "confidential",
},
"evidence": [
{
"ref": "docs/evidence/example-zone.md",
"supports": ["M2", "continuity-dependency"],
}
],
"reviewed": "2026-08-22",
"review_due": "2026-11-22",
}
class SemanticValidationTests(unittest.TestCase):
def validate(self, document: dict) -> list[str]:
return VALIDATE.validate_semantics(document, pathlib.Path("tenancy.yaml"))
def validate_full(self, document: dict, tmp_path: pathlib.Path) -> list[str]:
import yaml
tmp_path.write_text(yaml.safe_dump(document), encoding="utf-8")
return VALIDATE.validate(tmp_path, SCHEMA)
def test_floor_vector_with_reasons_is_valid(self) -> None:
self.assertEqual([], self.validate(declaration()))
@ -68,6 +98,140 @@ class SemanticValidationTests(unittest.TestCase):
}
self.assertIn("service names must be unique", self.validate(document)[0])
def test_workload_identity_name_must_match_service(self) -> None:
document = declaration()
document["workload_identity"] = {
"name": "different",
"kind": "operational-control-plane",
"responsible_repo": "example",
"identity_bindings": [
{
"scheme": "iam-profile",
"authority": "key-cape",
"subject": "example-prod",
"principal_type": "service",
}
],
}
self.assertIn(
"workload_identity.name must equal service", self.validate(document)[0]
)
def test_workload_identity_bindings_are_unique(self) -> None:
document = declaration()
binding = {
"scheme": "iam-profile",
"authority": "key-cape",
"subject": "example-prod",
"principal_type": "service",
}
document["workload_identity"] = {
"name": "example",
"kind": "platform-service",
"responsible_repo": "example",
"identity_bindings": [binding, binding],
}
self.assertIn(
"workload identity bindings must be unique", self.validate(document)[0]
)
def test_zones_require_authoritative_workload_identity(self) -> None:
import tempfile
document = declaration()
document["zones"] = zone_declaration()
with tempfile.TemporaryDirectory() as directory:
path = pathlib.Path(directory) / "tenancy.yaml"
errors = self.validate_full(document, path)
self.assertTrue(any("workload_identity" in error for error in errors))
def test_operational_workload_may_declare_zones(self) -> None:
import tempfile
document = declaration()
document["workload_identity"] = {
"name": "example",
"kind": "operational-control-plane",
"responsible_repo": "ops-warden",
"identity_bindings": [
{
"scheme": "ssh-certificate",
"authority": "ops-warden",
"subject": "agt-example",
"principal_type": "agent",
"environment": "prod",
}
],
}
document["zones"] = zone_declaration()
with tempfile.TemporaryDirectory() as directory:
path = pathlib.Path(directory) / "tenancy.yaml"
self.assertEqual([], self.validate_full(document, path))
def test_zone_membership_uses_canonical_catalog(self) -> None:
import tempfile
document = declaration()
document["workload_identity"] = {
"name": "example",
"kind": "application",
"responsible_repo": "example",
"declaration_ref": "rapp-example/declarations/rapp.yaml",
"identity_bindings": [
{
"scheme": "iam-profile",
"authority": "key-cape",
"subject": "example-prod",
"principal_type": "service",
}
],
}
document["zones"] = zone_declaration()
document["zones"]["membership"] = "permissive-default"
with tempfile.TemporaryDirectory() as directory:
path = pathlib.Path(directory) / "tenancy.yaml"
errors = self.validate_full(document, path)
self.assertTrue(any("membership" in error for error in errors))
def test_zone_review_due_must_be_after_reviewed(self) -> None:
document = declaration()
document["zones"] = zone_declaration()
document["zones"]["review_due"] = document["zones"]["reviewed"]
self.assertIn(
"zones.review_due must be after zones.reviewed",
self.validate(document)[0],
)
def test_multi_service_zones_must_not_be_top_level(self) -> None:
import tempfile
entry = declaration()
document = {
"schema_version": "0.1",
"framework": "netkingdom-tenancy-posture",
"services": [entry],
"zones": zone_declaration(),
}
with tempfile.TemporaryDirectory() as directory:
path = pathlib.Path(directory) / "tenancy.yaml"
errors = self.validate_full(document, path)
self.assertTrue(errors)
def test_multi_service_zone_requires_identity_on_same_entry(self) -> None:
import tempfile
entry = declaration()
entry["zones"] = zone_declaration()
document = {
"schema_version": "0.1",
"framework": "netkingdom-tenancy-posture",
"services": [entry],
}
with tempfile.TemporaryDirectory() as directory:
path = pathlib.Path(directory) / "tenancy.yaml"
errors = self.validate_full(document, path)
self.assertTrue(any("workload_identity" in error for error in errors))
if __name__ == "__main__":
unittest.main()

View file

@ -38,6 +38,30 @@ def validate_semantics(document: dict[str, Any], path: pathlib.Path) -> list[str
for entry in entries:
name = entry["service"]
workload_identity = entry.get("workload_identity")
if workload_identity:
if workload_identity["name"] != name:
errors.append(
f"{name}: workload_identity.name must equal service"
)
bindings = workload_identity["identity_bindings"]
binding_keys = [
(
binding["scheme"],
binding["authority"],
binding["subject"],
binding.get("environment"),
)
for binding in bindings
]
if len(binding_keys) != len(set(binding_keys)):
errors.append(f"{name}: workload identity bindings must be unique")
zones = entry.get("zones")
if zones:
zone_reviewed = dt.date.fromisoformat(zones["reviewed"])
zone_review_due = dt.date.fromisoformat(zones["review_due"])
if zone_review_due <= zone_reviewed:
errors.append(f"{name}: zones.review_due must be after zones.reviewed")
posture = entry["tenancy"]
current = posture["current"]
reason = posture.get("reason", {})