Files
govoplan/tools/assessments/govoplan_assessment/evidence.py

2899 lines
108 KiB
Python

"""Bounded installed-composition and externally authorized fit evidence."""
from __future__ import annotations
import base64
import csv
from dataclasses import dataclass
from datetime import UTC, datetime, timedelta
import hashlib
import hmac
from importlib import metadata
from importlib.util import source_from_cache
import io
import json
import os
from pathlib import Path, PurePosixPath
import re
import stat
import sys
from typing import Any, Iterable, Mapping, Sequence
from urllib.parse import urlsplit
from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
from jsonschema import Draft202012Validator, FormatChecker
from jsonschema.exceptions import SchemaError
from govoplan_release.artifact_identity import (
INSTALLED_PAYLOAD_ALGORITHM,
WHEEL_PAYLOAD_ALGORITHM,
payload_identity_sha256,
)
MAX_GOVOPLAN_DISTRIBUTIONS = 256
MAX_DISTRIBUTION_FILES = 10_000
MAX_COLLECTION_RECORD_FILES = 50_000
MAX_RECORD_BYTES = 4 * 1024 * 1024
MAX_RECORD_PATH_CHARACTERS = 4096
MAX_HASHED_FILE_BYTES = 64 * 1024 * 1024
MAX_HASHED_DISTRIBUTION_BYTES = 512 * 1024 * 1024
MAX_HASHED_COLLECTION_BYTES = 2 * 1024 * 1024 * 1024
MAX_DIRECT_URL_BYTES = 64 * 1024
MAX_LOCAL_OBSERVATION_AGE = timedelta(minutes=5)
MAX_LOCAL_OBSERVATION_FUTURE_SKEW = timedelta(seconds=30)
INSTALLED_OBSERVATION_MODES = frozenset({"direct_local", "imported_unsigned"})
VERIFICATION_MODES = frozenset({"current", "historical_override"})
PACKAGE_PATTERN = re.compile(r"^[a-z0-9]+(?:-[a-z0-9]+)*$")
OPAQUE_ID_PATTERN = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._:-]*$")
VERSION_PATTERN = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._+!-]*$")
ENTRY_POINT_VALUE_PATTERN = re.compile(
r"^[A-Za-z_][A-Za-z0-9_.]*(?::[A-Za-z_][A-Za-z0-9_.]*)?(?:\s*\[[A-Za-z0-9_., -]+\])?$"
)
VCS_REVISION_PATTERN = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._/+~-]{0,159}$")
GIT_OBJECT_PATTERN = re.compile(r"^[0-9a-f]{40,64}$")
SHA256_PATTERN = re.compile(r"^[0-9a-f]{64}$")
POSITIVE_RESULTS = {
"target_environment": "passed",
"external_providers": "passed",
"production_approval": "approved",
}
NEGATIVE_RESULTS = {
"target_environment": "failed",
"external_providers": "failed",
"production_approval": "rejected",
}
PROOF_REQUIREMENTS = {
"target_environment": (
"A target-run result bound to this assessment release and installed evidence whose release origin is independently anchored.",
"An independently trusted authority key permitted for target_environment proof.",
"Opaque control IDs and content hashes for the target acceptance artifacts.",
),
"external_providers": (
"Provider acceptance results bound to this assessment release and installed evidence whose release origin is independently anchored.",
"An independently trusted authority key permitted for external_providers proof.",
"Opaque control IDs and content hashes; credentials and endpoint identifiers stay outside the report.",
),
"production_approval": (
"An explicit approval bound to this assessment release and installed evidence whose release origin is independently anchored.",
"An independently provisioned authority key permitted for production_approval.",
"An unexpired signed proof bundle; an assessment or operator cannot approve itself.",
),
}
@dataclass(frozen=True, slots=True)
class EvidenceFinding:
severity: str
code: str
message: str
assessment_ids: tuple[str, ...] = ()
@dataclass(frozen=True, slots=True)
class InstalledEvidenceReview:
findings: tuple[EvidenceFinding, ...]
changes: tuple[dict[str, Any], ...]
changed_repositories: frozenset[str]
affected_module_ids: frozenset[str]
proof_scope: Mapping[str, Any]
evidence_sha256: str | None
@dataclass(frozen=True, slots=True)
class BoundaryEvidenceReview:
findings: tuple[EvidenceFinding, ...]
proof_scope: Mapping[str, Any]
review_targets: tuple[dict[str, Any], ...] = ()
@dataclass(slots=True)
class CollectionHashBudget:
remaining_files: int = MAX_COLLECTION_RECORD_FILES
remaining_bytes: int = MAX_HASHED_COLLECTION_BYTES
@dataclass(frozen=True, slots=True)
class RecordEntry:
path: str
hash_mode: str | None
hash_value: str | None
size: int | None
def validate_payload(
*, payload: dict[str, Any], schema: dict[str, Any]
) -> tuple[str, ...]:
try:
Draft202012Validator.check_schema(schema)
except SchemaError as exc:
return (f"$schema: {exc.message}",)
validator = Draft202012Validator(schema, format_checker=FormatChecker())
return tuple(
f"{_json_path(error.absolute_path)}: failed {error.validator!r} validation"
for error in sorted(
validator.iter_errors(payload),
key=lambda item: (
tuple(str(part) for part in item.absolute_path),
str(item.validator),
item.message,
),
)
)
def collect_installed_composition(
*,
assessment: dict[str, Any],
collected_at: datetime | None = None,
distributions: Iterable[metadata.Distribution] | None = None,
) -> dict[str, Any]:
"""Collect only bounded, non-identifying GovOPlaN distribution evidence.
Loading ``govoplan.modules`` entry points executes installed module code. The
collector catches failures and records only a stable error code; it never
serializes exception text, URLs, local paths, hostnames, or usernames.
"""
artifacts: list[dict[str, Any]] = []
issues: list[dict[str, str]] = []
hash_budget = CollectionHashBudget()
candidates: list[tuple[str, metadata.Distribution]] = []
source = metadata.distributions() if distributions is None else distributions
for distribution in source:
try:
raw_package_name = distribution.metadata["Name"]
if not isinstance(raw_package_name, str) or len(raw_package_name) > 256:
continue
package_name = normalize_package_name(raw_package_name)
except (Exception, SystemExit):
continue
if (
package_name.startswith("govoplan-")
and len(package_name) <= 128
and PACKAGE_PATTERN.fullmatch(package_name) is not None
):
candidates.append((package_name, distribution))
candidates.sort(key=lambda item: (item[0], _distribution_version(item[1])))
if len(candidates) > MAX_GOVOPLAN_DISTRIBUTIONS:
candidates = candidates[:MAX_GOVOPLAN_DISTRIBUTIONS]
issues.append(
{
"code": "collection-limit-exceeded",
"package_name": "govoplan-collector",
}
)
name_counts: dict[str, int] = {}
for package_name, _ in candidates:
name_counts[package_name] = name_counts.get(package_name, 0) + 1
for package_name, count in sorted(name_counts.items()):
if count > 1:
issues.append(
{
"code": "duplicate-distribution",
"package_name": package_name,
}
)
for package_name, distribution in candidates:
version = _distribution_version(distribution)
if not version:
issues.append(
{
"code": "distribution-metadata-invalid",
"package_name": package_name
if PACKAGE_PATTERN.fullmatch(package_name)
else "govoplan-invalid",
}
)
continue
modules, module_issues = _distribution_modules(
package_name=package_name,
distribution=distribution,
)
issues.extend(module_issues)
artifacts.append(
{
"package_name": package_name,
"package_version": version,
"modules": modules,
"source_provenance": _source_provenance(distribution),
"record_integrity": _record_integrity(
distribution,
package_name=package_name,
budget=hash_budget,
),
}
)
observed_at = collected_at or datetime.now(tz=UTC)
if observed_at.tzinfo is None:
observed_at = observed_at.replace(tzinfo=UTC)
release = assessment.get("release")
assessment_release = release.get("ref") if isinstance(release, dict) else None
sorted_issues = sorted(
_unique_dicts(issues),
key=lambda item: (item["package_name"], item["code"]),
)
if len(sorted_issues) > 256:
limit_issue = {
"code": "collection-limit-exceeded",
"package_name": "govoplan-collector",
}
sorted_issues = sorted_issues[:255]
if limit_issue not in sorted_issues:
sorted_issues.append(limit_issue)
sorted_issues.sort(key=lambda item: (item["package_name"], item["code"]))
return {
"$schema": "./installed-composition-evidence.schema.json",
"schema_version": "0.4.0",
"evidence_kind": "govoplan.installed-composition",
"assessment_id": _safe_opaque_id(
assessment.get("assessment_id"), fallback="invalid-assessment"
),
"assessment_release": _safe_opaque_id(
assessment_release, fallback="invalid-release"
),
"collected_at": observed_at.astimezone(UTC).isoformat().replace("+00:00", "Z"),
"scope": "current-python-environment.govoplan-distributions",
"artifacts": sorted(
artifacts,
key=lambda item: (
item["package_name"],
item["package_version"],
canonical_bytes(item),
),
),
"collection_issues": sorted_issues,
}
def review_installed_composition(
*,
assessment: dict[str, Any],
catalog_entries: Mapping[str, Mapping[str, Any]],
selected_versions: Mapping[str, str],
selected_commits: Mapping[str, str],
evidence: dict[str, Any] | None,
schema: dict[str, Any] | None,
observation_mode: str = "imported_unsigned",
verification_time: datetime | None = None,
verification_mode: str = "current",
catalog_trusted: bool = False,
catalog_artifacts: object = None,
catalog_sha256: str | None = None,
catalog_channel: str | None = None,
catalog_sequence: int | None = None,
installer_receipt: dict[str, Any] | None = None,
installer_receipt_schema: dict[str, Any] | None = None,
installer_authority_keyring: dict[str, Any] | None = None,
installer_authority_keyring_schema: dict[str, Any] | None = None,
forbidden_installer_public_keys: frozenset[bytes] = frozenset(),
) -> InstalledEvidenceReview:
if evidence is None:
return InstalledEvidenceReview(
findings=(),
changes=(),
changed_repositories=frozenset(),
affected_module_ids=frozenset(),
proof_scope=_unchecked_installed_scope(),
evidence_sha256=None,
)
digest = canonical_sha256(evidence)
if schema is None:
finding = EvidenceFinding(
"blocker",
"installed_evidence_schema_missing",
"Installed evidence was supplied without its validation schema.",
("assessment.installed_composition",),
)
return InstalledEvidenceReview(
findings=(finding,),
changes=(),
changed_repositories=frozenset(),
affected_module_ids=frozenset(),
proof_scope=_invalid_installed_scope(digest=digest),
evidence_sha256=digest,
)
schema_errors = validate_payload(payload=evidence, schema=schema)
if schema_errors:
findings = tuple(
EvidenceFinding(
"blocker",
"installed_evidence_schema",
message,
("assessment.installed_composition",),
)
for message in schema_errors
)
return InstalledEvidenceReview(
findings=findings,
changes=(),
changed_repositories=frozenset(),
affected_module_ids=frozenset(),
proof_scope=_invalid_installed_scope(digest=digest),
evidence_sha256=digest,
)
findings: list[EvidenceFinding] = []
effective_observation_mode = (
observation_mode
if observation_mode in INSTALLED_OBSERVATION_MODES
else "invalid"
)
effective_verification_mode = (
verification_mode if verification_mode in VERIFICATION_MODES else "invalid"
)
if effective_observation_mode == "invalid":
findings.append(
EvidenceFinding(
"blocker",
"installed_evidence_observation_mode",
"Installed evidence observation mode is invalid.",
("assessment.installed_composition",),
)
)
if effective_verification_mode == "invalid":
findings.append(
EvidenceFinding(
"blocker",
"installed_evidence_verification_mode",
"Installed evidence verification mode is invalid.",
("assessment.installed_composition",),
)
)
if catalog_trusted is not True:
findings.append(
EvidenceFinding(
"blocker",
"installed_catalog_trust_unavailable",
"Installed-composition proof depends on a valid signed catalog.",
("assessment.release", "assessment.installed_composition"),
)
)
changes: list[dict[str, Any]] = []
changed_repositories: set[str] = set()
affected_module_ids: set[str] = set()
now = verification_time or datetime.now(tz=UTC)
if now.tzinfo is None:
now = now.replace(tzinfo=UTC)
collected_at = _datetime(evidence.get("collected_at"))
observation_trusted = False
freshness = "invalid"
if effective_observation_mode == "direct_local":
if collected_at is None:
findings.append(
EvidenceFinding(
"blocker",
"installed_evidence_time_invalid",
"Direct installed evidence has no valid collection time.",
("assessment.installed_composition",),
)
)
elif collected_at > now + MAX_LOCAL_OBSERVATION_FUTURE_SKEW:
freshness = "future"
findings.append(
EvidenceFinding(
"blocker",
"installed_evidence_from_future",
"Direct installed evidence is newer than the permitted clock skew.",
("assessment.installed_composition",),
)
)
elif now - collected_at > MAX_LOCAL_OBSERVATION_AGE:
freshness = "stale"
findings.append(
EvidenceFinding(
"blocker",
"installed_evidence_stale",
"Direct installed evidence is older than the five-minute acceptance window.",
("assessment.installed_composition",),
)
)
else:
freshness = "fresh"
observation_trusted = True
elif effective_observation_mode == "imported_unsigned":
freshness = "unsigned_import"
if effective_verification_mode == "invalid":
observation_trusted = False
if catalog_trusted is not True:
observation_trusted = False
expected_release = (
assessment.get("release", {}).get("ref")
if isinstance(assessment.get("release"), dict)
else None
)
binding_valid = True
if evidence.get("assessment_id") != assessment.get("assessment_id"):
binding_valid = False
findings.append(
EvidenceFinding(
"blocker",
"installed_evidence_assessment_mismatch",
"Installed evidence is bound to a different assessment ID.",
("assessment.installed_composition",),
)
)
if evidence.get("assessment_release") != expected_release:
binding_valid = False
findings.append(
EvidenceFinding(
"blocker",
"installed_evidence_release_mismatch",
"Installed evidence is bound to a different assessment release.",
("assessment.release", "assessment.installed_composition"),
)
)
artifact_rows = [
item for item in evidence.get("artifacts", []) if isinstance(item, dict)
]
artifacts_by_package: dict[str, dict[str, Any]] = {}
duplicate_packages: set[str] = set()
for artifact in artifact_rows:
package_name = normalize_package_name(str(artifact.get("package_name") or ""))
if package_name in artifacts_by_package:
duplicate_packages.add(package_name)
else:
artifacts_by_package[package_name] = artifact
for package_name in sorted(duplicate_packages):
binding_valid = False
findings.append(
EvidenceFinding(
"blocker",
"installed_distribution_duplicate",
f"Installed evidence repeats distribution {package_name!r}.",
("assessment.installed_composition",),
)
)
expected_by_package: dict[str, tuple[dict[str, Any], Mapping[str, Any]]] = {}
assessment_by_module: dict[str, dict[str, Any]] = {}
for component in assessment.get("composition", []):
if not isinstance(component, dict):
continue
module_id = str(component.get("module_id") or "")
assessment_by_module[module_id] = component
if component.get("enabled") is not True:
continue
catalog_entry = catalog_entries.get(module_id)
if catalog_entry is None:
binding_valid = False
findings.append(
EvidenceFinding(
"blocker",
"installed_expected_catalog_entry_missing",
f"Enabled module {module_id!r} cannot be mapped to a catalog package.",
(f"composition.{module_id}",),
)
)
continue
package_name = normalize_package_name(str(catalog_entry.get("package") or ""))
if not package_name:
binding_valid = False
findings.append(
EvidenceFinding(
"blocker",
"installed_expected_package_missing",
f"Enabled module {module_id!r} has no valid catalog package name.",
(f"composition.{module_id}",),
)
)
continue
if package_name in expected_by_package:
binding_valid = False
findings.append(
EvidenceFinding(
"blocker",
"installed_expected_package_ambiguous",
f"Multiple enabled composition entries map to {package_name!r}.",
("assessment.installed_composition",),
)
)
continue
expected_by_package[package_name] = (component, catalog_entry)
if not expected_by_package:
binding_valid = False
findings.append(
EvidenceFinding(
"blocker",
"installed_expected_composition_empty",
"Installed proof requires at least one enabled assessment component mapped to a catalog package.",
("assessment.installed_composition",),
)
)
record_expected = 0
record_verified = 0
generated_unhashed_file_count = 0
provenance_expected = 0
provenance_declared_match = 0
provenance_mutable = 0
provenance_unanchored = 0
payload_consistent = binding_valid and not duplicate_packages
for package_name, (component, catalog_entry) in sorted(expected_by_package.items()):
module_id = str(component["module_id"])
repository = str(component["repository"])
artifact = artifacts_by_package.get(package_name)
record_expected += 1
provenance_expected += 1
if package_name in duplicate_packages:
payload_consistent = False
_record_change(
findings=findings,
changes=changes,
changed_repositories=changed_repositories,
affected_module_ids=affected_module_ids,
component=component,
kind="installed_distribution_duplicate",
code="installed_distribution_duplicate_ambiguous",
message=f"Installed distribution {package_name!r} is duplicated, so no candidate was selected for integrity or provenance conclusions.",
)
continue
if artifact is None:
payload_consistent = False
_record_change(
findings=findings,
changes=changes,
changed_repositories=changed_repositories,
affected_module_ids=affected_module_ids,
component=component,
kind="installed_distribution_missing",
code="installed_distribution_missing",
message=f"Enabled module {module_id!r} has no installed distribution {package_name!r} in the evidence.",
)
continue
expected_version = str(component["manifest_version"])
package_version = str(artifact.get("package_version") or "")
catalog_version = str(catalog_entry.get("version") or "")
if package_version != expected_version or package_version != catalog_version:
payload_consistent = False
_record_change(
findings=findings,
changes=changes,
changed_repositories=changed_repositories,
affected_module_ids=affected_module_ids,
component=component,
kind="installed_version_mismatch",
code="installed_distribution_version_mismatch",
message=(
f"Installed {package_name!r} version {package_version!r} does not match "
f"assessment {expected_version!r} and catalog {catalog_version!r}."
),
extra={
"installed_version": package_version,
"assessed_version": expected_version,
"catalog_version": catalog_version,
},
)
modules = [
item for item in artifact.get("modules", []) if isinstance(item, dict)
]
module_rows: dict[str, dict[str, Any]] = {}
duplicate_module_ids: set[str] = set()
for item in modules:
observed_id = str(item.get("module_id") or "")
if observed_id in module_rows:
duplicate_module_ids.add(observed_id)
else:
module_rows[observed_id] = item
expected_manifest = module_rows.get(module_id)
manifest_mismatch = (
expected_manifest is None if module_id != "core" else False
) or (
expected_manifest is not None
and str(expected_manifest.get("manifest_version") or "") != expected_version
)
if manifest_mismatch:
payload_consistent = False
_record_change(
findings=findings,
changes=changes,
changed_repositories=changed_repositories,
affected_module_ids=affected_module_ids,
component=component,
kind="installed_manifest_mismatch",
code="installed_manifest_version_mismatch",
message=f"Installed distribution {package_name!r} does not expose module {module_id!r} at version {expected_version!r}.",
)
unexpected_modules = sorted(set(module_rows) - {module_id})
if duplicate_module_ids or unexpected_modules:
payload_consistent = False
_record_change(
findings=findings,
changes=changes,
changed_repositories=changed_repositories,
affected_module_ids=affected_module_ids,
component=component,
kind="installed_manifest_set_mismatch",
code="installed_manifest_set_mismatch",
message=f"Installed distribution {package_name!r} exposes an unexpected or duplicate module entry-point set.",
)
record = artifact.get("record_integrity")
record_status = record.get("status") if isinstance(record, dict) else None
record_semantics_valid = (
_record_integrity_semantics_valid(record)
if isinstance(record, dict)
else False
)
if isinstance(record, dict):
generated_count = record.get("generated_unhashed_file_count")
if isinstance(generated_count, int) and not isinstance(
generated_count, bool
):
generated_unhashed_file_count += max(generated_count, 0)
if record_status == "verified" and record_semantics_valid:
record_verified += 1
else:
payload_consistent = False
_record_change(
findings=findings,
changes=changes,
changed_repositories=changed_repositories,
affected_module_ids=affected_module_ids,
component=component,
kind="installed_record_unverified",
code=(
"installed_record_integrity_unverified"
if record_semantics_valid
else "installed_record_integrity_invalid"
),
message=(
f"Installed distribution {package_name!r} does not have complete, matching RECORD hash coverage."
if record_semantics_valid
else f"Installed distribution {package_name!r} has contradictory RECORD status and counters."
),
extra={"record_status": record_status},
)
provenance = artifact.get("source_provenance")
provenance_kind = (
str(provenance.get("kind") or "") if isinstance(provenance, dict) else ""
)
provenance_basis = (
str(provenance.get("basis") or "") if isinstance(provenance, dict) else ""
)
if provenance_basis != "local-pep610-metadata":
provenance_unanchored += 1
_record_change(
findings=findings,
changes=changes,
changed_repositories=changed_repositories,
affected_module_ids=affected_module_ids,
component=component,
kind="installed_source_metadata_invalid",
code="installed_source_metadata_basis_invalid",
message=f"Installed distribution {package_name!r} does not identify its source statement as local PEP 610 metadata.",
)
continue
if provenance_kind == "vcs-commit":
commit = str(provenance.get("commit") or "").lower()
selected_version = selected_versions.get(repository)
selected_commit = selected_commits.get(repository)
assessed_commit = str(component.get("commit") or "").lower()
commit_matches = commit.startswith(assessed_commit)
selected_matches = (
selected_version != expected_version
or selected_commit is None
or commit == selected_commit.lower()
)
if commit_matches and selected_matches:
provenance_declared_match += 1
else:
_record_change(
findings=findings,
changes=changes,
changed_repositories=changed_repositories,
affected_module_ids=affected_module_ids,
component=component,
kind="installed_commit_mismatch",
code="installed_source_commit_mismatch",
message=f"Installed distribution {package_name!r} declares a local PEP 610 VCS commit that does not match the assessed or signed selected-unit commit.",
)
elif provenance_kind in {"editable-vcs", "editable-local", "local-directory"}:
provenance_mutable += 1
_record_change(
findings=findings,
changes=changes,
changed_repositories=changed_repositories,
affected_module_ids=affected_module_ids,
component=component,
kind="installed_source_mutable",
code="installed_source_mutable",
message=f"Installed distribution {package_name!r} declares an editable or directory-backed local source.",
)
else:
provenance_unanchored += 1
_record_change(
findings=findings,
changes=changes,
changed_repositories=changed_repositories,
affected_module_ids=affected_module_ids,
component=component,
kind="installed_source_unanchored",
code="installed_source_unanchored",
message=f"Installed distribution {package_name!r} has no local PEP 610 source statement matching the assessed release.",
)
expected_packages = set(expected_by_package)
for package_name in sorted(set(artifacts_by_package) - expected_packages):
payload_consistent = False
matching_module_id = next(
(
module_id
for module_id, entry in catalog_entries.items()
if normalize_package_name(str(entry.get("package") or ""))
== package_name
),
None,
)
component = assessment_by_module.get(str(matching_module_id or ""))
repository = (
str(component.get("repository")) if isinstance(component, dict) else None
)
if repository:
changed_repositories.add(repository)
if matching_module_id and component is not None:
affected_module_ids.add(str(matching_module_id))
target_ids = (
(f"composition.{matching_module_id}",)
if matching_module_id and component is not None
else ("assessment.installed_composition",)
)
findings.append(
EvidenceFinding(
"review",
"installed_distribution_extra",
f"Installed GovOPlaN distribution {package_name!r} is outside the enabled assessed composition.",
target_ids,
)
)
changes.append(
{
"module_id": str(matching_module_id or package_name),
"repository": repository,
"kind": "installed_distribution_extra",
"package_name": package_name,
}
)
for issue in evidence.get("collection_issues", []):
if not isinstance(issue, dict):
continue
package_name = str(issue.get("package_name") or "")
code = str(issue.get("code") or "")
payload_consistent = False
findings.append(
EvidenceFinding(
"review",
"installed_collection_incomplete",
f"Installed evidence collection reported {code!r} for {package_name!r}.",
("assessment.installed_composition",),
)
)
exact_set = (
set(artifacts_by_package) == expected_packages and not duplicate_packages
)
origin_scope, origin_findings = _review_installed_release_origin(
expected_by_package=expected_by_package,
installed_artifacts=artifacts_by_package,
installed_evidence=evidence,
installed_evidence_sha256=digest,
installed_composition_valid=(
binding_valid
and exact_set
and payload_consistent
and record_verified == record_expected
and record_expected > 0
),
observation_trusted=observation_trusted,
catalog_artifacts=catalog_artifacts,
catalog_sha256=catalog_sha256,
catalog_channel=catalog_channel,
catalog_sequence=catalog_sequence,
catalog_trusted=catalog_trusted,
receipt=installer_receipt,
receipt_schema=installer_receipt_schema,
authority_keyring=installer_authority_keyring,
authority_keyring_schema=installer_authority_keyring_schema,
verification_time=now,
forbidden_public_keys=forbidden_installer_public_keys,
)
findings.extend(origin_findings)
receipt_authenticated = (
origin_scope.get("valid") is True
and origin_scope.get("signed_installer_receipt_count") == record_expected
and record_expected > 0
)
effective_observation_trusted = observation_trusted or receipt_authenticated
if (
effective_observation_mode == "imported_unsigned"
and not receipt_authenticated
):
findings.append(
EvidenceFinding(
"blocker",
"installed_evidence_unsigned_import",
"Imported installed evidence requires a valid independent installer receipt before it can establish installed proof.",
("assessment.installed_composition",),
)
)
installed_checked = effective_observation_trusted
record_checked = (
effective_observation_trusted
and binding_valid
and exact_set
and record_expected > 0
)
provenance_checked = (
effective_observation_trusted
and binding_valid
and exact_set
and provenance_expected > 0
)
proof_scope = {
"installed_artifacts": {
"checked": installed_checked,
"valid": payload_consistent if installed_checked else None,
"comparison_valid": payload_consistent,
"evidence_sha256": digest,
"expected_distribution_count": len(expected_packages),
"observed_distribution_count": len(artifact_rows),
},
"installed_record_integrity": {
"checked": record_checked,
"valid": record_verified == record_expected if record_checked else None,
"verified_distribution_count": record_verified,
"expected_distribution_count": record_expected,
"generated_unhashed_file_count": generated_unhashed_file_count,
},
"installed_source_provenance": {
"checked": provenance_checked,
"valid": provenance_declared_match == provenance_expected
if provenance_checked
else None,
"basis": "local-pep610-metadata",
"declared_match_distribution_count": provenance_declared_match,
"mutable_distribution_count": provenance_mutable,
"unanchored_distribution_count": provenance_unanchored,
"expected_distribution_count": provenance_expected,
"release_origin_bound": False,
},
"installed_release_origin": origin_scope,
"runtime_activation": {
"checked": False,
"valid": None,
"required_evidence": (
"A separately collected runtime registry/configuration snapshot bound to the installed evidence digest.",
),
},
"installed_evidence_observation": {
"checked": True,
"mode": effective_observation_mode,
"freshness": freshness,
"collected_at": _iso_datetime(collected_at),
"evaluated_at": _iso_datetime(now),
"verification_mode": effective_verification_mode,
"catalog_trusted": catalog_trusted is True,
"receipt_authenticated": receipt_authenticated,
"freshness_window_seconds": int(MAX_LOCAL_OBSERVATION_AGE.total_seconds()),
},
}
return InstalledEvidenceReview(
findings=tuple(findings),
changes=tuple(changes),
changed_repositories=frozenset(changed_repositories),
affected_module_ids=frozenset(affected_module_ids),
proof_scope=proof_scope,
evidence_sha256=digest,
)
def _review_installed_release_origin(
*,
expected_by_package: Mapping[str, tuple[dict[str, Any], Mapping[str, Any]]],
installed_artifacts: Mapping[str, dict[str, Any]],
installed_evidence: dict[str, Any],
installed_evidence_sha256: str,
installed_composition_valid: bool,
observation_trusted: bool,
catalog_artifacts: object,
catalog_sha256: str | None,
catalog_channel: str | None,
catalog_sequence: int | None,
catalog_trusted: bool,
receipt: dict[str, Any] | None,
receipt_schema: dict[str, Any] | None,
authority_keyring: dict[str, Any] | None,
authority_keyring_schema: dict[str, Any] | None,
verification_time: datetime,
forbidden_public_keys: frozenset[bytes],
) -> tuple[dict[str, Any], tuple[EvidenceFinding, ...]]:
findings: list[EvidenceFinding] = []
expected_count = len(expected_by_package)
scope: dict[str, Any] = {
"checked": False,
"valid": None,
"release_origin_bound": False,
"anchored_artifact_digest_count": 0,
"signed_installer_receipt_count": 0,
"expected_distribution_count": expected_count,
"catalog_sha256": catalog_sha256,
"installer_receipt_sha256": None,
"required_evidence": (
"A signed catalog identity computed from each built immutable artifact, or a role-scoped installer receipt signed by an independently provisioned authority.",
),
}
manifest_supplied = catalog_artifacts is not None
receipt_supplied = receipt is not None
if not manifest_supplied and not receipt_supplied:
return scope, ()
scope["checked"] = True
scope["valid"] = False
if not installed_composition_valid or catalog_trusted is not True:
findings.append(
EvidenceFinding(
"blocker",
"installed_origin_dependency_untrusted",
"Installed release-origin proof requires a trusted catalog and valid fresh installed-composition evidence.",
("assessment.release", "assessment.installed_composition"),
)
)
return scope, tuple(findings)
catalog_by_package, catalog_findings = _catalog_artifact_identities(
catalog_artifacts
)
findings.extend(catalog_findings)
if catalog_findings:
return scope, tuple(findings)
direct_bound: set[str] = set()
receipt_required: set[str] = set()
for package_name, (component, catalog_entry) in sorted(expected_by_package.items()):
expected_version = str(catalog_entry.get("version") or "")
identity = catalog_by_package.get(package_name)
if identity is None or identity.get("package_version") != expected_version:
findings.append(
EvidenceFinding(
"review",
"installed_origin_catalog_artifact_missing",
f"The signed catalog has no built-artifact identity for {package_name!r} at the selected version.",
(f"composition.{component['module_id']}",),
)
)
continue
if identity.get("requires_installer_receipt") is True:
receipt_required.add(package_name)
continue
if not observation_trusted:
continue
installed = installed_artifacts.get(package_name)
record = installed.get("record_integrity") if isinstance(installed, dict) else None
observed = (
record.get("artifact_payload_identity") if isinstance(record, dict) else None
)
expected = identity.get("installed_payload")
if observed == expected:
direct_bound.add(package_name)
else:
findings.append(
EvidenceFinding(
"blocker",
"installed_origin_artifact_payload_mismatch",
f"Installed payload for {package_name!r} does not match the identity independently computed from the signed catalog artifact.",
(f"composition.{component['module_id']}",),
)
)
receipt_bound: set[str] = set()
if receipt_supplied:
receipt_bound, receipt_findings, receipt_digest = _verify_installer_receipt(
expected_by_package=expected_by_package,
installed_artifacts=installed_artifacts,
installed_evidence=installed_evidence,
installed_evidence_sha256=installed_evidence_sha256,
catalog_by_package=catalog_by_package,
catalog_sha256=catalog_sha256,
catalog_channel=catalog_channel,
catalog_sequence=catalog_sequence,
receipt=receipt,
receipt_schema=receipt_schema,
authority_keyring=authority_keyring,
authority_keyring_schema=authority_keyring_schema,
verification_time=verification_time,
forbidden_public_keys=forbidden_public_keys,
)
findings.extend(receipt_findings)
scope["installer_receipt_sha256"] = receipt_digest
elif receipt_required:
findings.append(
EvidenceFinding(
"review",
"installed_origin_receipt_required",
"At least one selected wheel produces installer-transformed files, so its signed installer receipt is required for complete origin proof.",
("assessment.installed_composition",),
)
)
bound = direct_bound | receipt_bound
scope["anchored_artifact_digest_count"] = len(direct_bound)
scope["signed_installer_receipt_count"] = len(receipt_bound)
valid = len(bound) == expected_count and not any(
finding.severity == "blocker" for finding in findings
)
scope["valid"] = valid
scope["release_origin_bound"] = valid
return scope, tuple(findings)
def _catalog_artifact_identities(
value: object,
) -> tuple[dict[str, dict[str, Any]], tuple[EvidenceFinding, ...]]:
if value is None:
return {}, ()
if not isinstance(value, list) or len(value) > MAX_GOVOPLAN_DISTRIBUTIONS:
return {}, (
EvidenceFinding(
"blocker",
"catalog_artifact_manifest_invalid",
"Signed catalog release artifacts must be a bounded list.",
("assessment.release",),
),
)
result: dict[str, dict[str, Any]] = {}
invalid = False
for item in value:
if not isinstance(item, dict) or set(item) != {
"artifact_kind",
"package_name",
"package_version",
"archive_sha256",
"archive_size",
"installed_payload",
"requires_installer_receipt",
}:
invalid = True
continue
package_name = item.get("package_name")
version = item.get("package_version")
archive_size = item.get("archive_size")
payload = item.get("installed_payload")
if (
item.get("artifact_kind") != "python-wheel"
or not isinstance(package_name, str)
or PACKAGE_PATTERN.fullmatch(package_name) is None
or not isinstance(version, str)
or VERSION_PATTERN.fullmatch(version) is None
or not isinstance(item.get("archive_sha256"), str)
or SHA256_PATTERN.fullmatch(str(item["archive_sha256"])) is None
or not isinstance(archive_size, int)
or isinstance(archive_size, bool)
or not 0 < archive_size <= MAX_HASHED_DISTRIBUTION_BYTES
or not isinstance(item.get("requires_installer_receipt"), bool)
or not _payload_identity_semantics_valid(
payload,
algorithm=WHEEL_PAYLOAD_ALGORITHM,
maximum_files=MAX_DISTRIBUTION_FILES,
)
or package_name in result
):
invalid = True
continue
result[package_name] = item
if invalid:
return {}, (
EvidenceFinding(
"blocker",
"catalog_artifact_manifest_invalid",
"Signed catalog release artifacts contain malformed or duplicate package identities.",
("assessment.release",),
),
)
return result, ()
def _verify_installer_receipt(
*,
expected_by_package: Mapping[str, tuple[dict[str, Any], Mapping[str, Any]]],
installed_artifacts: Mapping[str, dict[str, Any]],
installed_evidence: dict[str, Any],
installed_evidence_sha256: str,
catalog_by_package: Mapping[str, dict[str, Any]],
catalog_sha256: str | None,
catalog_channel: str | None,
catalog_sequence: int | None,
receipt: dict[str, Any],
receipt_schema: dict[str, Any] | None,
authority_keyring: dict[str, Any] | None,
authority_keyring_schema: dict[str, Any] | None,
verification_time: datetime,
forbidden_public_keys: frozenset[bytes],
) -> tuple[set[str], tuple[EvidenceFinding, ...], str]:
receipt_digest = canonical_sha256(receipt)
findings: list[EvidenceFinding] = []
if receipt_schema is None or authority_keyring_schema is None:
findings.append(
EvidenceFinding(
"blocker",
"installer_receipt_schema_missing",
"Installer receipt proof requires both bounded validation schemas.",
("assessment.installed_composition",),
)
)
return set(), tuple(findings), receipt_digest
receipt_errors = validate_payload(payload=receipt, schema=receipt_schema)
keyring_errors = (
validate_payload(payload=authority_keyring, schema=authority_keyring_schema)
if isinstance(authority_keyring, dict)
else ("$: an independently provisioned installer authority keyring is required",)
)
findings.extend(
EvidenceFinding(
"blocker",
"installer_receipt_schema",
message,
("assessment.installed_composition",),
)
for message in receipt_errors
)
findings.extend(
EvidenceFinding(
"blocker",
"installer_authority_keyring_schema",
message,
("assessment.installed_composition",),
)
for message in keyring_errors
)
if receipt_errors or keyring_errors or not isinstance(authority_keyring, dict):
return set(), tuple(findings), receipt_digest
expected_release = installed_evidence.get("assessment_release")
expected_assessment = installed_evidence.get("assessment_id")
catalog_binding = receipt.get("catalog")
binding_valid = True
if (
receipt.get("assessment_id") != expected_assessment
or receipt.get("assessment_release") != expected_release
or receipt.get("installed_evidence_sha256") != installed_evidence_sha256
):
binding_valid = False
findings.append(
EvidenceFinding(
"blocker",
"installer_receipt_evidence_mismatch",
"Installer receipt is not bound to the supplied assessment and installed-evidence digest.",
("assessment.installed_composition",),
)
)
if not isinstance(catalog_binding, dict) or (
catalog_binding.get("sha256") != catalog_sha256
or catalog_binding.get("channel") != catalog_channel
or catalog_binding.get("sequence") != catalog_sequence
):
binding_valid = False
findings.append(
EvidenceFinding(
"blocker",
"installer_receipt_catalog_mismatch",
"Installer receipt is not bound to the supplied signed catalog identity.",
("assessment.release", "assessment.installed_composition"),
)
)
issued_at = _datetime(receipt.get("issued_at"))
collected_at = _datetime(installed_evidence.get("collected_at"))
if (
issued_at is None
or collected_at is None
or issued_at < collected_at
or issued_at - collected_at > MAX_LOCAL_OBSERVATION_AGE
or issued_at > verification_time + MAX_LOCAL_OBSERVATION_FUTURE_SKEW
or verification_time - issued_at > MAX_LOCAL_OBSERVATION_AGE
):
binding_valid = False
findings.append(
EvidenceFinding(
"blocker",
"installer_receipt_time_invalid",
"Installer receipt issuance must follow the observation within five minutes and remain fresh at the selected verification time.",
("assessment.installed_composition",),
)
)
receipt_rows = [
item for item in receipt.get("artifacts", []) if isinstance(item, dict)
]
rows_by_package: dict[str, dict[str, Any]] = {}
duplicate_packages: set[str] = set()
for row in receipt_rows:
package_name = str(row.get("package_name") or "")
if package_name in rows_by_package:
duplicate_packages.add(package_name)
else:
rows_by_package[package_name] = row
expected_packages = set(expected_by_package)
if duplicate_packages or set(rows_by_package) != expected_packages:
binding_valid = False
findings.append(
EvidenceFinding(
"blocker",
"installer_receipt_artifact_set_mismatch",
"Installer receipt must bind exactly one row for every expected installed distribution.",
("assessment.installed_composition",),
)
)
bound: set[str] = set()
for package_name, (_, catalog_entry) in sorted(expected_by_package.items()):
row = rows_by_package.get(package_name)
installed = installed_artifacts.get(package_name)
record = installed.get("record_integrity") if isinstance(installed, dict) else None
observed_payload = (
record.get("installed_payload_identity") if isinstance(record, dict) else None
)
catalog_identity = catalog_by_package.get(package_name)
if (
row is None
or catalog_identity is None
or row.get("package_version") != catalog_entry.get("version")
or row.get("catalog_archive_sha256")
!= catalog_identity.get("archive_sha256")
or row.get("installed_payload") != observed_payload
):
binding_valid = False
findings.append(
EvidenceFinding(
"blocker",
"installer_receipt_artifact_mismatch",
f"Installer receipt does not bind the observed {package_name!r} payload to its signed catalog artifact.",
("assessment.installed_composition",),
)
)
else:
bound.add(package_name)
keys, key_findings = _installer_receipt_keys(
authority_keyring=authority_keyring,
issued_at=issued_at,
forbidden_public_keys=forbidden_public_keys,
)
findings.extend(key_findings)
signature_payload = dict(receipt)
signature_payload.pop("signatures", None)
signature_bytes = canonical_bytes(signature_payload)
signature_valid = False
seen_ids: set[str] = set()
duplicate_ids = False
for signature in receipt.get("signatures", []):
if not isinstance(signature, dict):
continue
key_id = str(signature.get("key_id") or "")
if key_id in seen_ids:
duplicate_ids = True
continue
seen_ids.add(key_id)
public_key = keys.get(key_id)
if public_key is None or signature.get("algorithm") != "ed25519":
continue
try:
encoded = base64.b64decode(str(signature.get("value") or ""), validate=True)
Ed25519PublicKey.from_public_bytes(public_key).verify(
encoded, signature_bytes
)
signature_valid = True
except (ValueError, InvalidSignature):
continue
if duplicate_ids or not signature_valid:
findings.append(
EvidenceFinding(
"blocker",
"installer_receipt_signature_untrusted",
"Installer receipt has no unique valid signature from an authorized independent installer key.",
("assessment.installed_composition",),
)
)
if not binding_valid or not signature_valid or key_findings:
return set(), tuple(findings), receipt_digest
return bound, tuple(findings), receipt_digest
def _installer_receipt_keys(
*,
authority_keyring: dict[str, Any],
issued_at: datetime | None,
forbidden_public_keys: frozenset[bytes],
) -> tuple[dict[str, bytes], tuple[EvidenceFinding, ...]]:
findings: list[EvidenceFinding] = []
result: dict[str, bytes] = {}
raw_keys = authority_keyring.get("keys")
if not isinstance(raw_keys, list) or issued_at is None:
return {}, (
EvidenceFinding(
"blocker",
"installer_authority_untrusted",
"Installer receipt authority keyring or issuance time is invalid.",
("assessment.installed_composition",),
),
)
seen_ids: set[str] = set()
seen_material: set[bytes] = set()
malformed = False
for item in raw_keys:
if not isinstance(item, dict):
malformed = True
continue
key_id = str(item.get("key_id") or "")
try:
public_key = base64.b64decode(str(item.get("public_key") or ""), validate=True)
Ed25519PublicKey.from_public_bytes(public_key)
except ValueError:
malformed = True
continue
not_before = _datetime(item.get("not_before"))
not_after = _datetime(item.get("not_after"))
interval_valid = not (
not_before is not None
and not_after is not None
and not_before >= not_after
)
if (
OPAQUE_ID_PATTERN.fullmatch(key_id) is None
or key_id in seen_ids
or public_key in seen_material
or public_key in forbidden_public_keys
or item.get("allowed_scopes") != ["installed_release_origin"]
or not interval_valid
):
malformed = True
continue
seen_ids.add(key_id)
seen_material.add(public_key)
status = item.get("status")
active_at_issue = (
(not_before is None or issued_at >= not_before)
and (not_after is None or issued_at < not_after)
)
historically_retired = status == "retired" and not_after is not None
if active_at_issue and (
status in {"active", "next"} or historically_retired
):
result[key_id] = public_key
if malformed or not result:
findings.append(
EvidenceFinding(
"blocker",
"installer_authority_untrusted",
"Installer authority keyring is malformed, reuses another trust-domain key, or has no role-scoped key valid at receipt issuance.",
("assessment.installed_composition",),
)
)
return {}, tuple(findings)
return result, ()
def review_boundary_evidence(
*,
assessment: dict[str, Any],
installed_review: InstalledEvidenceReview,
evidence: dict[str, Any] | None,
evidence_schema: dict[str, Any] | None,
authority_keyring: dict[str, Any] | None,
authority_keyring_schema: dict[str, Any] | None,
verification_time: datetime | None = None,
verification_mode: str = "current",
expected_external_provider_subject: str | None = None,
forbidden_authority_public_keys: frozenset[bytes] = frozenset(),
) -> BoundaryEvidenceReview:
deployment_profile = assessment.get("deployment_profile")
raw_deployment_subject = (
deployment_profile.get("id") if isinstance(deployment_profile, dict) else None
)
deployment_subject = _safe_opaque_id_or_none(raw_deployment_subject)
provider_subject = _safe_opaque_id_or_none(expected_external_provider_subject)
effective_verification_mode = (
verification_mode if verification_mode in VERIFICATION_MODES else "invalid"
)
expected_subjects = {
"target_environment": deployment_subject,
"external_providers": provider_subject,
"production_approval": deployment_subject,
}
scopes = _unchecked_boundary_scope(expected_subjects=expected_subjects)
findings: list[EvidenceFinding] = []
if raw_deployment_subject is not None and deployment_subject is None:
findings.append(
EvidenceFinding(
"blocker",
"boundary_deployment_subject_invalid",
"The assessment deployment profile has no valid opaque subject ID.",
("assessment.deployment_profile",),
)
)
if expected_external_provider_subject is not None and provider_subject is None:
findings.append(
EvidenceFinding(
"blocker",
"boundary_provider_subject_invalid",
"The expected external-provider subject must be a bounded opaque ID.",
("assessment.external_proof",),
)
)
if effective_verification_mode == "invalid":
findings.append(
EvidenceFinding(
"blocker",
"boundary_verification_mode_invalid",
"Boundary evidence verification mode is invalid.",
("assessment.external_proof",),
)
)
if evidence is None:
return BoundaryEvidenceReview(findings=tuple(findings), proof_scope=scopes)
now = verification_time or datetime.now(tz=UTC)
if now.tzinfo is None:
now = now.replace(tzinfo=UTC)
scopes["boundary_evidence_verification"] = {
"checked": True,
"evaluated_at": _iso_datetime(now),
"verification_mode": effective_verification_mode,
"historical": effective_verification_mode == "historical_override",
}
if evidence_schema is None or authority_keyring_schema is None:
findings.append(
EvidenceFinding(
"blocker",
"boundary_evidence_schema_missing",
"Boundary evidence was supplied without both validation schemas.",
("assessment.external_proof",),
)
)
return BoundaryEvidenceReview(tuple(findings), scopes)
evidence_errors = validate_payload(payload=evidence, schema=evidence_schema)
keyring_errors = (
validate_payload(payload=authority_keyring, schema=authority_keyring_schema)
if isinstance(authority_keyring, dict)
else ("$: an independently provisioned proof-authority keyring is required",)
)
findings.extend(
EvidenceFinding(
"blocker",
"boundary_evidence_schema",
message,
("assessment.external_proof",),
)
for message in evidence_errors
)
findings.extend(
EvidenceFinding(
"blocker",
"boundary_authority_keyring_schema",
message,
("assessment.external_proof",),
)
for message in keyring_errors
)
if evidence_errors or keyring_errors or not isinstance(authority_keyring, dict):
return BoundaryEvidenceReview(tuple(findings), scopes)
expected_release = (
assessment.get("release", {}).get("ref")
if isinstance(assessment.get("release"), dict)
else None
)
if evidence.get("assessment_id") != assessment.get("assessment_id"):
findings.append(
EvidenceFinding(
"blocker",
"boundary_assessment_mismatch",
"Boundary evidence is bound to a different assessment ID.",
("assessment.external_proof",),
)
)
if evidence.get("assessment_release") != expected_release:
findings.append(
EvidenceFinding(
"blocker",
"boundary_release_mismatch",
"Boundary evidence is bound to a different assessment release.",
("assessment.release", "assessment.external_proof"),
)
)
installed_digest = installed_review.evidence_sha256
installed_scope = installed_review.proof_scope.get("installed_artifacts", {})
installed_origin_scope = installed_review.proof_scope.get(
"installed_release_origin", {}
)
if (
installed_digest is None
or evidence.get("installed_evidence_sha256") != installed_digest
or installed_scope.get("valid") is not True
):
findings.append(
EvidenceFinding(
"blocker",
"boundary_installed_evidence_untrusted",
"Boundary evidence must bind to the supplied, valid installed-composition evidence digest.",
("assessment.installed_composition", "assessment.external_proof"),
)
)
if installed_origin_scope.get("valid") is not True:
findings.append(
EvidenceFinding(
"blocker",
"boundary_installed_release_origin_untrusted",
"Boundary evidence requires an independently anchored digest or signed installer receipt for every installed release artifact; local PEP 610 and RECORD metadata are insufficient.",
("assessment.installed_composition", "assessment.external_proof"),
)
)
issued_at = _datetime(evidence.get("issued_at"))
expires_at = _datetime(evidence.get("expires_at"))
time_valid = True
if issued_at is None or expires_at is None or issued_at >= expires_at:
time_valid = False
findings.append(
EvidenceFinding(
"blocker",
"boundary_evidence_interval_invalid",
"Boundary evidence must have issued_at earlier than expires_at.",
("assessment.external_proof",),
)
)
elif now < issued_at or now >= expires_at:
time_valid = False
findings.append(
EvidenceFinding(
"blocker",
"boundary_evidence_not_current",
"Boundary evidence is not valid at the verification time.",
("assessment.external_proof",),
)
)
claims = [item for item in evidence.get("claims", []) if isinstance(item, dict)]
claims_by_scope: dict[str, dict[str, Any]] = {}
duplicate_scopes: set[str] = set()
semantic_invalid: set[str] = set()
subject_invalid: set[str] = set()
for claim in claims:
scope = str(claim.get("scope") or "")
if scope in claims_by_scope:
duplicate_scopes.add(scope)
else:
claims_by_scope[scope] = claim
allowed_results = {POSITIVE_RESULTS.get(scope), NEGATIVE_RESULTS.get(scope)}
if claim.get("result") not in allowed_results:
semantic_invalid.add(scope)
controls = claim.get("control_ids")
if not isinstance(controls, list) or len(controls) != len(set(controls)):
semantic_invalid.add(scope)
artifacts = claim.get("artifacts")
artifact_ids = [
str(item.get("artifact_id") or "")
for item in artifacts or []
if isinstance(item, dict)
]
if len(artifact_ids) != len(set(artifact_ids)):
semantic_invalid.add(scope)
observed_subject = str(claim.get("subject_id") or "")
expected_subject = expected_subjects.get(scope)
if scope in scopes:
scopes[scope]["observed_subject_id"] = observed_subject
if expected_subject is None or observed_subject != expected_subject:
subject_invalid.add(scope)
for scope in sorted(duplicate_scopes):
findings.append(
EvidenceFinding(
"blocker",
"boundary_claim_duplicate",
f"Boundary evidence repeats claim scope {scope!r}.",
("assessment.external_proof",),
)
)
for scope in sorted(semantic_invalid):
findings.append(
EvidenceFinding(
"blocker",
"boundary_claim_semantics",
f"Boundary claim {scope!r} has an invalid result or duplicate control/artifact IDs.",
("assessment.external_proof",),
)
)
for scope in sorted(subject_invalid):
expected_subject = expected_subjects.get(scope)
findings.append(
EvidenceFinding(
"blocker",
(
"boundary_provider_subject_unconfigured"
if scope == "external_providers" and expected_subject is None
else "boundary_claim_subject_mismatch"
),
(
"External-provider proof requires an explicit expected opaque subject ID."
if scope == "external_providers" and expected_subject is None
else f"Boundary claim {scope!r} is not bound to its expected assessment subject."
),
("assessment.external_proof",),
)
)
authority_keys, key_findings = _active_authority_keys(
authority_keyring=authority_keyring,
verification_time=now,
forbidden_public_keys=forbidden_authority_public_keys,
)
findings.extend(key_findings)
signature_payload = dict(evidence)
signature_payload.pop("signatures", None)
signature_bytes = canonical_bytes(signature_payload)
authorized_scopes: set[str] = set()
seen_signature_key_ids: set[str] = set()
duplicate_signature_key_ids: set[str] = set()
for signature in evidence.get("signatures", []):
if not isinstance(signature, dict):
continue
key_id = str(signature.get("key_id") or "")
if key_id in seen_signature_key_ids:
duplicate_signature_key_ids.add(key_id)
continue
seen_signature_key_ids.add(key_id)
key = authority_keys.get(key_id)
if key is None or signature.get("algorithm") != "ed25519":
continue
try:
signature_value = base64.b64decode(
str(signature.get("value") or ""), validate=True
)
Ed25519PublicKey.from_public_bytes(key[0]).verify(
signature_value, signature_bytes
)
except (ValueError, InvalidSignature):
continue
authorized_scopes.update(key[1])
if duplicate_signature_key_ids:
findings.append(
EvidenceFinding(
"blocker",
"boundary_signature_duplicate",
"Boundary evidence repeats one or more signature key IDs.",
("assessment.external_proof",),
)
)
unauthorized_scopes = {
scope
for scope in claims_by_scope
if scope in PROOF_REQUIREMENTS and scope not in authorized_scopes
}
for scope in sorted(unauthorized_scopes):
findings.append(
EvidenceFinding(
"blocker",
"boundary_authority_untrusted",
f"No valid independently trusted signature is authorized for {scope!r}.",
("assessment.external_proof",),
)
)
global_valid = not any(item.severity == "blocker" for item in findings)
evidence_digest = canonical_sha256(evidence)
review_targets: list[dict[str, Any]] = []
for scope, claim in sorted(claims_by_scope.items()):
if scope not in PROOF_REQUIREMENTS:
continue
if scope in unauthorized_scopes:
continue
if (
scope in duplicate_scopes
or scope in semantic_invalid
or scope in subject_invalid
or not time_valid
):
continue
if not global_valid:
continue
result = str(claim.get("result"))
valid = result == POSITIVE_RESULTS[scope]
scopes[scope] = {
"checked": True,
"valid": valid,
"evidence_sha256": evidence_digest,
"result": result,
"control_count": len(claim.get("control_ids") or []),
"artifact_count": len(claim.get("artifacts") or []),
"expected_subject_id": expected_subjects[scope],
"observed_subject_id": claim.get("subject_id"),
"evaluated_at": _iso_datetime(now),
"verification_mode": effective_verification_mode,
"required_evidence": PROOF_REQUIREMENTS[scope],
}
if not valid:
findings.append(
EvidenceFinding(
"review",
"boundary_claim_negative",
f"Authorized boundary claim {scope!r} has result {result!r}.",
("assessment.external_proof",),
)
)
subject = str(expected_subjects[scope])
review_targets.append(
{
"id": f"boundary.{scope}.{subject}",
"section": scope,
"reason": f"Authorized boundary evidence reported {result!r} for {scope!r}.",
}
)
return BoundaryEvidenceReview(
tuple(findings),
scopes,
tuple(
{
item["id"]: item
for item in sorted(review_targets, key=lambda value: value["id"])
}.values()
),
)
def normalize_package_name(value: str) -> str:
return re.sub(r"[-_.]+", "-", value.strip().lower())
def canonical_bytes(payload: object) -> bytes:
return json.dumps(
payload, sort_keys=True, separators=(",", ":"), ensure_ascii=True
).encode("utf-8")
def canonical_sha256(payload: object) -> str:
return hashlib.sha256(canonical_bytes(payload)).hexdigest()
def public_key_material_from_keyrings(
*payloads: Mapping[str, Any],
) -> frozenset[bytes]:
result: set[bytes] = set()
for payload in payloads:
keys = payload.get("keys")
values = (
[item.get("public_key") for item in keys if isinstance(item, dict)]
if isinstance(keys, list)
else list(payload.values())
)
for value in values:
if not isinstance(value, str):
continue
try:
decoded = base64.b64decode(value, validate=True)
Ed25519PublicKey.from_public_bytes(decoded)
except ValueError:
continue
result.add(decoded)
return frozenset(result)
def _distribution_version(distribution: metadata.Distribution) -> str:
try:
value = str(distribution.version)
except Exception:
return ""
if len(value) > 128 or VERSION_PATTERN.fullmatch(value) is None:
return ""
return value
def _distribution_modules(
*, package_name: str, distribution: metadata.Distribution
) -> tuple[list[dict[str, str]], list[dict[str, str]]]:
modules: list[dict[str, str]] = []
issues: list[dict[str, str]] = []
try:
all_entry_points = []
for entry_point in distribution.entry_points:
if entry_point.group != "govoplan.modules":
continue
name = str(entry_point.name)
value = str(entry_point.value)
if (
len(name) > 160
or OPAQUE_ID_PATTERN.fullmatch(name) is None
or len(value) > 512
or ENTRY_POINT_VALUE_PATTERN.fullmatch(value) is None
):
issues.append(
{
"code": "module-entry-point-invalid",
"package_name": package_name,
}
)
continue
all_entry_points.append((name, value, entry_point))
all_entry_points.sort(key=lambda item: (item[0], item[1]))
except Exception:
return [], [
{
"code": "distribution-metadata-invalid",
"package_name": package_name,
}
]
if len(all_entry_points) > 16:
issues.append(
{
"code": "module-entry-point-limit-exceeded",
"package_name": package_name,
}
)
for _, _, entry_point in all_entry_points[:16]:
try:
manifest = entry_point.load()()
module_id = str(manifest.id)
manifest_version = str(manifest.version)
except (Exception, SystemExit):
issues.append(
{
"code": "module-entry-point-load-failed",
"package_name": package_name,
}
)
continue
if (
len(module_id) > 160
or OPAQUE_ID_PATTERN.fullmatch(module_id) is None
or len(manifest_version) > 128
or VERSION_PATTERN.fullmatch(manifest_version) is None
):
issues.append(
{
"code": "module-entry-point-invalid",
"package_name": package_name,
}
)
continue
modules.append({"module_id": module_id, "manifest_version": manifest_version})
return sorted(modules, key=lambda item: item["module_id"]), issues
def _source_provenance(distribution: metadata.Distribution) -> dict[str, str]:
try:
raw = distribution.read_text("direct_url.json")
except Exception:
return _local_source_metadata("malformed-direct-url")
if raw is None:
return _local_source_metadata("index-or-unknown")
if not isinstance(raw, str) or len(raw) > MAX_DIRECT_URL_BYTES:
return _local_source_metadata("malformed-direct-url")
if len(raw.encode("utf-8")) > MAX_DIRECT_URL_BYTES:
return _local_source_metadata("malformed-direct-url")
try:
direct_url = json.loads(raw)
except (TypeError, json.JSONDecodeError):
return _local_source_metadata("malformed-direct-url")
if not isinstance(direct_url, dict):
return _local_source_metadata("malformed-direct-url")
raw_url = direct_url.get("url")
if (
not isinstance(raw_url, str)
or not raw_url
or len(raw_url) > 2048
or any(character.isspace() or ord(character) < 32 for character in raw_url)
):
return _local_source_metadata("malformed-direct-url")
try:
parsed_url = urlsplit(raw_url)
except ValueError:
return _local_source_metadata("malformed-direct-url")
if parsed_url.password is not None or parsed_url.query or parsed_url.fragment:
return _local_source_metadata("malformed-direct-url")
vcs_info = direct_url.get("vcs_info")
directory_info = direct_url.get("dir_info")
archive_info = direct_url.get("archive_info")
provenance_forms = tuple(
name
for name, value in (
("vcs", vcs_info),
("directory", directory_info),
("archive", archive_info),
)
if value is not None
)
if len(provenance_forms) != 1:
return _local_source_metadata("malformed-direct-url")
if isinstance(vcs_info, dict):
if vcs_info.get("vcs") != "git":
return _local_source_metadata("malformed-direct-url")
commit = str(vcs_info.get("commit_id") or "").lower()
requested_revision = vcs_info.get("requested_revision")
if (
GIT_OBJECT_PATTERN.fullmatch(commit) is None
or parsed_url.scheme
not in {"file", "git", "git+https", "git+ssh", "https", "ssh"}
or not parsed_url.path
or (
parsed_url.scheme != "file"
and (not parsed_url.hostname or not parsed_url.path.endswith(".git"))
)
or (parsed_url.scheme in {"https", "git+https"} and parsed_url.username)
or (
requested_revision is not None
and (
not isinstance(requested_revision, str)
or VCS_REVISION_PATTERN.fullmatch(requested_revision) is None
)
)
):
return _local_source_metadata("malformed-direct-url")
return _local_source_metadata("vcs-commit", commit=commit)
if isinstance(archive_info, dict):
if (
parsed_url.scheme not in {"file", "https"}
or not parsed_url.path
or (
parsed_url.scheme == "https"
and (not parsed_url.hostname or parsed_url.username)
)
):
return _local_source_metadata("malformed-direct-url")
hashes = archive_info.get("hashes")
digest = hashes.get("sha256") if isinstance(hashes, dict) else None
if digest is None:
legacy = str(archive_info.get("hash") or "")
if legacy.startswith("sha256="):
digest = legacy.removeprefix("sha256=")
digest_text = str(digest or "").lower()
if SHA256_PATTERN.fullmatch(digest_text):
return _local_source_metadata("archive", sha256=digest_text)
return _local_source_metadata("malformed-direct-url")
if isinstance(directory_info, dict):
editable = directory_info.get("editable", False)
if (
parsed_url.scheme != "file"
or not parsed_url.path
or not isinstance(editable, bool)
):
return _local_source_metadata("malformed-direct-url")
return _local_source_metadata(
"editable-local" if editable else "local-directory"
)
return _local_source_metadata("malformed-direct-url")
def _local_source_metadata(kind: str, **values: str) -> dict[str, str]:
return {"basis": "local-pep610-metadata", "kind": kind, **values}
def _read_record_entries(
*,
distribution: metadata.Distribution,
distribution_root: Path,
max_entries: int,
) -> tuple[tuple[RecordEntry, ...], int, str]:
"""Read RECORD itself without importlib's missing-path filtering.
``Distribution.files`` is an interpreted convenience API rather than the
raw declaration being attested. Reading the metadata file directly lets
this collector retain missing and malformed declarations and enforce byte
and row limits before resolving any untrusted payload path.
"""
metadata_root_value = getattr(distribution, "_path", None)
if metadata_root_value is None:
return (), 0, "unavailable"
try:
metadata_root = Path(os.fspath(metadata_root_value))
if metadata_root.is_symlink():
return (), 0, "unavailable"
resolved_metadata_root = metadata_root.resolve()
except (OSError, TypeError, ValueError):
return (), 0, "unavailable"
if not _is_relative_to(resolved_metadata_root, distribution_root):
return (), 0, "unavailable"
record_path = resolved_metadata_root / "RECORD"
try:
if record_path.is_symlink():
return (), 0, "unavailable"
encoded, exceeded, stable = _bounded_regular_file_bytes(
record_path,
max_bytes=MAX_RECORD_BYTES,
)
except OSError:
return (), 0, "unavailable"
if exceeded:
return (), 0, "limit-exceeded"
if not stable:
return (), 1, "unavailable"
try:
text = encoded.decode("utf-8")
except UnicodeDecodeError:
return (), 1, "unavailable"
entries: list[RecordEntry] = []
malformed_rows = 0
declared_paths: set[str] = set()
try:
rows = csv.reader(io.StringIO(text, newline=""))
for row in rows:
if len(entries) + malformed_rows >= max_entries:
return (), 0, "limit-exceeded"
if len(row) != 3:
malformed_rows += 1
continue
raw_path, raw_hash, raw_size = row
if (
not raw_path
or len(raw_path) > MAX_RECORD_PATH_CHARACTERS
or any(ord(character) < 32 for character in raw_path)
or (raw_size and (len(raw_size) > 20 or not raw_size.isdecimal()))
):
malformed_rows += 1
continue
declared_path = str(PurePosixPath(raw_path.replace("\\", "/")))
if declared_path in declared_paths:
malformed_rows += 1
continue
declared_paths.add(declared_path)
if raw_hash:
hash_mode, separator, hash_value = raw_hash.partition("=")
if not separator or not hash_mode or not hash_value:
hash_mode = raw_hash
hash_value = ""
else:
hash_mode = None
hash_value = None
entries.append(
RecordEntry(
path=raw_path,
hash_mode=hash_mode,
hash_value=hash_value,
size=int(raw_size) if raw_size else None,
)
)
except (csv.Error, ValueError):
return (), 1, "unavailable"
return tuple(entries), malformed_rows, "ok"
def _bounded_regular_file_bytes(
path: Path,
*,
max_bytes: int,
) -> tuple[bytes, bool, bool]:
flags = os.O_RDONLY | getattr(os, "O_NOFOLLOW", 0) | getattr(os, "O_NONBLOCK", 0)
descriptor = os.open(path, flags)
chunks: list[bytes] = []
total = 0
try:
initial = os.fstat(descriptor)
if not stat.S_ISREG(initial.st_mode):
raise OSError("RECORD metadata is not a regular file")
if initial.st_size > max_bytes:
return b"", True, True
while total <= max_bytes:
chunk = os.read(descriptor, min(1024 * 1024, max_bytes + 1 - total))
if not chunk:
break
chunks.append(chunk)
total += len(chunk)
final = os.fstat(descriptor)
finally:
os.close(descriptor)
exceeded = total > max_bytes or final.st_size > max_bytes
stable = (
not exceeded
and total == initial.st_size
and final.st_size == initial.st_size
and (final.st_dev, final.st_ino) == (initial.st_dev, initial.st_ino)
and final.st_mtime_ns == initial.st_mtime_ns
and final.st_ctime_ns == initial.st_ctime_ns
)
return b"".join(chunks), exceeded, stable
def _record_integrity(
distribution: metadata.Distribution,
*,
package_name: str,
budget: CollectionHashBudget,
) -> dict[str, Any]:
counts = {
"hashed_file_count": 0,
"permitted_unhashed_file_count": 0,
"generated_unhashed_file_count": 0,
"unverifiable_file_count": 0,
"missing_file_count": 0,
"mismatched_file_count": 0,
}
identities = {
"artifact_payload_identity": None,
"installed_payload_identity": None,
}
try:
distribution_root = Path(distribution.locate_file("")).resolve()
installation_root = Path(sys.prefix).resolve()
except Exception:
return {"status": "unavailable", **counts, **identities}
if not _trusted_distribution_root(distribution_root):
return {"status": "unavailable", **counts, **identities}
entries, malformed_rows, record_status = _read_record_entries(
distribution=distribution,
distribution_root=distribution_root,
max_entries=min(MAX_DISTRIBUTION_FILES, budget.remaining_files),
)
if record_status == "limit-exceeded":
budget.remaining_files = 0
return {"status": "limit-exceeded", **counts, **identities}
if record_status != "ok":
counts["unverifiable_file_count"] = malformed_rows
return {"status": "unavailable", **counts, **identities}
record_file_count = len(entries) + malformed_rows
if record_file_count == 0:
return {"status": "unavailable", **counts, **identities}
budget.remaining_files -= record_file_count
counts["unverifiable_file_count"] = malformed_rows
declared_scripts = _declared_distribution_scripts(distribution)
owner_prefix = package_name.replace("-", "_")
resolved_entries: list[tuple[RecordEntry, Path | None]] = [
(
entry,
_resolve_record_path(
distribution=distribution,
package_path=entry.path,
distribution_root=distribution_root,
installation_root=installation_root,
owner_prefix=owner_prefix,
declared_scripts=declared_scripts,
),
)
for entry in entries
]
resolved_path_counts: dict[Path, int] = {}
for _, resolved_path in resolved_entries:
if resolved_path is not None:
resolved_path_counts[resolved_path] = (
resolved_path_counts.get(resolved_path, 0) + 1
)
duplicate_resolved_paths = {
path for path, count in resolved_path_counts.items() if count > 1
}
counts["unverifiable_file_count"] += sum(
resolved_path_counts[path] for path in duplicate_resolved_paths
)
hashed_payload_paths = {
resolved_path
for entry, resolved_path in resolved_entries
if resolved_path is not None
and resolved_path not in duplicate_resolved_paths
and entry.hash_mode == "sha256"
}
total_hashed_bytes = 0
limit_exceeded = False
artifact_payload_rows: list[dict[str, object]] = []
installed_payload_rows: list[dict[str, object]] = []
for entry, resolved_path in resolved_entries:
if resolved_path is None:
counts["unverifiable_file_count"] += 1
continue
if resolved_path in duplicate_resolved_paths:
continue
try:
file_stat = resolved_path.lstat()
except OSError:
counts["missing_file_count"] += 1
continue
if not stat.S_ISREG(file_stat.st_mode):
counts["missing_file_count"] += 1
continue
if entry.size is not None and file_stat.st_size != entry.size:
counts["mismatched_file_count"] += 1
continue
if entry.hash_mode is None:
if _permitted_unhashed_record_path(
resolved_path,
distribution_root=distribution_root,
owner_prefix=owner_prefix,
):
counts["permitted_unhashed_file_count"] += 1
elif _generated_unhashed_pyc(
resolved_path,
hashed_payload_paths=hashed_payload_paths,
):
counts["generated_unhashed_file_count"] += 1
else:
counts["unverifiable_file_count"] += 1
continue
if entry.hash_mode != "sha256":
counts["unverifiable_file_count"] += 1
continue
remaining_distribution_bytes = (
MAX_HASHED_DISTRIBUTION_BYTES - total_hashed_bytes
)
allowed_bytes = min(
MAX_HASHED_FILE_BYTES,
remaining_distribution_bytes,
budget.remaining_bytes,
)
if allowed_bytes <= 0 or file_stat.st_size > allowed_bytes:
limit_exceeded = True
continue
expected = _record_hash_bytes(entry.hash_value or "")
if expected is None:
counts["unverifiable_file_count"] += 1
continue
try:
actual, hashed_bytes, exceeded = _bounded_file_sha256(
resolved_path,
max_bytes=allowed_bytes,
)
except OSError:
counts["missing_file_count"] += 1
continue
total_hashed_bytes += hashed_bytes
budget.remaining_bytes -= hashed_bytes
if exceeded:
limit_exceeded = True
continue
if hmac.compare_digest(actual, expected):
counts["hashed_file_count"] += 1
installed_path = _installed_payload_path(
resolved_path,
distribution_root=distribution_root,
installation_root=installation_root,
declared_scripts=declared_scripts,
)
if installed_path is None:
counts["unverifiable_file_count"] += 1
continue
row = {
"path": installed_path,
"sha256": actual.hex(),
"size": file_stat.st_size,
}
installed_payload_rows.append(row)
artifact_path = _artifact_payload_path(
resolved_path,
distribution_root=distribution_root,
installation_root=installation_root,
declared_scripts=declared_scripts,
)
if artifact_path is not None and not _installer_generated_metadata(
resolved_path, distribution_root=distribution_root
):
artifact_payload_rows.append({**row, "path": artifact_path})
else:
counts["mismatched_file_count"] += 1
if limit_exceeded:
status = "limit-exceeded"
elif counts["missing_file_count"] or counts["mismatched_file_count"]:
status = "mismatch"
elif counts["hashed_file_count"] == 0:
status = "unavailable"
elif counts["unverifiable_file_count"]:
status = "partial"
else:
status = "verified"
if status == "verified":
installed_identity = _payload_identity(
algorithm=INSTALLED_PAYLOAD_ALGORITHM,
rows=installed_payload_rows,
)
artifact_identity = _payload_identity(
algorithm=WHEEL_PAYLOAD_ALGORITHM,
rows=artifact_payload_rows,
)
if installed_identity is None or artifact_identity is None:
status = "partial"
counts["unverifiable_file_count"] += 1
else:
identities["installed_payload_identity"] = installed_identity
identities["artifact_payload_identity"] = artifact_identity
return {"status": status, **counts, **identities}
def _payload_identity(
*, algorithm: str, rows: list[dict[str, object]]
) -> dict[str, object] | None:
ordered = sorted(rows, key=lambda item: str(item["path"]))
paths = [str(item["path"]) for item in ordered]
if not ordered or len(set(paths)) != len(paths):
return None
return {
"algorithm": algorithm,
"sha256": payload_identity_sha256(algorithm=algorithm, rows=ordered),
"file_count": len(ordered),
}
def _installed_payload_path(
path: Path,
*,
distribution_root: Path,
installation_root: Path,
declared_scripts: frozenset[str],
) -> str | None:
if _is_relative_to(path, distribution_root):
return path.relative_to(distribution_root).as_posix()
for script_root in (
(installation_root / "bin").resolve(),
(installation_root / "Scripts").resolve(),
):
if path.parent == script_root and path.name in declared_scripts:
return f"@scripts/{path.name}"
if _is_relative_to(path, installation_root):
return f"@data/{path.relative_to(installation_root).as_posix()}"
return None
def _artifact_payload_path(
path: Path,
*,
distribution_root: Path,
installation_root: Path,
declared_scripts: frozenset[str],
) -> str | None:
installed = _installed_payload_path(
path,
distribution_root=distribution_root,
installation_root=installation_root,
declared_scripts=declared_scripts,
)
return None if installed is None or installed.startswith("@scripts/") else installed
def _installer_generated_metadata(
path: Path, *, distribution_root: Path
) -> bool:
if not _is_relative_to(path, distribution_root):
return False
relative = path.relative_to(distribution_root)
return (
len(relative.parts) >= 2
and relative.parent.name.endswith(".dist-info")
and relative.name in {"direct_url.json", "INSTALLER", "REQUESTED"}
)
def _resolve_record_path(
*,
distribution: metadata.Distribution,
package_path: object,
distribution_root: Path,
installation_root: Path,
owner_prefix: str,
declared_scripts: frozenset[str],
) -> Path | None:
record_path = PurePosixPath(str(package_path).replace("\\", "/"))
if record_path.is_absolute() or not record_path.parts:
return None
try:
unresolved_path = Path(distribution.locate_file(package_path))
if unresolved_path.is_symlink():
return None
resolved_path = unresolved_path.resolve()
except (OSError, TypeError, ValueError):
return None
has_parent_traversal = ".." in record_path.parts
if not has_parent_traversal:
return (
resolved_path if _is_relative_to(resolved_path, distribution_root) else None
)
script_roots = (
(installation_root / "bin").resolve(),
(installation_root / "Scripts").resolve(),
)
for script_root in script_roots:
if (
resolved_path.parent == script_root
and resolved_path.name in declared_scripts
):
return resolved_path
if not _is_relative_to(resolved_path, installation_root):
return None
relative = resolved_path.relative_to(installation_root)
if not relative.parts:
return None
owned_root = relative.parts[0]
if owned_root == owner_prefix or owned_root.startswith(f"{owner_prefix}_"):
return resolved_path
return None
def _declared_distribution_scripts(
distribution: metadata.Distribution,
) -> frozenset[str]:
scripts: set[str] = set()
try:
entry_points = distribution.entry_points
except Exception:
return frozenset()
for entry_point in entry_points:
if entry_point.group != "console_scripts":
continue
name = str(entry_point.name)
if len(name) > 160 or re.fullmatch(r"[A-Za-z0-9][A-Za-z0-9._-]*", name) is None:
continue
scripts.update((name, f"{name}.exe", f"{name}-script.py"))
return frozenset(scripts)
def _bounded_file_sha256(path: Path, *, max_bytes: int) -> tuple[bytes, int, bool]:
flags = os.O_RDONLY | getattr(os, "O_NOFOLLOW", 0)
descriptor = os.open(path, flags)
digest = hashlib.sha256()
total = 0
exceeded = False
try:
file_stat = os.fstat(descriptor)
if not stat.S_ISREG(file_stat.st_mode):
raise OSError("RECORD path is not a regular file")
if file_stat.st_size > max_bytes:
return digest.digest(), 0, True
expected_size = file_stat.st_size
with os.fdopen(descriptor, "rb", closefd=False) as handle:
while total < expected_size:
chunk = handle.read(min(1024 * 1024, expected_size - total))
if not chunk:
break
digest.update(chunk)
total += len(chunk)
final_stat = os.fstat(descriptor)
exceeded = total != expected_size or final_stat.st_size != expected_size
finally:
os.close(descriptor)
return digest.digest(), total, exceeded
def _record_hash_bytes(value: str) -> bytes | None:
try:
decoded = base64.urlsafe_b64decode(value + "=" * (-len(value) % 4))
except (ValueError, TypeError):
return None
return decoded if len(decoded) == hashlib.sha256().digest_size else None
def _record_integrity_semantics_valid(record: Mapping[str, Any]) -> bool:
count_names = (
"hashed_file_count",
"permitted_unhashed_file_count",
"generated_unhashed_file_count",
"unverifiable_file_count",
"missing_file_count",
"mismatched_file_count",
)
counts: dict[str, int] = {}
for name in count_names:
value = record.get(name)
if isinstance(value, bool) or not isinstance(value, int) or value < 0:
return False
counts[name] = value
if sum(counts.values()) > MAX_DISTRIBUTION_FILES:
return False
status = record.get("status")
hashed = counts["hashed_file_count"]
unverifiable = counts["unverifiable_file_count"]
missing = counts["missing_file_count"]
mismatched = counts["mismatched_file_count"]
if status == "verified":
artifact_identity = record.get("artifact_payload_identity")
installed_identity = record.get("installed_payload_identity")
return (
hashed > 0
and counts["permitted_unhashed_file_count"] > 0
and unverifiable == 0
and missing == 0
and mismatched == 0
and _payload_identity_semantics_valid(
artifact_identity,
algorithm=WHEEL_PAYLOAD_ALGORITHM,
maximum_files=hashed,
)
and _payload_identity_semantics_valid(
installed_identity,
algorithm=INSTALLED_PAYLOAD_ALGORITHM,
maximum_files=hashed,
exact_files=hashed,
)
)
if status == "partial":
return hashed > 0 and unverifiable > 0 and missing == 0 and mismatched == 0
if status == "mismatch":
return missing + mismatched > 0
if status == "unavailable":
return hashed == 0 and missing == 0 and mismatched == 0
if status == "limit-exceeded":
return True
return False
def _payload_identity_semantics_valid(
value: object,
*,
algorithm: str,
maximum_files: int,
exact_files: int | None = None,
) -> bool:
if not isinstance(value, Mapping) or set(value) != {
"algorithm",
"sha256",
"file_count",
}:
return False
file_count = value.get("file_count")
return (
value.get("algorithm") == algorithm
and isinstance(value.get("sha256"), str)
and SHA256_PATTERN.fullmatch(str(value["sha256"])) is not None
and isinstance(file_count, int)
and not isinstance(file_count, bool)
and 0 < file_count <= maximum_files
and (exact_files is None or file_count == exact_files)
)
def _permitted_unhashed_record_path(
path: Path,
*,
distribution_root: Path,
owner_prefix: str,
) -> bool:
if not _is_relative_to(path, distribution_root):
return False
if path.name not in {"RECORD", "RECORD.jws", "RECORD.p7s"}:
return False
parent = path.parent.name
return parent.endswith(".dist-info") and (
parent == f"{owner_prefix}.dist-info" or parent.startswith(f"{owner_prefix}-")
)
def _generated_unhashed_pyc(
path: Path,
*,
hashed_payload_paths: set[Path],
) -> bool:
if path.suffix != ".pyc" or "__pycache__" not in path.parts:
return False
try:
source = Path(source_from_cache(str(path))).resolve()
except (ValueError, OSError):
return False
return source in hashed_payload_paths
def _active_authority_keys(
*,
authority_keyring: dict[str, Any],
verification_time: datetime,
forbidden_public_keys: frozenset[bytes],
) -> tuple[dict[str, tuple[bytes, frozenset[str]]], tuple[EvidenceFinding, ...]]:
result: dict[str, tuple[bytes, frozenset[str]]] = {}
findings: list[EvidenceFinding] = []
seen: set[str] = set()
public_key_owners: dict[bytes, str] = {}
duplicate_public_keys: set[bytes] = set()
raw_keys = authority_keyring.get("keys")
if not isinstance(raw_keys, list):
return {}, (
EvidenceFinding(
"blocker",
"boundary_authority_key_invalid",
"Proof-authority keyring does not contain a valid key list.",
("assessment.external_proof",),
),
)
for item in raw_keys:
if not isinstance(item, dict):
findings.append(
EvidenceFinding(
"blocker",
"boundary_authority_key_invalid",
"Proof-authority keyring contains a malformed key entry.",
("assessment.external_proof",),
)
)
continue
key_id = str(item.get("key_id") or "")
status = item.get("status")
raw_allowed_scopes = item.get("allowed_scopes")
if (
len(key_id) > 160
or OPAQUE_ID_PATTERN.fullmatch(key_id) is None
or status not in {"active", "next", "revoked", "disabled", "retired"}
or not isinstance(raw_allowed_scopes, list)
or not raw_allowed_scopes
or any(not isinstance(scope, str) for scope in raw_allowed_scopes)
or len(raw_allowed_scopes) != len(set(raw_allowed_scopes))
or any(scope not in PROOF_REQUIREMENTS for scope in raw_allowed_scopes)
):
findings.append(
EvidenceFinding(
"blocker",
"boundary_authority_key_invalid",
"Proof-authority keyring contains a malformed key entry.",
("assessment.external_proof",),
)
)
continue
if key_id in seen:
findings.append(
EvidenceFinding(
"blocker",
"boundary_authority_key_duplicate",
"Proof-authority keyring repeats a key ID.",
("assessment.external_proof",),
)
)
continue
seen.add(key_id)
try:
public_key = base64.b64decode(
str(item.get("public_key") or ""), validate=True
)
Ed25519PublicKey.from_public_bytes(public_key)
except ValueError:
findings.append(
EvidenceFinding(
"blocker",
"boundary_authority_key_invalid",
"Proof-authority keyring contains invalid Ed25519 public-key material.",
("assessment.external_proof",),
)
)
continue
raw_not_before = item.get("not_before")
raw_not_after = item.get("not_after")
not_before = _datetime(raw_not_before)
not_after = _datetime(raw_not_after)
if (
(raw_not_before is not None and not_before is None)
or (raw_not_after is not None and not_after is None)
or (
not_before is not None
and not_after is not None
and not_before >= not_after
)
):
findings.append(
EvidenceFinding(
"blocker",
"boundary_authority_key_interval_invalid",
"Proof-authority keyring contains an invalid or empty key-validity interval.",
("assessment.external_proof",),
)
)
continue
previous_owner = public_key_owners.get(public_key)
if previous_owner is not None and previous_owner != key_id:
if public_key not in duplicate_public_keys:
findings.append(
EvidenceFinding(
"blocker",
"boundary_authority_public_key_duplicate",
"Proof-authority keyring assigns one public key to multiple key IDs.",
("assessment.external_proof",),
)
)
duplicate_public_keys.add(public_key)
result.pop(previous_owner, None)
continue
public_key_owners[public_key] = key_id
if status not in {"active", "next"}:
continue
if (not_before is not None and verification_time < not_before) or (
not_after is not None and verification_time >= not_after
):
continue
if public_key in forbidden_public_keys:
findings.append(
EvidenceFinding(
"blocker",
"boundary_authority_reuses_release_key",
"A proof-authority public key is also trusted for catalog release signatures.",
("assessment.external_proof",),
)
)
continue
result[key_id] = (
public_key,
frozenset(raw_allowed_scopes),
)
# A supplied authority keyring is one trust root. Selecting usable members
# out of a malformed set would let a valid-looking sibling conceal an
# invalid interval, duplicate identity, or ambiguous key assignment.
return ({} if findings else result), tuple(findings)
def _record_change(
*,
findings: list[EvidenceFinding],
changes: list[dict[str, Any]],
changed_repositories: set[str],
affected_module_ids: set[str],
component: Mapping[str, Any],
kind: str,
code: str,
message: str,
extra: Mapping[str, Any] | None = None,
) -> None:
module_id = str(component.get("module_id"))
repository = str(component.get("repository"))
changed_repositories.add(repository)
affected_module_ids.add(module_id)
findings.append(
EvidenceFinding(
"review",
code,
message,
(f"composition.{module_id}",),
)
)
change: dict[str, Any] = {
"module_id": module_id,
"repository": repository,
"kind": kind,
}
if extra:
change.update(extra)
changes.append(change)
def _unchecked_installed_scope() -> dict[str, Any]:
return {
"installed_artifacts": {
"checked": False,
"valid": None,
"required_evidence": (
"A bounded installed-composition evidence document collected from the Python environment under review.",
),
},
"installed_record_integrity": {"checked": False, "valid": None},
"installed_source_provenance": {
"checked": False,
"valid": None,
"basis": "local-pep610-metadata",
"release_origin_bound": False,
},
"installed_release_origin": {
"checked": False,
"valid": None,
"release_origin_bound": False,
"required_evidence": (
"An independently anchored artifact digest or signed installer receipt bound to the signed release catalog.",
),
},
"runtime_activation": {
"checked": False,
"valid": None,
"required_evidence": (
"A separately collected runtime registry/configuration snapshot bound to installed evidence.",
),
},
}
def _invalid_installed_scope(*, digest: str) -> dict[str, Any]:
scope = _unchecked_installed_scope()
scope["installed_artifacts"] = {
"checked": False,
"valid": None,
"comparison_valid": False,
"evidence_sha256": digest,
}
return scope
def _unchecked_boundary_scope(
*, expected_subjects: Mapping[str, str | None]
) -> dict[str, Any]:
return {
scope: {
"checked": False,
"valid": None,
"expected_subject_id": expected_subjects.get(scope),
"required_evidence": requirements,
}
for scope, requirements in PROOF_REQUIREMENTS.items()
}
def _datetime(value: object) -> datetime | None:
if not isinstance(value, str) or not value:
return None
try:
parsed = datetime.fromisoformat(value.replace("Z", "+00:00"))
except ValueError:
return None
return parsed if parsed.tzinfo is not None else parsed.replace(tzinfo=UTC)
def _iso_datetime(value: datetime | None) -> str | None:
if value is None:
return None
return value.astimezone(UTC).isoformat().replace("+00:00", "Z")
def _safe_opaque_id(value: object, *, fallback: str) -> str:
text = value if isinstance(value, str) else ""
return (
text
if len(text) <= 160 and OPAQUE_ID_PATTERN.fullmatch(text) is not None
else fallback
)
def _safe_opaque_id_or_none(value: object) -> str | None:
if not isinstance(value, str):
return None
if len(value) > 160 or OPAQUE_ID_PATTERN.fullmatch(value) is None:
return None
return value
def _json_path(parts: Iterable[object]) -> str:
path = "$"
for part in parts:
path += f"[{part}]" if isinstance(part, int) else f".{part}"
return path
def _unique_dicts(values: Sequence[dict[str, str]]) -> list[dict[str, str]]:
result: list[dict[str, str]] = []
seen: set[tuple[tuple[str, str], ...]] = set()
for value in values:
key = tuple(sorted(value.items()))
if key not in seen:
seen.add(key)
result.append(value)
return result
def _is_relative_to(path: Path, root: Path) -> bool:
try:
path.relative_to(root)
except ValueError:
return False
return True
def _trusted_distribution_root(root: Path) -> bool:
for value in sys.path:
try:
candidate = Path(value or ".").resolve()
except OSError:
continue
if candidate.parent == candidate:
continue
if root == candidate or _is_relative_to(root, candidate):
return True
return False