feat(access-control-prover): decode installed fact authority

This commit is contained in:
Marius Ciepluch
2026-11-01 16:56:26 +01:00
parent a2ffbacd05
commit a5ebc69a6e
4 changed files with 738 additions and 1 deletions
@@ -0,0 +1,248 @@
"""Nested value codecs for the installed fact-authority wire boundary."""
from __future__ import annotations
import json
from collections.abc import Callable, Mapping
from dataclasses import fields, is_dataclass
from enum import Enum
from typing import TypeVar, cast
from openultrasast.core import canonical, provenance, semantics
from openultrasast.core.factpack import (
IndependenceAttestation,
KnowledgeEvidence,
KnowledgeEvidenceKind,
RelationEffect,
ReviewIndependencePolicy,
SemanticFact,
StructuralRequirement,
StructuralRequirementKind,
)
_T = TypeVar("_T")
_REF_FIELDS = ("artifact_id", "content_digest", "media_type", "byte_length", "retention_policy_digest", "storage_receipt_digest")
_ATTESTATION_FIELDS = ("subject_digest", "producer_identity", "reviewer_identity", "conflict_disclosure", "attestation_digest")
class InstalledAuthorityWireError(ValueError):
"""Installed authority bytes do not satisfy the closed wire contract."""
def wire_value(value: object) -> canonical.JsonValue:
"""Project dataclasses, enums, and parsed JSON into canonical values."""
if isinstance(value, Enum):
return cast(canonical.JsonValue, value.value)
if is_dataclass(value) and not isinstance(value, type):
return {item.name: wire_value(getattr(value, item.name)) for item in fields(value)}
if isinstance(value, Mapping):
if not all(isinstance(key, str) for key in value):
raise InstalledAuthorityWireError("JSON object keys must be text")
return {cast(str, key): wire_value(item) for key, item in value.items()}
if isinstance(value, (tuple, list)):
return tuple(wire_value(item) for item in value)
if value is None or isinstance(value, (str, bool, int, float)):
return value
raise InstalledAuthorityWireError(f"unsupported wire value: {type(value).__name__}")
def closed_object(value: object, expected: tuple[str, ...], label: str) -> dict[str, object]:
"""Require a JSON object with exactly the declared field set."""
if not isinstance(value, dict) or not all(isinstance(key, str) for key in value):
raise InstalledAuthorityWireError(f"{label} must be an object")
record = cast(dict[str, object], value)
missing = set(expected) - set(record)
unknown = set(record) - set(expected)
if missing or unknown:
details = [f"missing {item}" for item in sorted(missing)]
details.extend(f"unknown {item}" for item in sorted(unknown))
raise InstalledAuthorityWireError(f"{label} has {', '.join(details)}")
return record
def items(value: object, label: str) -> tuple[object, ...]:
if not isinstance(value, list):
raise InstalledAuthorityWireError(f"{label} must be an array")
return tuple(value)
def text(value: object, label: str) -> str:
if not isinstance(value, str) or not value:
raise InstalledAuthorityWireError(f"{label} must be nonempty text")
return value
def integer(value: object, label: str) -> int:
if isinstance(value, bool) or not isinstance(value, int):
raise InstalledAuthorityWireError(f"{label} must be an integer")
return value
def boolean(value: object, label: str) -> bool:
if not isinstance(value, bool):
raise InstalledAuthorityWireError(f"{label} must be boolean")
return value
def strings(value: object, label: str) -> tuple[str, ...]:
return tuple(text(item, label) for item in items(value, label))
def pairs(value: object, label: str) -> tuple[tuple[str, str], ...]:
decoded: list[tuple[str, str]] = []
for item in items(value, label):
pair = items(item, label)
if len(pair) != 2:
raise InstalledAuthorityWireError(f"{label} entries must be pairs")
decoded.append((text(pair[0], label), text(pair[1], label)))
return tuple(decoded)
def parse_record(content: bytes, schema: str, expected: tuple[str, ...], label: str) -> dict[str, object]:
"""Parse canonical JSON and enforce its top-level schema and fields."""
if not isinstance(content, bytes):
raise InstalledAuthorityWireError(f"{label} content must be bytes")
try:
raw: object = json.loads(content)
except (UnicodeDecodeError, json.JSONDecodeError) as exc:
raise InstalledAuthorityWireError(f"{label} is not valid JSON") from exc
record = closed_object(raw, expected, label)
if record["schema_version"] != schema:
raise InstalledAuthorityWireError(f"unknown {label} schema")
if canonical.canonical_bytes(wire_value(record)) != content:
raise InstalledAuthorityWireError(f"{label} bytes are not canonical")
return record
def decode_value(label: str, build: Callable[[], _T]) -> _T:
"""Normalize typed construction failures to the wire error boundary."""
try:
return build()
except InstalledAuthorityWireError:
raise
except (KeyError, TypeError, ValueError) as exc:
raise InstalledAuthorityWireError(f"invalid {label}: {exc}") from exc
def content_ref(value: object) -> canonical.ContentRef:
row = closed_object(value, _REF_FIELDS, "content reference")
return canonical.ContentRef(
text(row["artifact_id"], "artifact_id"),
text(row["content_digest"], "content_digest"),
text(row["media_type"], "media_type"),
integer(row["byte_length"], "byte_length"),
text(row["retention_policy_digest"], "retention_policy_digest"),
text(row["storage_receipt_digest"], "storage_receipt_digest"),
)
def attestation(value: object) -> IndependenceAttestation:
row = closed_object(value, _ATTESTATION_FIELDS, "attestation")
return IndependenceAttestation(
text(row["subject_digest"], "subject_digest"),
text(row["producer_identity"], "producer_identity"),
text(row["reviewer_identity"], "reviewer_identity"),
content_ref(row["conflict_disclosure"]),
text(row["attestation_digest"], "attestation_digest"),
)
def evidence(value: object) -> KnowledgeEvidence:
expected = ("kind", "content", "producer_identity", "reviewer_identity", "independence", "lineage_manifest_digest")
row = closed_object(value, expected, "knowledge evidence")
return KnowledgeEvidence(
KnowledgeEvidenceKind(text(row["kind"], "evidence kind")),
content_ref(row["content"]),
text(row["producer_identity"], "producer_identity"),
text(row["reviewer_identity"], "reviewer_identity"),
attestation(row["independence"]),
text(row["lineage_manifest_digest"], "lineage_manifest_digest"),
)
def requirement(value: object) -> StructuralRequirement:
row = closed_object(value, ("requirement_id", "kind", "field", "expected"), "structural requirement")
return StructuralRequirement(
text(row["requirement_id"], "requirement_id"),
StructuralRequirementKind(text(row["kind"], "requirement kind")),
text(row["field"], "requirement field"),
wire_value(row["expected"]),
)
def effect(value: object) -> RelationEffect:
row = closed_object(value, ("kind", "role", "source_role", "target_role", "conditions"), "relation effect")
return RelationEffect(
semantics.RelationKind(text(row["kind"], "relation kind")),
text(row["role"], "effect role"),
text(row["source_role"], "source role"),
text(row["target_role"], "target role"),
strings(row["conditions"], "conditions"),
)
def fact(value: object) -> SemanticFact:
row = closed_object(value, ("fact_id", "role", "structural_requirements", "relation_effects"), "semantic fact")
requirements = items(row["structural_requirements"], "structural_requirements")
effects = items(row["relation_effects"], "relation_effects")
return SemanticFact(
text(row["fact_id"], "fact_id"),
text(row["role"], "fact role"),
tuple(requirement(item) for item in requirements),
tuple(effect(item) for item in effects),
)
def lineage(value: object) -> provenance.LineageManifest:
row = closed_object(value, ("arm_id", "subject_digest", "uses", "manifest_digest"), "lineage")
expected = (
"purpose",
"source_population_digest",
"labels_accessed",
"influenced_artifact_digest",
"population_use_receipt_digest",
)
uses = tuple(_lineage_use(item, expected) for item in items(row["uses"], "lineage uses"))
return provenance.LineageManifest(
text(row["arm_id"], "arm_id"),
text(row["subject_digest"], "subject_digest"),
uses,
text(row["manifest_digest"], "manifest_digest"),
)
def _lineage_use(value: object, expected: tuple[str, ...]) -> provenance.LineageUse:
row = closed_object(value, expected, "lineage use")
return provenance.LineageUse(
provenance.LineagePurpose(text(row["purpose"], "lineage purpose")),
text(row["source_population_digest"], "source population"),
boolean(row["labels_accessed"], "labels_accessed"),
text(row["influenced_artifact_digest"], "influenced artifact"),
text(row["population_use_receipt_digest"], "population receipt"),
)
def custody_policy(value: object) -> provenance.PopulationCustodyPolicy:
row = closed_object(value, ("reviewed_custodian_digests", "policy_digest"), "custody policy")
return provenance.PopulationCustodyPolicy(
strings(row["reviewed_custodian_digests"], "custodian digests"),
text(row["policy_digest"], "custody policy digest"),
)
def review_policy(value: object) -> ReviewIndependencePolicy:
expected = (
"reviewed_reviewer_digests",
"forbidden_identity_pairs",
"trusted_store_identities",
"maximum_evidence_bytes",
"policy_digest",
)
row = closed_object(value, expected, "review policy")
return ReviewIndependencePolicy(
strings(row["reviewed_reviewer_digests"], "reviewer digests"),
pairs(row["forbidden_identity_pairs"], "forbidden pairs"),
strings(row["trusted_store_identities"], "store identities"),
integer(row["maximum_evidence_bytes"], "maximum evidence bytes"),
text(row["policy_digest"], "review policy digest"),
)
@@ -0,0 +1,242 @@
"""Closed canonical wire format for installed entry-fact authority."""
from __future__ import annotations
import re
from collections.abc import Mapping
from dataclasses import dataclass
from pathlib import Path
from typing import cast
from openultrasast.core import canonical
from openultrasast.core.factpack import FACT_PACK_SCHEMA, FactPack
from openultrasast.core.family import FamilyContract
from openultrasast.mapping._installed_fact_authority_codec import (
InstalledAuthorityWireError,
attestation,
content_ref,
custody_policy,
decode_value,
evidence,
fact,
integer,
items,
lineage,
pairs,
parse_record,
review_policy,
strings,
text,
wire_value,
)
from openultrasast.mapping.fact_authority import (
ENTRY_AUTHORITY_BOOTSTRAP_SCHEMA,
EntryAuthorityBootstrapPolicy,
EntryFactAuthorityBundle,
)
INSTALLED_AUTHORITY_SCHEMA = "openultrasast.access-control.installed-entry-authority.v1"
PACK_FILES = ("express.javascript.v2.json", "express.typescript.v2.json")
_PACK_LANGUAGES = ("javascript", "typescript")
_DIGEST = re.compile(r"[0-9a-f]{64}")
_PACK_FIELDS = (
"schema_version",
"family_contract_digest",
"family_id",
"ecosystem",
"language",
"facts",
"normalized_content_digest",
"review_identity",
"review_evidence",
"review_evidence_digest",
"review_policy_digest",
)
_BOOTSTRAP_FIELDS = (
"schema_version",
"reviewed_bundle_reviewer_digests",
"forbidden_identity_pairs",
"trusted_store_identities",
"maximum_bundle_bytes",
"policy_digest",
)
_AUTHORITY_FIELDS = (
"schema_version",
"pack_files",
"recognition_projection",
"lineages",
"custody_policy",
"review_policy",
"matcher_revision",
"matcher_behavior_digest",
"matcher_lineage_manifest_digest",
"authority_review",
"bundle_digest",
)
def _record_bytes(value: object, schema: str) -> bytes:
record = cast(Mapping[str, canonical.JsonValue], wire_value(value))
return canonical.canonical_record_bytes(record, known_schema_versions=(schema,))
def fact_pack_bytes(value: FactPack) -> bytes:
"""Encode every public fact-pack field as canonical JSON."""
return _record_bytes(value, FACT_PACK_SCHEMA)
def decode_fact_pack_bytes(content: bytes) -> FactPack:
"""Decode only the closed v2 fact-pack representation."""
def build() -> FactPack:
row = parse_record(content, FACT_PACK_SCHEMA, _PACK_FIELDS, "fact pack")
value = FactPack(
FACT_PACK_SCHEMA,
text(row["family_contract_digest"], "family_contract_digest"),
text(row["family_id"], "family_id"),
text(row["ecosystem"], "ecosystem"),
text(row["language"], "language"),
tuple(fact(item) for item in items(row["facts"], "facts")),
text(row["normalized_content_digest"], "normalized_content_digest"),
text(row["review_identity"], "review_identity"),
tuple(evidence(item) for item in items(row["review_evidence"], "review_evidence")),
text(row["review_evidence_digest"], "review_evidence_digest"),
text(row["review_policy_digest"], "review_policy_digest"),
)
if fact_pack_bytes(value) != content:
raise InstalledAuthorityWireError("fact pack does not round-trip canonically")
return value
return decode_value("fact pack", build)
def bootstrap_bytes(value: EntryAuthorityBootstrapPolicy) -> bytes:
"""Encode the external bootstrap policy without authority data."""
row = cast(dict[str, canonical.JsonValue], wire_value(value))
return canonical.canonical_record_bytes(
{"schema_version": ENTRY_AUTHORITY_BOOTSTRAP_SCHEMA, **row},
known_schema_versions=(ENTRY_AUTHORITY_BOOTSTRAP_SCHEMA,),
)
def decode_bootstrap_bytes(content: bytes) -> EntryAuthorityBootstrapPolicy:
"""Decode a closed external bootstrap policy."""
def build() -> EntryAuthorityBootstrapPolicy:
row = parse_record(content, ENTRY_AUTHORITY_BOOTSTRAP_SCHEMA, _BOOTSTRAP_FIELDS, "bootstrap")
value = EntryAuthorityBootstrapPolicy(
strings(row["reviewed_bundle_reviewer_digests"], "bundle reviewers"),
pairs(row["forbidden_identity_pairs"], "forbidden pairs"),
strings(row["trusted_store_identities"], "store identities"),
integer(row["maximum_bundle_bytes"], "maximum bundle bytes"),
text(row["policy_digest"], "policy digest"),
)
if bootstrap_bytes(value) != content:
raise InstalledAuthorityWireError("bootstrap does not round-trip canonically")
return value
return decode_value("bootstrap", build)
def _authority_record(value: EntryFactAuthorityBundle) -> dict[str, canonical.JsonValue]:
return {
"schema_version": INSTALLED_AUTHORITY_SCHEMA,
"pack_files": PACK_FILES,
"recognition_projection": wire_value(value.recognition_projection),
"lineages": wire_value(value.lineages),
"custody_policy": wire_value(value.custody_policy),
"review_policy": wire_value(value.review_policy),
"matcher_revision": value.matcher_revision,
"matcher_behavior_digest": value.matcher_behavior_digest,
"matcher_lineage_manifest_digest": value.matcher_lineage_manifest_digest,
"authority_review": wire_value(value.authority_review),
"bundle_digest": value.bundle_digest,
}
def installed_authority_bytes(value: EntryFactAuthorityBundle) -> bytes:
"""Encode installed authority while leaving bootstrap trust external."""
return canonical.canonical_record_bytes(
_authority_record(value),
known_schema_versions=(INSTALLED_AUTHORITY_SCHEMA,),
)
def decode_installed_authority_bytes(
content: bytes,
packs: tuple[FactPack, ...],
contract: FamilyContract,
) -> EntryFactAuthorityBundle:
"""Decode closed installed authority and attach separately decoded packs."""
def build() -> EntryFactAuthorityBundle:
row = parse_record(content, INSTALLED_AUTHORITY_SCHEMA, _AUTHORITY_FIELDS, "installed authority")
if strings(row["pack_files"], "pack_files") != PACK_FILES:
raise InstalledAuthorityWireError("pack_files must use the fixed order")
if tuple(pack.language for pack in packs) != _PACK_LANGUAGES:
raise InstalledAuthorityWireError("packs must use the fixed language order")
value = EntryFactAuthorityBundle(
contract,
packs,
content_ref(row["recognition_projection"]),
tuple(lineage(item) for item in items(row["lineages"], "lineages")),
custody_policy(row["custody_policy"]),
review_policy(row["review_policy"]),
text(row["matcher_revision"], "matcher_revision"),
text(row["matcher_behavior_digest"], "matcher_behavior_digest"),
text(row["matcher_lineage_manifest_digest"], "matcher_lineage_manifest_digest"),
attestation(row["authority_review"]),
text(row["bundle_digest"], "bundle_digest"),
)
if installed_authority_bytes(value) != content:
raise InstalledAuthorityWireError("installed authority does not round-trip canonically")
return value
return decode_value("installed authority", build)
@dataclass(frozen=True)
class DigestDirectoryResolver:
"""Read immutable artifacts by validated content digest only."""
root: Path
store_identity: str
def resolve(self, reference: canonical.ContentRef) -> canonical.ResolvedContent:
if _DIGEST.fullmatch(reference.content_digest) is None:
raise canonical.ArtifactResolutionError("content digest is not lowercase SHA-256")
path = self.root / "artifacts" / "sha256" / reference.content_digest
try:
content = path.read_bytes()
except OSError as exc:
raise canonical.ArtifactResolutionError("digest-addressed artifact is unavailable") from exc
if len(content) != reference.byte_length or canonical.bytes_digest(content) != reference.content_digest:
raise canonical.ArtifactResolutionError("digest-addressed artifact bytes do not match reference")
receipt_digest = canonical.derive_storage_receipt_digest(
store_identity=self.store_identity,
content_digest=reference.content_digest,
byte_length=reference.byte_length,
retention_policy_digest=reference.retention_policy_digest,
)
receipt = canonical.StorageReceipt(
self.store_identity,
reference.content_digest,
reference.byte_length,
reference.retention_policy_digest,
receipt_digest,
)
return canonical.ResolvedContent(content, receipt)
__all__ = [
"DigestDirectoryResolver",
"INSTALLED_AUTHORITY_SCHEMA",
"InstalledAuthorityWireError",
"PACK_FILES",
"bootstrap_bytes",
"decode_bootstrap_bytes",
"decode_fact_pack_bytes",
"decode_installed_authority_bytes",
"fact_pack_bytes",
"installed_authority_bytes",
]