69 lines
2.0 KiB
Python
69 lines
2.0 KiB
Python
"""Evidence helpers."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import json
|
|
|
|
from .models import EvidenceEnvelope
|
|
from .store import TaskPlaneStore
|
|
|
|
|
|
def evidence_digest(payload: dict) -> str:
|
|
body = json.dumps(payload, sort_keys=True, separators=(",", ":"))
|
|
return hashlib.sha256(body.encode("utf-8")).hexdigest()
|
|
|
|
|
|
class EvidenceService:
|
|
def __init__(self, store: TaskPlaneStore):
|
|
self.store = store
|
|
|
|
def add(
|
|
self,
|
|
task_id: str,
|
|
kind: str,
|
|
payload: dict,
|
|
worker_identity: str,
|
|
*,
|
|
envelope: EvidenceEnvelope | None = None,
|
|
claim_id: str | None = None,
|
|
evidence_id: str | None = None,
|
|
created_at: float | None = None,
|
|
expires_at: float | None = None,
|
|
signature: str | None = None,
|
|
attestation_ref: str | None = None,
|
|
signature_algorithm: str | None = None,
|
|
signing_key_id: str | None = None,
|
|
verifier_identity: str | None = None,
|
|
authority_domain: str | None = None,
|
|
sequence: int | None = None,
|
|
) -> str:
|
|
return self.store.add_evidence(
|
|
task_id,
|
|
kind,
|
|
payload,
|
|
worker_identity,
|
|
envelope=envelope,
|
|
claim_id=claim_id,
|
|
evidence_id=evidence_id,
|
|
created_at=created_at,
|
|
expires_at=expires_at,
|
|
signature=signature,
|
|
attestation_ref=attestation_ref,
|
|
signature_algorithm=signature_algorithm,
|
|
signing_key_id=signing_key_id,
|
|
verifier_identity=verifier_identity,
|
|
authority_domain=authority_domain,
|
|
sequence=sequence,
|
|
)
|
|
|
|
def list(self, task_id: str) -> list[dict]:
|
|
return self.store.list_evidence(task_id)
|
|
|
|
def verify(self, task_id: str, required_kinds: list[str]) -> bool:
|
|
evidences = self.list(task_id)
|
|
observed = {e["kind"] for e in evidences}
|
|
return set(required_kinds).issubset(
|
|
observed
|
|
) and self.store.verify_evidence_integrity(task_id)
|