test_trusted_delivery_controls.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. """Security contracts for P3-WP06 trusted-delivery control profiles and gates."""
  2. from __future__ import annotations
  3. from datetime import UTC, datetime, timedelta
  4. from pathlib import Path
  5. import pytest
  6. from app.core.system.trusted_delivery_controls import (
  7. ControlProfileCatalog,
  8. EvidenceLedger,
  9. SupplyChainReleaseGate,
  10. TrustedCapabilityRegistry,
  11. TrustedDeliveryControlError,
  12. )
  13. def _digest(seed: str) -> str:
  14. return (seed * 64)[:64]
  15. def _future() -> str:
  16. return (datetime.now(UTC) + timedelta(minutes=10)).isoformat()
  17. def test_control_profiles_are_versioned_evidence_mappings_not_compliance_claims():
  18. catalog = ControlProfileCatalog()
  19. profiles = [catalog.resolve(name, "1.0") for name in (
  20. "china_general", "finance", "medical", "government"
  21. )]
  22. assert [profile["profile_id"] for profile in profiles] == [
  23. "china_general", "finance", "medical", "government"
  24. ]
  25. assert all(profile["conformance_state"] == "ENGINEERING_EVIDENCE_ONLY" for profile in profiles)
  26. assert all(profile["external_required"] is True for profile in profiles)
  27. assert all(set(profile["external_dependencies"]) == {"security_legal", "identity", "network"} for profile in profiles)
  28. assert all(profile["evidence_mapping"] for profile in profiles)
  29. with pytest.raises(TrustedDeliveryControlError, match="unknown control profile"):
  30. catalog.resolve("medical", "2.0")
  31. def test_capability_registry_defaults_disabled_and_only_issues_bound_signed_envelopes():
  32. registry = TrustedCapabilityRegistry()
  33. with pytest.raises(TrustedDeliveryControlError, match="disabled"):
  34. registry.issue_envelope(
  35. "kms", "kms-key-wrap", {"request_digest": _digest("a"), "expires_at": _future()}
  36. )
  37. fake = TrustedCapabilityRegistry.for_tests({
  38. "kms": {"version": "v1", "config_digest": _digest("b")},
  39. })
  40. envelope = fake.issue_envelope(
  41. "kms", "kms-key-wrap", {"request_digest": _digest("a"), "expires_at": _future()}
  42. )
  43. assert set(envelope) == {"capability", "version", "config_digest", "request_digest", "expires_at", "receipt", "signature"}
  44. assert fake.verify_envelope(envelope) is True
  45. assert "credential" not in str(envelope).lower()
  46. with pytest.raises(TrustedDeliveryControlError, match="replay"):
  47. fake.issue_envelope(
  48. "kms", "kms-key-wrap", {"request_digest": _digest("a"), "expires_at": _future()}
  49. )
  50. with pytest.raises(TrustedDeliveryControlError, match="unsupported"):
  51. fake.issue_envelope(
  52. "kms", "kms-key-wrap", {"request_digest": _digest("c"), "expires_at": _future(), "url": "https://evil.example"}
  53. )
  54. def test_capability_envelope_rejects_expired_wrong_bound_or_tampered_receipt():
  55. fake = TrustedCapabilityRegistry.for_tests({
  56. "dlp": {"version": "v2", "config_digest": _digest("d")},
  57. })
  58. with pytest.raises(TrustedDeliveryControlError, match="expired"):
  59. fake.issue_envelope(
  60. "dlp", "dlp-export-check", {
  61. "request_digest": _digest("e"),
  62. "expires_at": (datetime.now(UTC) - timedelta(seconds=1)).isoformat(),
  63. },
  64. )
  65. envelope = fake.issue_envelope(
  66. "dlp", "dlp-export-check", {"request_digest": _digest("f"), "expires_at": _future()}
  67. )
  68. envelope["request_digest"] = _digest("0")
  69. with pytest.raises(TrustedDeliveryControlError, match="signature"):
  70. fake.verify_envelope(envelope)
  71. def test_capability_registry_rejects_credentials_raw_config_and_unknown_scan_payloads():
  72. assert TrustedCapabilityRegistry().dependency_status() == {
  73. "dlp": "TBD_EXTERNAL", "iam": "TBD_EXTERNAL", "kms": "TBD_EXTERNAL",
  74. "siem": "TBD_EXTERNAL", "target": "TBD_EXTERNAL",
  75. }
  76. with pytest.raises(TrustedDeliveryControlError, match="unsupported"):
  77. TrustedCapabilityRegistry.for_tests({
  78. "siem": {"version": "v1", "config_digest": _digest("a"), "url": "https://evil.example"},
  79. })
  80. with pytest.raises(TrustedDeliveryControlError, match="unsafe"):
  81. TrustedCapabilityRegistry.for_tests({
  82. "siem": {"version": "secret-v1", "config_digest": _digest("a")},
  83. })
  84. with pytest.raises(TrustedDeliveryControlError, match="unsupported"):
  85. SupplyChainReleaseGate().evaluate({
  86. "artifact_digest": _digest("a"), "sbom_digest": _digest("b"),
  87. "license_policy_digest": _digest("c"), "vulnerability_scan_digest": _digest("d"),
  88. "approval_id": "release-approval-1", "approval_version": "v1",
  89. "scan_decision": "passed", "evidence_expires_at": _future(),
  90. "raw_scan": "password=must-not-persist",
  91. })
  92. def test_control_contract_deployment_copy_is_exact():
  93. root = Path(__file__).resolve().parents[2]
  94. source = root / "app/core/system/trusted_delivery_controls.py"
  95. deployed = root / "deployment/app/core/system/trusted_delivery_controls.py"
  96. assert deployed.read_bytes() == source.read_bytes()
  97. def test_supply_chain_gate_fails_closed_and_returns_digest_only_approval_summary():
  98. gate = SupplyChainReleaseGate(now_factory=lambda: datetime(2026, 8, 11, tzinfo=UTC))
  99. with pytest.raises(TrustedDeliveryControlError, match="missing"):
  100. gate.evaluate({"artifact_digest": _digest("a")})
  101. with pytest.raises(TrustedDeliveryControlError, match="rejected"):
  102. gate.evaluate({
  103. "artifact_digest": _digest("a"), "sbom_digest": _digest("b"),
  104. "license_policy_digest": _digest("c"), "vulnerability_scan_digest": _digest("d"),
  105. "approval_id": "release-approval-1", "approval_version": "v1",
  106. "scan_decision": "failed", "evidence_expires_at": "2026-08-12T00:00:00+00:00",
  107. })
  108. summary = gate.evaluate({
  109. "artifact_digest": _digest("a"), "sbom_digest": _digest("b"),
  110. "license_policy_digest": _digest("c"), "vulnerability_scan_digest": _digest("d"),
  111. "approval_id": "release-approval-1", "approval_version": "v1",
  112. "scan_decision": "passed", "evidence_expires_at": "2026-08-12T00:00:00+00:00",
  113. })
  114. assert summary["decision_code"] == "RELEASE_GATE_APPROVED"
  115. assert set(summary) == {"decision_code", "artifact_digest", "sbom_digest", "license_policy_digest", "vulnerability_scan_digest", "approval_id", "approval_version", "evidence_expires_at"}
  116. assert "scan" not in str(summary).lower() or "digest" in str(summary).lower()
  117. def test_evidence_ledger_exports_only_immutable_references_and_blocks_hold_or_single_party_destruction():
  118. ledger = EvidenceLedger()
  119. ledger.append({
  120. "evidence_ref": "trusted-evidence:delivery-001", "evidence_digest": _digest("a"),
  121. "decision_code": "DELIVERY_ALLOWED",
  122. })
  123. assert ledger.export_summary() == [{
  124. "evidence_ref": "trusted-evidence:delivery-001", "evidence_digest": _digest("a"),
  125. "decision_code": "DELIVERY_ALLOWED",
  126. }]
  127. with pytest.raises(TrustedDeliveryControlError, match="active legal hold"):
  128. ledger.approve_destruction({"approval_refs": ["case-1", "case-2"], "active_hold": True})
  129. with pytest.raises(TrustedDeliveryControlError, match="two independent"):
  130. ledger.approve_destruction({"approval_refs": ["case-1", "case-1"], "active_hold": False})
  131. result = ledger.approve_destruction({"approval_refs": ["case-1", "case-2"], "active_hold": False})
  132. assert result["decision_code"] == "DESTRUCTION_DUAL_APPROVED"
  133. with pytest.raises(TrustedDeliveryControlError, match="immutable"):
  134. ledger.tamper({"evidence_ref": "trusted-evidence:delivery-001", "replacement": "raw secret"})
  135. assert ledger.audit_events()[-1]["decision_code"] == "TAMPER_REJECTED"