approval-engine/tests/test_networkpolicies.py
tegwick e9e9f93317 APPROVAL-WP-0007-T01 done: required_assurance floor; executor ingress; alignment answer
- Optional required_assurance {"level": aal1|aal2|aal3} at issue, schema v7.
  Enforced at add_entry (403), claim (assurance_unsatisfied) and consume (409)
  from the verified token level only; inherited on supersession; legacy rows
  NULL. Served only when declared so undeclared claims keep exact bytes.
- deploy/networkpolicies.yaml: pod-scoped ingress for sso +
  app.kubernetes.io/name=bounded-executor on 8080 (hub 39a3bffa). Not applied.
- docs/decision-services-alignment-answer.md: owner answer to the NetKingdom
  decision services review (hub 81cafbf3): roles accepted, T02 split proposed,
  presentation_ref at create declined with an entry-level counter-proposal.

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

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 5502@bnt-lap001
Assistant-Session: 68b3b02f-5d0f-4e71-8421-796f62e50196
2026-10-31 23:07:05 +01:00

67 lines
2.5 KiB
Python

"""Mechanical checks on deploy/networkpolicies.yaml.
The bounded-executor rule must stay pod-scoped. Splitting namespaceSelector
and podSelector into two `from` elements turns AND into OR and admits every
pod in sso (KeyCape, Authelia, LLDAP) or every bounded-executor pod in any
namespace. That is a one-character YAML change review can miss.
"""
from __future__ import annotations
from pathlib import Path
import pytest
yaml = pytest.importorskip("yaml")
POLICIES = Path(__file__).resolve().parents[1] / "deploy" / "networkpolicies.yaml"
def _policies() -> dict[str, dict]:
docs = [d for d in yaml.safe_load_all(POLICIES.read_text(encoding="utf-8")) if d]
return {d["metadata"]["name"]: d for d in docs}
def test_default_deny_remains():
spec = _policies()["approval-engine-default-deny"]["spec"]
assert spec["podSelector"] == {}
assert set(spec["policyTypes"]) == {"Ingress", "Egress"}
def test_bounded_executor_ingress_is_pod_scoped_to_sso_on_8080():
policy = _policies()["approval-engine-bounded-executor"]
assert policy["metadata"]["namespace"] == "approval-engine"
spec = policy["spec"]
assert spec["podSelector"] == {"matchLabels": {"app.kubernetes.io/name": "approval-engine"}}
assert spec["policyTypes"] == ["Ingress"]
assert len(spec["ingress"]) == 1
rule = spec["ingress"][0]
assert rule["from"] == [
{
"namespaceSelector": {"matchLabels": {"kubernetes.io/metadata.name": "sso"}},
"podSelector": {"matchLabels": {"app.kubernetes.io/name": "bounded-executor"}},
}
]
assert rule["ports"] == [{"protocol": "TCP", "port": 8080}]
def test_no_policy_admits_sso_namespace_wide():
for name, policy in _policies().items():
for rule in policy["spec"].get("ingress", []):
for peer in rule.get("from", []):
ns = peer.get("namespaceSelector", {}).get("matchLabels", {})
if ns.get("kubernetes.io/metadata.name") == "sso":
assert "podSelector" in peer, f"{name} admits all of sso"
def test_existing_callers_policy_is_unchanged():
rule = _policies()["approval-engine-callers"]["spec"]["ingress"]
assert rule == [
{
"from": [
{"namespaceSelector": {"matchLabels": {"kubernetes.io/metadata.name": "secrets-engine"}}},
{"namespaceSelector": {"matchLabels": {"railiance.io/approval-engine-client": "true"}}},
],
"ports": [{"protocol": "TCP", "port": 8080}],
}
]