import json from datetime import UTC, datetime import pytest from whitehat_security.engagement import AuthorizationError, Engagement from whitehat_security.platform_custody import ( CLEANUP_INTERFACE, CONTRACT_INTERFACE, PROJECTION_INTERFACE, PlatformCustodyBroker, load_schemas, validate_broker_readiness, validate_cleanup_receipt, validate_projection_contract, validate_projection_receipt, ) from whitehat_security.plane import KillSwitch, admit NOW = datetime(2026, 8, 22, 12, tzinfo=UTC) def contract() -> dict: return { "interface": CONTRACT_INTERFACE, "version": 1, "workplan_id": "RAILIANCE-WP-0025", "engagement_id": "WH-ENG-FIXTURE-1", "status": "approved", "engagement_contract_sha256": "1" * 64, "target": { "id": "audit-core", "namespace": "audit-core", "deployment": "audit-core", "container": "audit-core", "sender_external_secret": "audit-core-senders", "revision": "a" * 40, "image_digest": "sha256:" + "b" * 64, "contract_sha256": "c" * 64, }, "runner": { "namespace": "whitehat", "service_account": "whitehat-runner", "secret_name": "whitehat-e2-audit-credentials", "mount_root": "/var/run/secrets/whitehat", "manifest_sha256": "d" * 64, }, "window": { "starts_at": "2026-08-22T12:00:00Z", "projection_cutoff": "2026-08-22T12:03:00Z", "expires_at": "2099-01-01T00:00:00Z", }, "authority": { "remote": "railiance01", "registry_path": "platform/workloads/audit-core/senders", "registry_field": "senders.json", "kv_mount": "platform", "kv_prefix": "engagements/WH-ENG-FIXTURE-1/audit-core", "eso_service_account": "external-secrets", "eso_namespace": "external-secrets", }, "identities": [ { "handle": "token-a", "role": "attacker", "sender_name": "whitehat-e2-a", "tenant": "tenant-a", "mount_path": "/var/run/secrets/whitehat/token-a", "may_read": True, "may_write": True, }, { "handle": "token-b", "role": "owner", "sender_name": "whitehat-e2-b", "tenant": "tenant-b", "mount_path": "/var/run/secrets/whitehat/token-b", "may_read": True, "may_write": True, }, ], } def projection_receipt() -> dict: return { "interface": PROJECTION_INTERFACE, "version": 1, "workplan_id": "RAILIANCE-WP-0025", "state": "projected", "receipt_id": "sha256:" + "e" * 64, "lease_id": "custody:" + "f" * 32, "engagement_id": "WH-ENG-FIXTURE-1", "target": {"id": "audit-core", "revision": "a" * 40, "image_digest": "sha256:" + "b" * 64}, "projection_contract_digest": "1" * 64, "broker_receipt_digest": "2" * 64, "projected_at": "2026-08-22T12:02:00Z", "expires_at": "2099-01-01T00:00:00Z", "identities": [ { "handle": "token-a", "role": "attacker", "sender_name": "whitehat-e2-a", "mount_path": "/var/run/secrets/whitehat/token-a", }, { "handle": "token-b", "role": "owner", "sender_name": "whitehat-e2-b", "mount_path": "/var/run/secrets/whitehat/token-b", }, ], "resources": {"names": {"store": "custody-example"}, "uids": {"mounted_secret": "uid"}}, "cleanup_authority": "railiance-platform", "secret_values_observed": False, } def cleanup_receipt() -> dict: return { "interface": CLEANUP_INTERFACE, "version": 1, "workplan_id": "RAILIANCE-WP-0025", "state": "cleaned", "lease_id": "custody:" + "f" * 32, "engagement_id": "WH-ENG-FIXTURE-1", "projection_receipt_id": "sha256:" + "e" * 64, "cleaned_at": "2026-08-22T12:14:00Z", "removed_resources": ["custody-example"], "target_ready": True, "secret_values_observed": False, } def broker_readiness() -> dict: return { "interface": "railiance.custody-broker-readiness", "version": 1, "workplan_id": "RAILIANCE-WP-0025", "owner": "whitehat-security", "reviewer": "whitehat-owner", "decision": "approve", "created_at": "2026-08-22T12:00:00Z", "engagement_id": "WH-ENG-FIXTURE-1", "target_id": "audit-core", "projection_contract_digest": "1" * 64, "projection_receipt_interface": PROJECTION_INTERFACE, "interface_artifacts": { "schemas/custody-projection-contract.schema.json": "a" * 64, "schemas/custody-broker-readiness.schema.json": "b" * 64, "schemas/custody-projection-receipt.schema.json": "c" * 64, "schemas/custody-cleanup-receipt.schema.json": "d" * 64, }, "required_roles": ["attacker", "owner"], "mount_paths": [ "/var/run/secrets/whitehat/token-a", "/var/run/secrets/whitehat/token-b", ], "adapter": { "repo": "whitehat-security", "revision": "a" * 40, "path": "src/whitehat_security/platform_custody.py", "sha256": "b" * 64, "tests_passed": True, }, "cleanup_request_supported": True, "secret_values_observed": False, } def live_record(): return { "engagement_id": "WH-ENG-FIXTURE-1", "authorization_id": "auth-1", "authorizer": "operator", "approved_at": "2026-08-22T11:00:00Z", "expires_at": "2099-01-01T00:00:00Z", "target": "https://fixture.invalid", "target_id": "audit-core", "target_owner": "audit-core", "environment": "build", "source": "runner", "approval_class": "live-e2", "plane_namespace": "whitehat", "runner_image_digest": "sha256:abc", "routes": ["POST /v1/events"], "fixture_ids": ["a", "b"], "credential_lane": "receipt", "credential_role": "runtime", "credential_max_ttl_seconds": 900, "techniques": ["e2-differential"], "prohibited_techniques": ["saturation"], "rate_limit_per_minute": 10, "max_concurrency": 1, "window_start": "2026-08-22T11:00:00Z", "window_end": "2099-01-01T00:00:00Z", "operator_contact": "operator", "abort_contact": "operator", "posture_claim": "E2", "attacker_model": "E2-authenticated-tenant-a", "finding_destination": "risk-nexus", "target_owner_acknowledged_at": "2026-08-22T11:01:00Z", } def test_four_custody_schemas_are_published(): schemas = load_schemas() assert set(schemas) == { "custody-projection-contract.schema.json", "custody-broker-readiness.schema.json", "custody-projection-receipt.schema.json", "custody-cleanup-receipt.schema.json", } assert "custody-projection-contract" in schemas["custody-projection-contract.schema.json"]["$id"] assert "custody-broker-readiness" in schemas["custody-broker-readiness.schema.json"]["$id"] assert "custody-projection-receipt" in schemas["custody-projection-receipt.schema.json"]["$id"] assert "custody-cleanup-receipt" in schemas["custody-cleanup-receipt.schema.json"]["$id"] def test_adapter_validates_all_four_document_kinds(): assert validate_projection_contract(contract())["engagement_id"] == "WH-ENG-FIXTURE-1" assert validate_projection_receipt(projection_receipt(), contract=contract())["state"] == "projected" assert validate_cleanup_receipt(cleanup_receipt(), projection=projection_receipt())["state"] == "cleaned" assert validate_broker_readiness(broker_readiness())["owner"] == "whitehat-security" def test_adapter_rejects_secret_material(): tainted = projection_receipt() tainted["token"] = "never" with pytest.raises(AuthorizationError, match="secret material"): validate_projection_receipt(tainted) def test_platform_broker_issues_handles_and_supports_cleanup(tmp_path): path = tmp_path / "engagement.json" path.write_text(json.dumps(live_record()), encoding="utf-8") engagement = Engagement.load(path, now=NOW) broker = PlatformCustodyBroker(projection_receipt(), contract=contract()) assert broker.cleanup_request_supported is True from whitehat_security.targets import load_registration lease = admit( engagement=engagement, registration=load_registration("targets/audit-core-e2.json"), broker=broker, kill_switch=KillSwitch(tmp_path / "KILL"), now=NOW, retired=set(), ) assert {handle.role for handle in lease.identities} == {"attacker", "owner"} assert lease.lease_id.startswith("custody:") with pytest.raises(AuthorizationError, match="custody must revoke"): broker.revoke(lease.lease_id) cleaned = PlatformCustodyBroker( projection_receipt(), contract=contract(), cleanup=cleanup_receipt() ) cleaned.revoke(lease.lease_id) def test_cleanup_receipt_must_match_lease(): with pytest.raises(AuthorizationError, match="lease_id"): bad = cleanup_receipt() bad["lease_id"] = "custody:" + "0" * 32 validate_cleanup_receipt(bad, projection=projection_receipt())