Implement KG-WP-0002 posture pilot scaffold
This commit is contained in:
parent
6cee3503da
commit
3c549d9b78
22 changed files with 1418 additions and 25 deletions
8
tests/conftest.py
Normal file
8
tests/conftest.py
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
SRC = Path(__file__).resolve().parents[1] / "src"
|
||||
if str(SRC) not in sys.path:
|
||||
sys.path.insert(0, str(SRC))
|
||||
48
tests/test_contracts.py
Normal file
48
tests/test_contracts.py
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
from kings_guard.adapters import observation_from_audit_event
|
||||
from kings_guard.contracts import PostureLevel, SecurityGenome, as_jsonable
|
||||
from kings_guard.fixtures import load_qonto_assistant_pilot
|
||||
from kings_guard.posture import PostureEvaluator
|
||||
|
||||
|
||||
def test_qonto_fixture_loads_a_normalized_genome() -> None:
|
||||
fixture = load_qonto_assistant_pilot()
|
||||
|
||||
assert isinstance(fixture.genome, SecurityGenome)
|
||||
assert fixture.genome.genome_id == "kg:genome:qonto-assistant"
|
||||
assert fixture.genome.tenant_id == "binky"
|
||||
assert "finance.qonto.read" in fixture.genome.permitted_capabilities
|
||||
assert fixture.normalization_hints["identity_binding"] == "self_asserted"
|
||||
|
||||
|
||||
def test_qonto_audit_event_normalizes_to_immune_observation() -> None:
|
||||
fixture = load_qonto_assistant_pilot()
|
||||
observation = observation_from_audit_event(
|
||||
fixture.audit_event,
|
||||
subject_id=fixture.normalization_hints["subject_id"],
|
||||
capability_scope=fixture.normalization_hints["capability_scope"],
|
||||
identity_binding=fixture.normalization_hints["identity_binding"],
|
||||
egress_destination=fixture.normalization_hints["egress_destination"],
|
||||
)
|
||||
|
||||
assert observation.source_system == "qonto-assistant"
|
||||
assert observation.capability == "finance.qonto.read"
|
||||
assert observation.resource_scope == "org_summary"
|
||||
assert observation.protocol == "mcp"
|
||||
assert observation.decision.value == "deny"
|
||||
assert observation.deny_reason == "credential_exfil"
|
||||
|
||||
|
||||
def test_posture_evaluation_is_jsonable() -> None:
|
||||
fixture = load_qonto_assistant_pilot()
|
||||
observation = observation_from_audit_event(
|
||||
fixture.audit_event,
|
||||
subject_id=fixture.normalization_hints["subject_id"],
|
||||
capability_scope=fixture.normalization_hints["capability_scope"],
|
||||
identity_binding=fixture.normalization_hints["identity_binding"],
|
||||
egress_destination=fixture.normalization_hints["egress_destination"],
|
||||
)
|
||||
evaluation = PostureEvaluator().evaluate(fixture.genome, observation)
|
||||
payload = as_jsonable(evaluation)
|
||||
|
||||
assert payload["assessment"]["posture"] == PostureLevel.INFLAMED.value
|
||||
assert payload["signals"][0]["signal_kind"] == "posture_hint"
|
||||
42
tests/test_posture.py
Normal file
42
tests/test_posture.py
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
from kings_guard.adapters import observation_from_audit_event
|
||||
from kings_guard.fixtures import load_qonto_assistant_pilot
|
||||
from kings_guard.posture import PostureEvaluator
|
||||
|
||||
|
||||
def test_qonto_pilot_produces_inflamed_posture_with_tolerance_context() -> None:
|
||||
fixture = load_qonto_assistant_pilot()
|
||||
observation = observation_from_audit_event(
|
||||
fixture.audit_event,
|
||||
subject_id=fixture.normalization_hints["subject_id"],
|
||||
capability_scope=fixture.normalization_hints["capability_scope"],
|
||||
identity_binding=fixture.normalization_hints["identity_binding"],
|
||||
egress_destination=fixture.normalization_hints["egress_destination"],
|
||||
)
|
||||
|
||||
evaluation = PostureEvaluator().evaluate(fixture.genome, observation)
|
||||
|
||||
assert evaluation.assessment.posture.value == "inflamed"
|
||||
assert "credential_exfil_probe" in evaluation.assessment.findings
|
||||
assert "tolerated:self-asserted-actor-claims" in evaluation.assessment.tolerated_findings
|
||||
assert evaluation.assessment.risk_score >= 80
|
||||
|
||||
|
||||
def test_qonto_pilot_emits_advisory_only_effector_requests() -> None:
|
||||
fixture = load_qonto_assistant_pilot()
|
||||
observation = observation_from_audit_event(
|
||||
fixture.audit_event,
|
||||
subject_id=fixture.normalization_hints["subject_id"],
|
||||
capability_scope=fixture.normalization_hints["capability_scope"],
|
||||
identity_binding=fixture.normalization_hints["identity_binding"],
|
||||
egress_destination=fixture.normalization_hints["egress_destination"],
|
||||
)
|
||||
|
||||
evaluation = PostureEvaluator().evaluate(fixture.genome, observation)
|
||||
signal = evaluation.signals[0]
|
||||
|
||||
assert signal.target_system == "qonto-assistant"
|
||||
assert signal.signal_kind.value == "posture_hint"
|
||||
assert signal.effector_requests[0].authority_boundary == "advisory_only"
|
||||
assert signal.effector_requests[0].action == "lock_actor_temporarily"
|
||||
assert signal.effector_requests[1].target_system == "state-hub"
|
||||
assert signal.effector_requests[1].authority_boundary == "metadata_only"
|
||||
Loading…
Add table
Add a link
Reference in a new issue