feat(P04): kyverno-json ABAC policy + evaluator (REQ-339, D-227, C-5.1, security-engineer)
---ci--- project: acdl phase: 4 milestone: v1.28 status: execute persona: security-engineer ---
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
"""ABAC policy tests for the token-vend Lambda (REQ-339, C-5.1, C-6.1).
|
||||
|
||||
Uses the **real** ``kj`` binary at ``/usr/local/bin/kj`` — these are
|
||||
real policy-evaluation tests, not mocked. Skipped when ``kj`` is absent
|
||||
(graceful, not failed — the binary is a build-host dep).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import shutil
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
||||
|
||||
from core.abac_evaluator import evaluate_token_vend_policy
|
||||
|
||||
KJ_AVAILABLE = shutil.which("kj") is not None
|
||||
skip_no_kj = pytest.mark.skipif(
|
||||
not KJ_AVAILABLE, reason="`kj` binary not on PATH (D-227 build-host dep)"
|
||||
)
|
||||
|
||||
|
||||
def _payload(role, env, owner="t1", res_owner="t1"):
|
||||
return {
|
||||
"subject": {"id": "u1", "role": role, "owner": owner},
|
||||
"requested_claims": ["sub", "roles"],
|
||||
"target_resource": {
|
||||
"type": "contract",
|
||||
"id": "c1",
|
||||
"owner": res_owner,
|
||||
"environment": env,
|
||||
},
|
||||
"environment": env,
|
||||
"pat_jti": "p1",
|
||||
"policy_version": "test",
|
||||
}
|
||||
|
||||
|
||||
@skip_no_kj
|
||||
def test_developer_dev_allowed():
|
||||
allowed, pcrs, sha = evaluate_token_vend_policy(_payload("developer", "dev"))
|
||||
assert allowed is True, [p for p in pcrs if p["result"] == "fail"]
|
||||
assert sha # non-empty SHA
|
||||
|
||||
|
||||
@skip_no_kj
|
||||
def test_sre_prod_allowed():
|
||||
allowed, pcrs, sha = evaluate_token_vend_policy(_payload("sre", "prod"))
|
||||
assert allowed is True, [p for p in pcrs if p["result"] == "fail"]
|
||||
|
||||
|
||||
@skip_no_kj
|
||||
def test_sre_qa_allowed():
|
||||
allowed, _, _ = evaluate_token_vend_policy(_payload("sre", "qa"))
|
||||
assert allowed is True
|
||||
|
||||
|
||||
@skip_no_kj
|
||||
def test_sre_dr_allowed():
|
||||
allowed, _, _ = evaluate_token_vend_policy(_payload("sre", "dr"))
|
||||
assert allowed is True
|
||||
|
||||
|
||||
@skip_no_kj
|
||||
def test_developer_prod_denied():
|
||||
allowed, pcrs, _ = evaluate_token_vend_policy(_payload("developer", "prod"))
|
||||
assert allowed is False
|
||||
fails = [p for p in pcrs if p["result"] == "fail" and p["severity"] == "critical"]
|
||||
assert fails, "expected at least one critical fail PCR"
|
||||
|
||||
|
||||
@skip_no_kj
|
||||
def test_wrong_owner_denied():
|
||||
allowed, pcrs, _ = evaluate_token_vend_policy(
|
||||
_payload("developer", "dev", owner="t1", res_owner="t2")
|
||||
)
|
||||
assert allowed is False
|
||||
fails = [p for p in pcrs if p["result"] == "fail"]
|
||||
assert fails
|
||||
|
||||
|
||||
@skip_no_kj
|
||||
def test_developer_qa_denied():
|
||||
allowed, _, _ = evaluate_token_vend_policy(_payload("developer", "qa"))
|
||||
assert allowed is False
|
||||
|
||||
|
||||
@skip_no_kj
|
||||
def test_empty_requested_claims_denied():
|
||||
pl = _payload("developer", "dev")
|
||||
pl["requested_claims"] = []
|
||||
allowed, pcrs, _ = evaluate_token_vend_policy(pl)
|
||||
assert allowed is False
|
||||
|
||||
|
||||
@skip_no_kj
|
||||
def test_policy_sha_is_string():
|
||||
_, _, sha = evaluate_token_vend_policy(_payload("developer", "dev"))
|
||||
assert isinstance(sha, str)
|
||||
assert len(sha) > 0
|
||||
Reference in New Issue
Block a user