- 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
67 lines
2.5 KiB
Python
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}],
|
|
}
|
|
]
|