Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m38s
CD Pipeline / build-and-deploy (push) Failing after 24m19s
CD Pipeline / post-deploy-checks (push) Has been skipped
257 lines
8.7 KiB
Python
257 lines
8.7 KiB
Python
from __future__ import annotations
|
|
|
|
import os
|
|
from dataclasses import replace
|
|
from datetime import UTC, datetime, timedelta
|
|
from uuid import UUID, uuid4
|
|
|
|
import pytest
|
|
|
|
os.environ.setdefault("DATABASE_URL", "postgresql+asyncpg://test:test@localhost/test")
|
|
|
|
from src.services.paid_provider_canary_authorization import ( # noqa: E402
|
|
PAID_CANARY_AGENT_ID,
|
|
PAID_CANARY_PROJECT_ID,
|
|
PAID_CANARY_TRIGGER_REF,
|
|
PAID_CANARY_TRIGGER_TYPE,
|
|
PAID_CANARY_WORK_ITEM_ID,
|
|
PaidProviderCanaryAuthorizationError,
|
|
PaidProviderCanaryAuthorizationEvidence,
|
|
paid_provider_canary_authorization_input,
|
|
paid_provider_canary_authorization_input_sha256,
|
|
require_paid_provider_canary_authorization,
|
|
verify_paid_provider_canary_authorization,
|
|
)
|
|
|
|
_SELECTED_RUN_ID = UUID("267a3d26-3c29-470f-8fe3-388a2f408f39")
|
|
_TRACE_ID = "00-0123456789abcdef0123456789abcdef-0123456789abcdef-01"
|
|
|
|
|
|
class _Reader:
|
|
def __init__(
|
|
self,
|
|
evidence: PaidProviderCanaryAuthorizationEvidence | None,
|
|
*,
|
|
error: Exception | None = None,
|
|
) -> None:
|
|
self.evidence = evidence
|
|
self.error = error
|
|
self.calls: list[tuple[UUID, str, str]] = []
|
|
|
|
async def read(
|
|
self,
|
|
*,
|
|
run_id: UUID,
|
|
project_id: str,
|
|
work_item_id: str,
|
|
) -> PaidProviderCanaryAuthorizationEvidence | None:
|
|
self.calls.append((run_id, project_id, work_item_id))
|
|
if self.error is not None:
|
|
raise self.error
|
|
return self.evidence
|
|
|
|
|
|
def _evidence(
|
|
*,
|
|
now: datetime,
|
|
run_id: UUID | None = None,
|
|
) -> PaidProviderCanaryAuthorizationEvidence:
|
|
return PaidProviderCanaryAuthorizationEvidence(
|
|
run_id=run_id or _SELECTED_RUN_ID,
|
|
trace_id=_TRACE_ID,
|
|
project_id=PAID_CANARY_PROJECT_ID,
|
|
agent_id=PAID_CANARY_AGENT_ID,
|
|
state="running",
|
|
trigger_type=PAID_CANARY_TRIGGER_TYPE,
|
|
trigger_ref=PAID_CANARY_TRIGGER_REF,
|
|
is_shadow=False,
|
|
input_sha256=paid_provider_canary_authorization_input_sha256(),
|
|
timeout_at=now + timedelta(minutes=5),
|
|
approval_step_count=1,
|
|
approval_step_status="success",
|
|
approval_step_was_blocked=False,
|
|
approval_completed_at=now - timedelta(minutes=1),
|
|
approval_audit_count=1,
|
|
approval_audit_created_at=now - timedelta(seconds=50),
|
|
prior_canary_start_count=0,
|
|
)
|
|
|
|
|
|
def test_authorization_input_is_detached_and_hash_is_stable() -> None:
|
|
first = paid_provider_canary_authorization_input()
|
|
second = paid_provider_canary_authorization_input()
|
|
|
|
first["provider_order"].append("unexpected")
|
|
|
|
assert second["project_id"] == "awoooi"
|
|
assert second["work_item_id"] == "AIA-SRE-013"
|
|
assert "unexpected" not in second["provider_order"]
|
|
assert len(paid_provider_canary_authorization_input_sha256()) == 64
|
|
assert (
|
|
paid_provider_canary_authorization_input_sha256()
|
|
== paid_provider_canary_authorization_input_sha256()
|
|
)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_exact_gate5_evidence_returns_non_sensitive_authorized_receipt() -> None:
|
|
now = datetime(2026, 7, 16, 8, 0, tzinfo=UTC)
|
|
evidence = _evidence(now=now)
|
|
reader = _Reader(evidence)
|
|
|
|
receipt = await verify_paid_provider_canary_authorization(
|
|
str(evidence.run_id),
|
|
evidence_reader=reader,
|
|
now=now,
|
|
)
|
|
|
|
assert receipt["authorized"] is True
|
|
assert receipt["status"] == "authorized"
|
|
assert receipt["authorization_ref"] == str(evidence.run_id)
|
|
assert receipt["run_id"] == str(evidence.run_id)
|
|
assert receipt["trace_id"] == _TRACE_ID
|
|
assert receipt["project_id"] == "awoooi"
|
|
assert receipt["work_item_id"] == "AIA-SRE-013"
|
|
assert receipt["valid_for_seconds"] == 300
|
|
assert receipt["checks"]["authorization_unused"] is True
|
|
assert receipt["checks"]["authorization_run_selected"] is True
|
|
assert receipt["contract"]["same_run_identity"] is True
|
|
assert receipt["reuse_check"] == "clear_at_read_time"
|
|
assert receipt["read_only_verification"] is True
|
|
assert receipt["authorization_consumed_by_verifier"] is False
|
|
assert receipt["operator_identity_returned"] is False
|
|
assert receipt["secret_value_read_or_returned"] is False
|
|
assert "approver_id" not in str(receipt)
|
|
assert reader.calls == [
|
|
(evidence.run_id, PAID_CANARY_PROJECT_ID, PAID_CANARY_WORK_ITEM_ID)
|
|
]
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_authorization_ref_must_be_canonical_uuid_without_db_read() -> None:
|
|
reader = _Reader(None)
|
|
|
|
malformed = await verify_paid_provider_canary_authorization(
|
|
"AIA-SRE-013-user-approved-20260716",
|
|
evidence_reader=reader,
|
|
)
|
|
uppercase = await verify_paid_provider_canary_authorization(
|
|
str(uuid4()).upper(),
|
|
evidence_reader=reader,
|
|
)
|
|
|
|
assert malformed["authorized"] is False
|
|
assert malformed["error_code"] == (
|
|
"paid_canary_authorization_ref_must_be_uuid_run_id"
|
|
)
|
|
assert uppercase["authorized"] is False
|
|
assert uppercase["error_code"] == (
|
|
"paid_canary_authorization_ref_not_canonical_uuid"
|
|
)
|
|
assert reader.calls == []
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.parametrize(
|
|
("field", "value", "failed_check"),
|
|
[
|
|
("project_id", "other", "project_exact"),
|
|
(
|
|
"run_id",
|
|
UUID("00000000-0000-4000-8000-000000000001"),
|
|
"authorization_run_selected",
|
|
),
|
|
("agent_id", "generic-agent", "agent_exact"),
|
|
("state", "waiting_approval", "state_executable"),
|
|
("is_shadow", True, "non_shadow"),
|
|
("trigger_type", "schedule", "trigger_type_exact"),
|
|
("trigger_ref", "paid-provider-canary:OTHER", "trigger_ref_exact"),
|
|
("input_sha256", "0" * 64, "input_sha256_exact"),
|
|
("trace_id", None, "trace_id_present"),
|
|
("approval_step_count", 0, "approval_step_exactly_once"),
|
|
("approval_step_status", "failed", "approval_step_success"),
|
|
("approval_step_was_blocked", True, "approval_step_not_blocked"),
|
|
("approval_audit_count", 0, "approval_audit_exactly_once"),
|
|
("prior_canary_start_count", 1, "authorization_unused"),
|
|
],
|
|
)
|
|
async def test_contract_drift_fails_closed(
|
|
field: str,
|
|
value: object,
|
|
failed_check: str,
|
|
) -> None:
|
|
now = datetime(2026, 7, 16, 8, 0, tzinfo=UTC)
|
|
evidence = replace(_evidence(now=now), **{field: value})
|
|
|
|
receipt = await verify_paid_provider_canary_authorization(
|
|
str(evidence.run_id),
|
|
evidence_reader=_Reader(evidence),
|
|
now=now,
|
|
)
|
|
|
|
assert receipt["authorized"] is False
|
|
assert failed_check in receipt["failed_checks"]
|
|
assert receipt["checks"][failed_check] is False
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_missing_timeout_or_expired_approval_fails_closed() -> None:
|
|
now = datetime(2026, 7, 16, 8, 0, tzinfo=UTC)
|
|
missing_timeout = replace(_evidence(now=now), timeout_at=None)
|
|
expired = replace(
|
|
_evidence(now=now),
|
|
approval_completed_at=now - timedelta(minutes=16),
|
|
timeout_at=now + timedelta(minutes=5),
|
|
)
|
|
|
|
missing_receipt = await verify_paid_provider_canary_authorization(
|
|
str(missing_timeout.run_id),
|
|
evidence_reader=_Reader(missing_timeout),
|
|
now=now,
|
|
)
|
|
expired_receipt = await verify_paid_provider_canary_authorization(
|
|
str(expired.run_id),
|
|
evidence_reader=_Reader(expired),
|
|
now=now,
|
|
)
|
|
|
|
assert missing_receipt["authorized"] is False
|
|
assert missing_receipt["checks"]["run_timeout_present"] is False
|
|
assert expired_receipt["authorized"] is False
|
|
assert expired_receipt["checks"]["authorization_not_expired"] is False
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_db_error_and_missing_run_are_blocked_without_error_detail() -> None:
|
|
run_id = uuid4()
|
|
|
|
unavailable = await verify_paid_provider_canary_authorization(
|
|
str(run_id),
|
|
evidence_reader=_Reader(None, error=RuntimeError("database dsn secret")),
|
|
)
|
|
missing = await verify_paid_provider_canary_authorization(
|
|
str(run_id),
|
|
evidence_reader=_Reader(None),
|
|
)
|
|
|
|
assert unavailable["error_code"] == (
|
|
"paid_canary_authorization_evidence_unavailable"
|
|
)
|
|
assert "database dsn secret" not in str(unavailable)
|
|
assert missing["error_code"] == "paid_canary_authorization_run_not_found"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_require_helper_raises_only_safe_error_code() -> None:
|
|
run_id = uuid4()
|
|
|
|
with pytest.raises(PaidProviderCanaryAuthorizationError) as raised:
|
|
await require_paid_provider_canary_authorization(
|
|
str(run_id),
|
|
evidence_reader=_Reader(None),
|
|
)
|
|
|
|
assert raised.value.error_code == "paid_canary_authorization_run_not_found"
|
|
assert str(raised.value) == raised.value.error_code
|
|
assert raised.value.receipt["authorized"] is False
|