DSSE & Policy Hash Linkage (FL6)
Goal: Every export, replay report, and anchor manifest is tied to the exact policy digest that produced it and is verifiable offline via DSSE.
Binding rules
- Policy digest:
policyVersion(SHA-256 over policy bundle) is mandatory in ledger events, projections, exports, and replay reports. - DSSE payload types
application/vnd.stella-ledger-export+json— export manifests (hashlist + filtersHash).application/vnd.stella-ledger-anchor+json— Merkle anchors (seemerkle-anchor-policy.md).application/vnd.stella-ledger-harness+json— replay harness report.- Alert evidence bundle archives use media type
application/vnd.stellaops.findings.evidence-bundle.v1+tarinsidemanifest.json; their HTTP download remainsapplication/gzip.
- Hashlists: export manifests contain
sha256for each emitted NDJSON line (lineDigest), plus a dataset digest (datasetSha256) over concatenated line digests. Replay harness exposeseventStreamChecksumandprojectionChecksum. - Policy linkage: DSSE payload must include
policyHashandschemaVersionto prevent replay under mismatched policy versions.
Offline verification flow
- Verify DSSE signature (local key or Rekor transparency log if online).
- Recompute dataset checksum with
tools/LedgerReplayHarness/scripts/verify_export.py --input <export.ndjson> --expected <datasetSha256>. - Cross-check
policyHashin payload matches policy bundle in use; mismatch → block import/export. - For alert evidence bundles, recompute the gzip tar SHA-256 and compare it with
/v1/alerts/{alertId}/bundle/verify; when the alert id contains image path slashes, call/v1/alerts/bundle/verify?alert_id=<url-encoded-alert-id>instead. If a DSSEsignatureenvelope is supplied, the verifier requires the envelope payload to bind to the regenerated bundle hash and validates the signature against configured PEM trust roots (findings:ledger:evidenceBundles:dsseVerification:trustRootPathsortrustedPublicKeysPem). - Local-compose trust roots:
devops/compose/docker-compose.findings-dsse-dev.yml. The overlay was deleted atSPRINT_20260722_010FND-10 (it keyed the volume mount andfindings__ledger__EvidenceBundles__DsseVerification__TrustRootPaths__0to the retiredfindings-ledger-web) and re-created againstfindings-webat FND-21 on 2026-08-28. The section binds on the consolidated host:LedgerServiceOptions.SectionNameisfindings:ledger(src/Findings/StellaOps.Findings.Ledger/Options/LedgerServiceOptions.cs:8),findings-webbinds that section atsrc/Findings/StellaOps.Findings.WebService/Program.cs:163-171, and itsPostConfigureoverrides onlyDatabase.ConnectionString, so theEvidenceBundlessubtree survives the bind. The value is read atsrc/Findings/StellaOps.Findings.Ledger/Services/DsseEvidenceBundleSignatureVerifier.cs:59,69. PointFINDINGS_DSSE_TRUST_ROOT_DIRat a host directory of PEM public keys and layer the overlay on the live-flist (read it off the running container’scom.docker.compose.project.config_fileslabel). Verify the setting took effect by the error code, not by the container starting: without trust roots the verify endpoints answerfinding.evidence_bundle.trust_roots_required; with them the call proceeds to signature verification. Production trust roots are provisioned through the deployment’s normal config channel; this overlay is only a development shortcut.
File locations
- Harness DSSE placeholder now embeds
policyHashwhenLEDGER_POLICY_HASHenv var is set. - Export manifests and checksums:
docs/modules/findings/ledger/golden-checksums.json. - External anchors:
docs/modules/findings/ledger/merkle-anchor-policy.md(DSSE template). - Set
LEDGER_POLICY_HASHbefore runningtools/LedgerReplayHarnessto imprint the policy digest into the generated.sigfile.
Change management
- Any change to payloadType or hash recipe bumps schema version in
schema-catalog.mdand requires new DSSE key roll announcement.
