feat: enforce signed target maturity evidence
Dependency Audit / dependency-audit (push) Failing after 9s
Deployment Installer / deployment-installer (push) Successful in 6s
Security Audit / security-audit (push) Failing after 8s

This commit is contained in:
2026-08-02 03:41:09 +02:00
parent be8ba10ae3
commit 2c56a0fc11
12 changed files with 1245 additions and 15 deletions
+363
View File
@@ -0,0 +1,363 @@
#!/usr/bin/env python3
"""Issue and immediately verify a sanitized target-boundary proof."""
from __future__ import annotations
import argparse
from copy import deepcopy
from datetime import UTC, datetime
import json
from pathlib import Path
import sys
META_ROOT = Path(__file__).resolve().parents[2]
for tools_root in (
META_ROOT / "tools" / "assessments",
META_ROOT / "tools" / "release",
):
if str(tools_root) not in sys.path:
sys.path.insert(0, str(tools_root))
from cryptography.hazmat.primitives import serialization # noqa: E402
from cryptography.hazmat.primitives.asymmetric.ed25519 import ( # noqa: E402
Ed25519PrivateKey,
)
from govoplan_assessment.atomic_io import ( # noqa: E402
AtomicJsonWriteError,
atomic_write_json,
)
from govoplan_assessment.boundary_evidence import ( # noqa: E402
issue_boundary_evidence,
)
from govoplan_assessment.capability_fit import review_capability_fit # noqa: E402
from govoplan_assessment.evidence import ( # noqa: E402
public_key_material_from_keyrings,
validate_payload,
)
MAX_INPUT_BYTES = 16 * 1024 * 1024
MAX_OUTPUT_BYTES = 4 * 1024 * 1024
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--assessment", type=Path, required=True)
parser.add_argument(
"--assessment-schema",
type=Path,
default=META_ROOT / "docs" / "capability-fit.schema.json",
)
parser.add_argument("--catalog", type=Path, required=True)
parser.add_argument("--keyring", type=Path, required=True)
parser.add_argument("--trusted-keyring", type=Path, required=True)
parser.add_argument("--installed-evidence", type=Path, required=True)
parser.add_argument(
"--installed-evidence-schema",
type=Path,
default=META_ROOT / "docs" / "installed-composition-evidence.schema.json",
)
parser.add_argument("--installer-receipt", type=Path, required=True)
parser.add_argument(
"--installer-receipt-schema",
type=Path,
default=META_ROOT / "docs" / "installer-receipt.schema.json",
)
parser.add_argument("--installer-authority-keyring", type=Path, required=True)
parser.add_argument(
"--installer-authority-keyring-schema",
type=Path,
default=META_ROOT / "docs" / "installer-receipt-authority-keyring.schema.json",
)
parser.add_argument(
"--claims",
type=Path,
required=True,
help="Private target-run claim manifest; artifact paths are not published.",
)
parser.add_argument(
"--claims-schema",
type=Path,
default=META_ROOT / "docs" / "capability-fit-boundary-run.schema.json",
)
parser.add_argument("--authority-keyring", type=Path, required=True)
parser.add_argument(
"--authority-keyring-schema",
type=Path,
default=META_ROOT
/ "docs"
/ "capability-fit-proof-authority-keyring.schema.json",
)
parser.add_argument(
"--signing-key",
action="append",
default=[],
required=True,
metavar="KEY_ID=/PATH/PRIVATE.pem",
help="Repeat for independent authorities needed to cover all claim scopes.",
)
parser.add_argument("--expected-external-provider-subject")
parser.add_argument("--output", type=Path, required=True)
parser.add_argument("--review-output", type=Path, required=True)
parser.add_argument(
"--boundary-evidence-schema",
type=Path,
default=META_ROOT / "docs" / "capability-fit-boundary-evidence.schema.json",
)
args = parser.parse_args(argv)
if args.output.resolve() == args.review_output.resolve():
parser.error("proof and review output paths must differ")
assessment = read_object(args.assessment, label="assessment")
assessment_schema = read_object(args.assessment_schema, label="assessment schema")
catalog = read_object(args.catalog, label="catalog")
published_keyring = read_object(args.keyring, label="published keyring")
trusted_keyring = read_object(args.trusted_keyring, label="trusted keyring")
installed_evidence = read_object(
args.installed_evidence, label="installed evidence"
)
installed_schema = read_object(
args.installed_evidence_schema, label="installed evidence schema"
)
installer_receipt = read_object(args.installer_receipt, label="installer receipt")
installer_receipt_schema = read_object(
args.installer_receipt_schema, label="installer receipt schema"
)
installer_authorities = read_object(
args.installer_authority_keyring, label="installer authority keyring"
)
installer_authority_schema = read_object(
args.installer_authority_keyring_schema,
label="installer authority keyring schema",
)
claim_manifest = read_object(args.claims, label="target-run claim manifest")
claim_schema = read_object(args.claims_schema, label="target-run claim schema")
authority_keyring = read_object(
args.authority_keyring, label="proof-authority keyring"
)
authority_schema = read_object(
args.authority_keyring_schema, label="proof-authority keyring schema"
)
boundary_schema = read_object(
args.boundary_evidence_schema, label="boundary evidence schema"
)
_require_schema(claim_manifest, claim_schema, label="target-run claim manifest")
_require_schema(
authority_keyring, authority_schema, label="proof-authority keyring"
)
base_report = review_capability_fit(
assessment=assessment,
schema=assessment_schema,
catalog=catalog,
published_keyring=published_keyring,
trusted_keyring=trusted_keyring,
workspace_root=None,
installed_evidence=installed_evidence,
installed_evidence_schema=installed_schema,
installer_receipt=installer_receipt,
installer_receipt_schema=installer_receipt_schema,
installer_authority_keyring=installer_authorities,
installer_authority_keyring_schema=installer_authority_schema,
installed_evidence_mode="imported_unsigned",
)
_require_release_origin(base_report, parser=parser)
claims = resolve_claim_artifact_paths(
claim_manifest.get("claims"), base_dir=args.claims.resolve().parent
)
signing_keys = read_signing_keys(tuple(args.signing_key))
expires_at = parse_datetime(claim_manifest.get("expires_at"), label="expires_at")
forbidden_keys = public_key_material_from_keyrings(
published_keyring,
trusted_keyring,
installer_authorities,
)
try:
proof = issue_boundary_evidence(
assessment=assessment,
installed_evidence=installed_evidence,
proof_id=str(claim_manifest.get("proof_id") or ""),
claims=claims,
authority_keyring=authority_keyring,
signing_keys=signing_keys,
expires_at=expires_at,
expected_external_provider_subject=(
args.expected_external_provider_subject
),
forbidden_authority_public_keys=forbidden_keys,
release_origin_verified=True,
)
except ValueError as exc:
parser.error(str(exc))
_require_schema(proof, boundary_schema, label="issued boundary evidence")
review = review_capability_fit(
assessment=assessment,
schema=assessment_schema,
catalog=catalog,
published_keyring=published_keyring,
trusted_keyring=trusted_keyring,
workspace_root=None,
installed_evidence=installed_evidence,
installed_evidence_schema=installed_schema,
installer_receipt=installer_receipt,
installer_receipt_schema=installer_receipt_schema,
installer_authority_keyring=installer_authorities,
installer_authority_keyring_schema=installer_authority_schema,
boundary_evidence=proof,
boundary_evidence_schema=boundary_schema,
boundary_authority_keyring=authority_keyring,
boundary_authority_keyring_schema=authority_schema,
installed_evidence_mode="imported_unsigned",
expected_external_provider_subject=args.expected_external_provider_subject,
)
supplied_scopes = {str(claim.get("scope")) for claim in proof["claims"]}
unchecked = sorted(
scope
for scope in supplied_scopes
if review.get("proof_scope", {}).get(scope, {}).get("checked") is not True
)
if unchecked:
parser.error(
"issued proof did not pass immediate verification for scopes: "
+ ", ".join(unchecked)
)
write_object(args.output, proof, label="boundary evidence")
write_object(args.review_output, review, label="capability-fit review")
print(
json.dumps(
{
"proof_id": proof["proof_id"],
"scopes": sorted(supplied_scopes),
"reference_readiness": review.get("proof_scope", {}).get(
"reference_readiness"
),
"output": str(args.output),
"review_output": str(args.review_output),
},
sort_keys=True,
)
)
return 0
def read_object(path: Path, *, label: str) -> dict[str, object]:
try:
if path.stat().st_size > MAX_INPUT_BYTES:
raise ValueError("input exceeds size limit")
payload = json.loads(path.read_bytes().decode("utf-8"))
except (OSError, UnicodeDecodeError, json.JSONDecodeError, ValueError) as exc:
raise SystemExit(f"Could not read {label}") from exc
if not isinstance(payload, dict):
raise SystemExit(f"{label.capitalize()} must be a JSON object")
return payload
def read_signing_keys(values: tuple[str, ...]) -> dict[str, Ed25519PrivateKey]:
result: dict[str, Ed25519PrivateKey] = {}
for value in values:
key_id, separator, path_text = value.partition("=")
if not separator or not key_id or not path_text or key_id in result:
raise SystemExit(
"--signing-key must uniquely use KEY_ID=/path/to/private.pem"
)
try:
key = serialization.load_pem_private_key(
Path(path_text).expanduser().read_bytes(), password=None
)
except (OSError, ValueError) as exc:
raise SystemExit("Could not read boundary signing key") from exc
if not isinstance(key, Ed25519PrivateKey):
raise SystemExit("Boundary signing keys must be Ed25519")
result[key_id] = key
return result
def resolve_claim_artifact_paths(
claims: object, *, base_dir: Path
) -> list[dict[str, object]]:
if not isinstance(claims, list):
raise SystemExit("Target-run claim manifest has no claim list")
resolved = deepcopy(claims)
for claim in resolved:
if not isinstance(claim, dict):
continue
artifacts = claim.get("artifacts")
if not isinstance(artifacts, list):
continue
for artifact in artifacts:
if not isinstance(artifact, dict) or not isinstance(
artifact.get("path"), str
):
continue
path = Path(artifact["path"]).expanduser()
artifact["path"] = path if path.is_absolute() else base_dir / path
return resolved
def parse_datetime(value: object, *, label: str) -> datetime:
if not isinstance(value, str):
raise SystemExit(f"{label} must be an RFC 3339 date-time")
try:
parsed = datetime.fromisoformat(value.replace("Z", "+00:00"))
except ValueError as exc:
raise SystemExit(f"{label} must be an RFC 3339 date-time") from exc
if parsed.tzinfo is None:
raise SystemExit(f"{label} must include a timezone")
return parsed.astimezone(UTC)
def _require_schema(
payload: dict[str, object], schema: dict[str, object], *, label: str
) -> None:
errors = validate_payload(payload=payload, schema=schema)
if errors:
raise SystemExit(f"{label.capitalize()} failed schema validation: {errors[0]}")
def _require_release_origin(
report: dict[str, object], *, parser: argparse.ArgumentParser
) -> None:
proof_scope = report.get("proof_scope")
if not isinstance(proof_scope, dict):
parser.error("capability-fit review did not return proof scope")
required = (
"catalog_signature_and_keyring",
"catalog_signature_and_trusted_keyring",
"published_keyring_hash",
"release_metadata",
"installed_artifacts",
"installed_record_integrity",
"installed_release_origin",
)
failed = sorted(
scope
for scope in required
if not isinstance(proof_scope.get(scope), dict)
or proof_scope[scope].get("valid") is not True
)
observation = proof_scope.get("installed_evidence_observation")
if (
not isinstance(observation, dict)
or observation.get("receipt_authenticated") is not True
):
failed.append("installed_evidence_observation.receipt_authenticated")
if failed:
parser.error(
"trusted release and installer evidence must pass before target proof issuance: "
+ ", ".join(failed)
)
def write_object(path: Path, payload: dict[str, object], *, label: str) -> None:
try:
atomic_write_json(path, payload, max_bytes=MAX_OUTPUT_BYTES)
except AtomicJsonWriteError as exc:
raise SystemExit(f"Could not securely write {label}") from exc
if __name__ == "__main__":
raise SystemExit(main())
+28
View File
@@ -20,9 +20,11 @@ for tools_root in (ASSESSMENT_TOOLS_ROOT, RELEASE_TOOLS_ROOT):
from govoplan_assessment import ( # noqa: E402
collect_installed_composition,
enforce_required_boundary_scopes,
render_review,
review_capability_fit,
)
from govoplan_assessment.evidence import REFERENCE_READINESS_SCOPES # noqa: E402
from govoplan_assessment.atomic_io import ( # noqa: E402
AtomicJsonWriteError,
atomic_write_json,
@@ -169,6 +171,21 @@ def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
"never supply a URL, credential, or endpoint identifier."
),
)
parser.add_argument(
"--require-reference-readiness",
action="store_true",
help="Fail unless every reference-readiness boundary scope is current and positive.",
)
parser.add_argument(
"--require-external-provider-proof",
action="store_true",
help="Fail unless current positive external-provider evidence is present.",
)
parser.add_argument(
"--require-production-approval",
action="store_true",
help="Fail unless a current explicit production approval is present.",
)
parser.add_argument(
"--json", action="store_true", help="Print the machine-readable review report."
)
@@ -377,6 +394,17 @@ def main(argv: list[str] | None = None) -> int:
),
expected_external_provider_subject=args.expected_external_provider_subject,
)
required_boundary_scopes: set[str] = set()
if args.require_reference_readiness:
required_boundary_scopes.update(REFERENCE_READINESS_SCOPES)
if args.require_external_provider_proof:
required_boundary_scopes.add("external_providers")
if args.require_production_approval:
required_boundary_scopes.add("production_approval")
if required_boundary_scopes:
enforce_required_boundary_scopes(
report, required_scopes=required_boundary_scopes
)
encoded = json.dumps(report, indent=2, sort_keys=True) + "\n"
if args.output is not None:
write_object(
@@ -1,10 +1,15 @@
"""Repeatable GovOPlaN product-assessment tooling."""
from .capability_fit import review_capability_fit, render_review
from .capability_fit import (
enforce_required_boundary_scopes,
render_review,
review_capability_fit,
)
from .evidence import collect_installed_composition
__all__ = (
"collect_installed_composition",
"enforce_required_boundary_scopes",
"render_review",
"review_capability_fit",
)
@@ -0,0 +1,270 @@
"""Issue sanitized, release-bound target evidence from retained result files."""
from __future__ import annotations
import base64
from datetime import UTC, datetime, timedelta
from pathlib import Path
from typing import Any, Mapping, Sequence
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from .evidence import (
MAX_HASHED_FILE_BYTES,
NEGATIVE_RESULTS,
OPAQUE_ID_PATTERN,
POSITIVE_RESULTS,
PROOF_REQUIREMENTS,
_active_authority_keys,
_bounded_file_sha256,
canonical_bytes,
canonical_sha256,
)
MAX_BOUNDARY_ARTIFACT_BYTES = MAX_HASHED_FILE_BYTES
MAX_BOUNDARY_ARTIFACT_TOTAL_BYTES = 512 * 1024 * 1024
def issue_boundary_evidence(
*,
assessment: Mapping[str, Any],
installed_evidence: Mapping[str, Any],
proof_id: str,
claims: Sequence[Mapping[str, Any]],
authority_keyring: dict[str, Any],
signing_keys: Mapping[str, Ed25519PrivateKey],
expires_at: datetime,
issued_at: datetime | None = None,
expected_external_provider_subject: str | None = None,
forbidden_authority_public_keys: frozenset[bytes] = frozenset(),
release_origin_verified: bool = False,
) -> dict[str, Any]:
"""Build and sign one bounded proof after its release origin was verified.
The public CLI is responsible for deriving ``release_origin_verified`` from
the signed catalog, installed observation and installer receipt. Artifact
paths are consumed here and never copied into the resulting receipt.
"""
if release_origin_verified is not True:
raise ValueError(
"boundary evidence requires independently verified installed release origin"
)
_require_opaque_id(proof_id, label="proof ID")
now = issued_at or datetime.now(tz=UTC)
now = _aware_utc(now, label="issuance time")
expiry = _aware_utc(expires_at, label="expiry time")
if now >= expiry:
raise ValueError("boundary evidence expiry must be after issuance")
assessment_id = assessment.get("assessment_id")
release = assessment.get("release")
assessment_release = release.get("ref") if isinstance(release, Mapping) else None
deployment = assessment.get("deployment_profile")
deployment_subject = (
deployment.get("id") if isinstance(deployment, Mapping) else None
)
_require_opaque_id(assessment_id, label="assessment ID")
_require_opaque_id(assessment_release, label="assessment release")
_require_opaque_id(deployment_subject, label="deployment subject")
if expected_external_provider_subject is not None:
_require_opaque_id(
expected_external_provider_subject,
label="external-provider subject",
)
normalized_claims = _normalize_claims(
claims=claims,
deployment_subject=str(deployment_subject),
expected_external_provider_subject=expected_external_provider_subject,
)
active_at_issue, issue_findings = _active_authority_keys(
authority_keyring=authority_keyring,
verification_time=now,
forbidden_public_keys=forbidden_authority_public_keys,
)
active_until_expiry, expiry_findings = _active_authority_keys(
authority_keyring=authority_keyring,
verification_time=expiry - timedelta(microseconds=1),
forbidden_public_keys=forbidden_authority_public_keys,
)
if issue_findings or expiry_findings:
raise ValueError(
"proof-authority keyring is malformed, reused, or not valid for the full proof interval"
)
if not signing_keys:
raise ValueError(
"at least one independently provisioned signing key is required"
)
covered_scopes: set[str] = set()
verified_signers: list[tuple[str, Ed25519PrivateKey]] = []
for key_id, private_key in sorted(signing_keys.items()):
_require_opaque_id(key_id, label="signing key ID")
if not isinstance(private_key, Ed25519PrivateKey):
raise ValueError("boundary signing keys must be Ed25519")
authority = active_at_issue.get(key_id)
authority_at_expiry = active_until_expiry.get(key_id)
public_bytes = private_key.public_key().public_bytes(
encoding=serialization.Encoding.Raw,
format=serialization.PublicFormat.Raw,
)
if (
authority is None
or authority_at_expiry is None
or authority[0] != public_bytes
or authority_at_expiry[0] != public_bytes
):
raise ValueError(
f"signing key {key_id!r} is not independently authorized for the full proof interval"
)
covered_scopes.update(authority[1])
verified_signers.append((key_id, private_key))
claim_scopes = {str(claim["scope"]) for claim in normalized_claims}
uncovered_scopes = sorted(claim_scopes - covered_scopes)
if uncovered_scopes:
raise ValueError(
"no supplied signing key is authorized for scopes: "
+ ", ".join(uncovered_scopes)
)
proof: dict[str, Any] = {
"$schema": "./capability-fit-boundary-evidence.schema.json",
"schema_version": "0.1.0",
"evidence_kind": "govoplan.capability-fit-boundary-proof",
"proof_id": proof_id,
"assessment_id": assessment_id,
"assessment_release": assessment_release,
"installed_evidence_sha256": canonical_sha256(installed_evidence),
"issued_at": _iso_datetime(now),
"expires_at": _iso_datetime(expiry),
"claims": normalized_claims,
}
signature_payload = canonical_bytes(proof)
proof["signatures"] = [
{
"algorithm": "ed25519",
"key_id": key_id,
"value": base64.b64encode(private_key.sign(signature_payload)).decode(
"ascii"
),
}
for key_id, private_key in verified_signers
]
return proof
def _normalize_claims(
*,
claims: Sequence[Mapping[str, Any]],
deployment_subject: str,
expected_external_provider_subject: str | None,
) -> list[dict[str, Any]]:
if not 1 <= len(claims) <= len(PROOF_REQUIREMENTS):
raise ValueError("boundary evidence requires between one and eight claims")
normalized: list[dict[str, Any]] = []
seen_scopes: set[str] = set()
total_bytes = 0
for claim in claims:
scope = str(claim.get("scope") or "")
if scope not in PROOF_REQUIREMENTS or scope in seen_scopes:
raise ValueError("boundary claim scopes must be known and unique")
seen_scopes.add(scope)
result = str(claim.get("result") or "")
if result not in {POSITIVE_RESULTS[scope], NEGATIVE_RESULTS[scope]}:
raise ValueError(f"boundary claim result is invalid for {scope!r}")
controls = _opaque_id_list(
claim.get("control_ids"),
label=f"{scope} control IDs",
maximum=256,
)
raw_artifacts = claim.get("artifacts")
if not isinstance(raw_artifacts, Sequence) or isinstance(
raw_artifacts, (str, bytes)
):
raise ValueError(f"{scope} artifacts must be a non-empty list")
if not 1 <= len(raw_artifacts) <= 256:
raise ValueError(f"{scope} must reference between one and 256 artifacts")
artifacts: list[dict[str, str]] = []
seen_artifacts: set[str] = set()
for artifact in raw_artifacts:
if not isinstance(artifact, Mapping):
raise ValueError(f"{scope} contains a malformed artifact")
artifact_id = artifact.get("artifact_id")
_require_opaque_id(artifact_id, label=f"{scope} artifact ID")
artifact_id = str(artifact_id)
if artifact_id in seen_artifacts:
raise ValueError(f"{scope} contains duplicate artifact IDs")
seen_artifacts.add(artifact_id)
raw_path = artifact.get("path")
if not isinstance(raw_path, (str, Path)) or not str(raw_path):
raise ValueError(f"{scope} artifact {artifact_id!r} has no file path")
try:
digest, size, changed = _bounded_file_sha256(
Path(raw_path), max_bytes=MAX_BOUNDARY_ARTIFACT_BYTES
)
except OSError as exc:
raise ValueError(
f"could not securely hash {scope} artifact {artifact_id!r}"
) from exc
if changed:
raise ValueError(
f"{scope} artifact {artifact_id!r} changed or exceeded the size limit while hashing"
)
total_bytes += size
if total_bytes > MAX_BOUNDARY_ARTIFACT_TOTAL_BYTES:
raise ValueError(
"boundary evidence artifacts exceed the total size limit"
)
artifacts.append({"artifact_id": artifact_id, "sha256": digest.hex()})
normalized.append(
{
"scope": scope,
"result": result,
"subject_id": (
expected_external_provider_subject
if scope == "external_providers"
else deployment_subject
),
"control_ids": controls,
"artifacts": artifacts,
}
)
if "external_providers" in seen_scopes and not expected_external_provider_subject:
raise ValueError(
"external-provider evidence requires its expected opaque subject ID"
)
return sorted(normalized, key=lambda item: str(item["scope"]))
def _opaque_id_list(value: object, *, label: str, maximum: int) -> list[str]:
if not isinstance(value, Sequence) or isinstance(value, (str, bytes)):
raise ValueError(f"{label} must be a non-empty list")
result = [str(item) for item in value]
if not 1 <= len(result) <= maximum or len(result) != len(set(result)):
raise ValueError(f"{label} must contain unique bounded IDs")
for item in result:
_require_opaque_id(item, label=label)
return result
def _require_opaque_id(value: object, *, label: str) -> None:
if (
not isinstance(value, str)
or len(value) > 160
or OPAQUE_ID_PATTERN.fullmatch(value) is None
):
raise ValueError(f"{label} must be a bounded opaque ID")
def _aware_utc(value: datetime, *, label: str) -> datetime:
if value.tzinfo is None:
raise ValueError(f"{label} must include a timezone")
return value.astimezone(UTC)
def _iso_datetime(value: datetime) -> str:
return value.astimezone(UTC).isoformat().replace("+00:00", "Z")
@@ -930,10 +930,7 @@ def build_report(
boundary_scope = (
boundary_review.proof_scope
if boundary_review is not None
else {
scope: {"checked": False, "valid": None}
for scope in PROOF_REQUIREMENTS
}
else {scope: {"checked": False, "valid": None} for scope in PROOF_REQUIREMENTS}
)
proof_scope = {
"assessment_schema": {"checked": True, "valid": schema_valid},
@@ -1002,6 +999,63 @@ def build_report(
}
def enforce_required_boundary_scopes(
report: dict[str, Any], *, required_scopes: Iterable[str]
) -> dict[str, Any]:
"""Turn missing or negative external proof into an admission blocker."""
requested = tuple(dict.fromkeys(sorted(required_scopes)))
unknown = sorted(set(requested) - set(PROOF_REQUIREMENTS))
if unknown:
raise ValueError("unknown boundary scopes: " + ", ".join(unknown))
proof_scope = report.get("proof_scope")
if not isinstance(proof_scope, dict):
raise ValueError("capability-fit report has no proof scope")
failed = tuple(
scope
for scope in requested
if not isinstance(proof_scope.get(scope), dict)
or proof_scope[scope].get("checked") is not True
or proof_scope[scope].get("valid") is not True
)
proof_scope["admission"] = {
"checked": True,
"valid": not failed,
"required_scopes": list(requested),
"failed_scopes": list(failed),
}
if not failed:
return report
findings = report.setdefault("findings", [])
existing = {
(item.get("code"), item.get("message"))
for item in findings
if isinstance(item, dict)
}
for scope in failed:
message = (
f"Admission requires current positive boundary evidence for {scope!r}."
)
if ("required_boundary_scope_unsatisfied", message) not in existing:
findings.append(
{
"severity": "blocker",
"code": "required_boundary_scope_unsatisfied",
"message": message,
"assessment_ids": ["assessment.external_proof"],
}
)
findings.sort(
key=lambda item: (
_severity_rank(str(item.get("severity") or "")),
str(item.get("code") or ""),
str(item.get("message") or ""),
)
)
report["status"] = "blocked"
return report
def render_review(report: dict[str, Any]) -> str:
proof_scope = report.get("proof_scope", {})
installed_scope = proof_scope.get("installed_artifacts", {})
@@ -1062,8 +1116,7 @@ def render_review(report: dict[str, Any]) -> str:
unchecked_boundaries = [
label
for key, label in (
(scope, scope.replace("_", "-"))
for scope in PROOF_REQUIREMENTS
(scope, scope.replace("_", "-")) for scope in PROOF_REQUIREMENTS
)
if report.get("proof_scope", {}).get(key, {}).get("checked") is not True
]