Admit live E2 from a value-safe custody receipt
WH-ENG-20260822-AUDIT-E2-02 projected and then aborted: admit-plane had no receipt adapter, so the runner sent zero packets. Consume custody receipts as handles only, keep unconnected admission fail-closed, and retire -02. Assistant: grok Assistant-Session: 01a02670-3345-76f2-a014-70fde8e2a2bb
This commit is contained in:
parent
b6c1806680
commit
45548e44a2
14 changed files with 221 additions and 42 deletions
|
|
@ -10,7 +10,7 @@ from whitehat_security.fixtures import FixtureService, probe_suite
|
|||
from whitehat_security.model import RunReport
|
||||
from whitehat_security.e3 import e3_calibration
|
||||
from whitehat_security.plane import (
|
||||
KillSwitch, LocalBroker, RateWatcher, UnconnectedCustodyBroker,
|
||||
KillSwitch, LocalBroker, RateWatcher, ReceiptBroker, UnconnectedCustodyBroker,
|
||||
admit, cleanup, retired_ids,
|
||||
)
|
||||
from whitehat_security.reporting import queue_risk_nexus
|
||||
|
|
@ -71,6 +71,7 @@ def test_retired_ids_include_cancelled_records():
|
|||
assert "WH-ENG-20260821-AUDIT-E2" in ids
|
||||
assert "WH-ENG-20260821-TENANT-E2" in ids
|
||||
assert "WH-ENG-20260822-AUDIT-E2-01" in ids
|
||||
assert "WH-ENG-20260822-AUDIT-E2-02" in ids
|
||||
|
||||
|
||||
def test_fixture_plane_admits_and_projects_handles_without_secrets(tmp_path):
|
||||
|
|
@ -165,6 +166,63 @@ def test_unconnected_broker_requests_no_credential(tmp_path):
|
|||
)
|
||||
|
||||
|
||||
def test_receipt_broker_issues_lease_without_secret_values(tmp_path):
|
||||
engagement = load_engagement(tmp_path, fixture_record(
|
||||
approval_class="live-e2", environment="build",
|
||||
target_id="audit-core",
|
||||
routes=["POST /v1/events"],
|
||||
plane_namespace="whitehat",
|
||||
runner_image_digest="sha256:abc",
|
||||
))
|
||||
receipt = {
|
||||
"engagement_id": "WH-ENG-FIXTURE-1",
|
||||
"projected_at": "2026-08-22T12:00:00Z",
|
||||
"expires_at": "2099-01-01T00:00:00Z",
|
||||
"identities": ["whitehat-e2-a", "whitehat-e2-b"],
|
||||
"mounted_secret": "whitehat/whitehat-e2-audit-credentials",
|
||||
"mounted_keys": ["token-a", "token-b"],
|
||||
"target_ready": True,
|
||||
"secret_values_observed": False,
|
||||
}
|
||||
lease = admit(
|
||||
engagement=engagement, registration=load_registration("targets/audit-core-e2.json"),
|
||||
broker=ReceiptBroker(receipt), kill_switch=KillSwitch(tmp_path / "KILL"),
|
||||
now=NOW, retired=set(),
|
||||
)
|
||||
assert {handle.role for handle in lease.identities} == {"owner", "attacker"}
|
||||
rendered = repr(lease) + repr(lease.identities) + json.dumps(receipt)
|
||||
assert "token_urlsafe" not in rendered
|
||||
with pytest.raises(AuthorizationError, match="custody must revoke"):
|
||||
cleanup(lease, ReceiptBroker(receipt))
|
||||
|
||||
|
||||
def test_receipt_broker_rejects_secret_material(tmp_path):
|
||||
engagement = load_engagement(tmp_path, fixture_record(
|
||||
approval_class="live-e2", environment="build",
|
||||
target_id="audit-core",
|
||||
routes=["POST /v1/events"],
|
||||
plane_namespace="whitehat",
|
||||
runner_image_digest="sha256:abc",
|
||||
))
|
||||
receipt = {
|
||||
"engagement_id": "WH-ENG-FIXTURE-1",
|
||||
"projected_at": "2026-08-22T12:00:00Z",
|
||||
"expires_at": "2099-01-01T00:00:00Z",
|
||||
"identities": ["whitehat-e2-a", "whitehat-e2-b"],
|
||||
"mounted_secret": "whitehat/whitehat-e2-audit-credentials",
|
||||
"mounted_keys": ["token-a", "token-b"],
|
||||
"target_ready": True,
|
||||
"secret_values_observed": False,
|
||||
"token": "must-not-appear",
|
||||
}
|
||||
with pytest.raises(AuthorizationError, match="secret material"):
|
||||
admit(
|
||||
engagement=engagement, registration=load_registration("targets/audit-core-e2.json"),
|
||||
broker=ReceiptBroker(receipt), kill_switch=KillSwitch(tmp_path / "KILL"),
|
||||
now=NOW, retired=set(),
|
||||
)
|
||||
|
||||
|
||||
def test_e3_is_not_admitted_by_the_e2_plane(tmp_path):
|
||||
engagement = load_engagement(tmp_path, fixture_record(
|
||||
approval_class="e3", techniques=["e3-rls"],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue