Files
git.stella-ops.org/docs/modules/findings-ledger/prep/ledger-attestations-storage.md
master d519782a8f
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
prep docs and service updates
2025-11-21 06:56:36 +00:00

2.7 KiB

Ledger Attestations Storage & Query Contract (LEDGER-OBS-54-001)

Status: PrepComplete (2025-11-20) Owners: Findings Ledger Guild · Provenance Guild

Goal

Provide a deterministic storage/view contract so the /v1/ledger/attestations endpoint can be implemented without further design work.

Table (proposed)

  • Name: ledger_attestations
  • Partitioning: tenant-scoped (same strategy as ledger_events).
  • Columns:
    • tenant_id (text, not null)
    • attestation_id (uuid, not null)
    • artifact_id (text, not null) — OCI digest or SBOM id
    • finding_id (text, null)
    • verification_status (text, not null; verified|failed|unknown)
    • verification_time (timestamptz, not null)
    • dsse_digest (text, not null; lowercase sha256)
    • rekor_entry_id (text, null)
    • evidence_bundle_ref (text, null)
    • ledger_event_id (uuid, not null) — source ledger event linking the attestation
    • recorded_at (timestamptz, not null)
    • merkle_leaf_hash (text, not null)
    • root_hash (text, not null)
    • cycle_hash (text, not null)
    • projection_version (text, not null)

Indexes / ordering

  • PK: (tenant_id, attestation_id)
  • Paging index: (tenant_id, recorded_at, attestation_id) to back deterministic sort recorded_at ASC, attestation_id ASC.
  • Lookup indexes:
    • (tenant_id, artifact_id, recorded_at DESC)
    • (tenant_id, finding_id, recorded_at DESC)
    • (tenant_id, verification_status, recorded_at DESC)

Query contract for /v1/ledger/attestations

  • Filters map to indexed columns: artifactId, findingId, attestationId, status, sinceRecordedAt, untilRecordedAt.
  • Pagination token encodes { recordedAt, attestationId, filtersHash }; server must reject mismatched hash.
  • Response fields align 1:1 with columns above; no joins required.
  • Determinism: sort strictly by (recorded_at ASC, attestation_id ASC); no server clocks in payload.

Migration notes

  • Add table and indexes in the same migration (see src/Findings/StellaOps.Findings.Ledger/migrations/004_ledger_attestations.sql).
  • Backfill from existing provenance/verification store (if present) into this table with recorded_at = original verification timestamp.
  • Ensure writes/coalescing happen via ledger projections to keep ledger_event_id/cycle_hash consistent.

Observability

  • Logs: ledger.attestations.query (tenant, filtersHash, limit, duration_ms, result_count).
  • Metrics: ledger_attestations_queries_total{tenant,status}, ledger_attestations_failures_total{reason}; reuse endpoint spans already defined in prep doc.

Artefact location

  • Storage contract: docs/modules/findings-ledger/prep/ledger-attestations-storage.md
  • HTTP contract: docs/modules/findings-ledger/prep/ledger-attestations-http.md