Files
aios/tests/test_governed_provider_auth_adapter.py
T

142 lines
4.8 KiB
Python

from __future__ import annotations
import os
from dataclasses import dataclass
from datetime import datetime, timezone
from pathlib import Path
import pytest
from governed_provider_auth_adapter import (
ALL_RELEASE_EVIDENCE_KINDS,
authenticate_build_artifacts,
gate_w_authentication_status,
)
from trusted_provider_receipts import (
PROVIDER_RECEIPT_SCHEMA,
PROVIDER_RECEIPT_VERSION,
ProviderAuthenticationError,
TrustedProviderPolicy,
TrustedProviderReceiptResolver,
canonical_json_bytes,
canonical_sha256,
)
SOURCE = "a" * 40
TREE = "b" * 40
NOW = datetime(2026, 9, 9, 5, 0, tzinfo=timezone.utc)
@dataclass(frozen=True)
class FakeBuild:
source_commit: str
tree_oid: str
tests: dict
canary: dict
gitea: dict
rollback: dict
secret_scan: dict
def _policy(kind: str, root: Path) -> TrustedProviderPolicy:
return TrustedProviderPolicy(
evidence_kind=kind,
provider_identity=f"aios.{kind}-provider",
store_id=kind,
store_root=root / kind,
allowed_operations=frozenset({f"{kind}.run"}),
expected_owner_uid=os.getuid(),
allowed_directory_modes=frozenset({0o700}),
allowed_receipt_modes=frozenset({0o600}),
max_age_seconds=300,
)
def _write_receipt(root: Path, kind: str, result: dict) -> str:
store = root / kind
store.mkdir(parents=True, exist_ok=True, mode=0o700)
os.chmod(store, 0o700)
ref = f"run-1/{kind}.json"
path = store / ref
path.parent.mkdir(parents=True, exist_ok=True)
os.chmod(path.parent, 0o700)
payload = {
"schema": PROVIDER_RECEIPT_SCHEMA,
"version": PROVIDER_RECEIPT_VERSION,
"provider_identity": f"aios.{kind}-provider",
"provider_operation": f"{kind}.run",
"operation_run_id": f"{kind}-run-1",
"result_reference": f"runs/{kind}-run-1/result.json",
"content_sha256": canonical_sha256(result),
"source_oid": SOURCE,
"tree_oid": TREE,
"environment": "linux-isolated",
"issued_at": "2026-09-09T04:59:00+00:00",
"result": result,
"authentication": {"kind": "root-owned-store-v1", "store_id": kind},
}
path.write_bytes(canonical_json_bytes(payload))
os.chmod(path, 0o600)
return ref
def _resolver(root: Path):
policies = {kind: _policy(kind, root) for kind in ALL_RELEASE_EVIDENCE_KINDS}
return TrustedProviderReceiptResolver(policies, now_fn=lambda: NOW)
def _request(root: Path) -> FakeBuild:
refs = {}
for kind in ALL_RELEASE_EVIDENCE_KINDS:
result = {"passed": True, "kind": kind}
if kind == "gitea":
result = {"consistent": True, "kind": kind}
elif kind == "rollback":
result = {"ready": True, "kind": kind}
refs[kind] = {"receipt_ref": _write_receipt(root, kind, result)}
return FakeBuild(source_commit=SOURCE, tree_oid=TREE, **refs)
def test_full_release_authentication_replaces_receipt_refs_with_authenticated_results(tmp_path: Path):
request = _request(tmp_path)
authenticated = authenticate_build_artifacts(request, resolver=_resolver(tmp_path))
assert authenticated.tests["passed"] is True
assert authenticated.gitea["consistent"] is True
assert authenticated.rollback["ready"] is True
assert authenticated.tests["provider_receipt"]["provider_identity"] == "aios.tests-provider"
assert "receipt_ref" not in authenticated.tests
def test_missing_resolver_fails_closed(tmp_path: Path):
request = _request(tmp_path)
with pytest.raises(ProviderAuthenticationError, match="PROVIDER_AUTHENTICATION_REQUIRED"):
authenticate_build_artifacts(request, resolver=None)
def test_gate_w_authenticates_only_currently_real_provider_classes(tmp_path: Path):
request = _request(tmp_path)
# Remove canary/rollback stores entirely; Gate W must not pretend final
# release closure exists, but it can validate tests/Gitea/secret-scan.
for kind in ("canary", "rollback"):
store = tmp_path / kind
for child in sorted(store.rglob("*"), reverse=True):
if child.is_file():
child.unlink()
elif child.is_dir():
child.rmdir()
store.rmdir()
status = gate_w_authentication_status(request, resolver=_resolver(tmp_path))
assert status == {
"producer_runtime": "PRODUCER_RUNTIME_REGISTRATION_PASS",
"provider_auth": "PROVIDER_AUTH_ENFORCEMENT_PASS",
"final_release_closure": "FINAL_RELEASE_CLOSURE_PENDING_GATE_R",
}
def test_full_release_authentication_requires_canary_and_rollback_receipts(tmp_path: Path):
request = _request(tmp_path)
(tmp_path / "canary" / "run-1" / "canary.json").unlink()
with pytest.raises(ProviderAuthenticationError, match="PROVIDER_RECEIPT_UNAVAILABLE"):
authenticate_build_artifacts(request, resolver=_resolver(tmp_path))