Files
git.stella-ops.org/docs/features/unchecked/scanner/idempotent-attestation-submission.md

51 lines
3.9 KiB
Markdown

# Idempotent Attestation Submission
## Module
Scanner
## Status
IMPLEMENTED
## Description
Ensures that attestation submissions (verdict push to OCI registry, Rekor transparency log entries) are idempotent: resubmitting the same attestation produces no duplicate entries and returns the existing entry reference. Handles transient failures with retry logic that avoids creating duplicate transparency log entries.
## What's Implemented
- **Verdict Push Stage**:
- `src/Scanner/StellaOps.Scanner.Worker/Processing/VerdictPushStageExecutor.cs` - `VerdictPushStageExecutor` scan pipeline stage that pushes signed verdict attestations to the OCI registry and triggers downstream evidence publication
- **OCI Verdict Publishing**:
- `src/Scanner/__Libraries/StellaOps.Scanner.Storage.Oci/VerdictOciPublisher.cs` - `VerdictOciPublisher` publishing signed verdict DSSE envelopes to OCI registries as attestation artifacts
- **Rekor Integration**:
- `src/Attestor/__Libraries/StellaOps.Attestor.ProofChain/Rekor/EnhancedRekorProofBuilder.Build.cs` - Builds Rekor inclusion proofs for attestations
- `src/Attestor/__Libraries/StellaOps.Attestor.ProofChain/Rekor/EnhancedRekorProofBuilder.Validate.cs` - Validates Rekor inclusion proofs
- `src/Attestor/__Libraries/StellaOps.Attestor.ProofChain/Pipeline/RekorEntry.cs` - `RekorEntry` model for transparency log entries
- **Evidence Pipeline**:
- `src/Scanner/__Libraries/StellaOps.Scanner.Evidence/` - Evidence collection and bundling infrastructure
## What's Missing
- **Idempotency Key Generation**: No content-addressed idempotency key derived from attestation payload hash to detect duplicate submissions before sending to Rekor
- **Rekor Duplicate Detection**: No pre-submission check against Rekor search API to verify whether an attestation with the same content hash already exists in the log
- **Retry with Deduplication**: `VerdictPushStageExecutor` lacks explicit retry logic that distinguishes between "already submitted" (success) and "transient failure" (retry) responses from Rekor/OCI
- **OCI Tag Idempotency**: `VerdictOciPublisher` does not check for existing attestation tags before pushing, potentially creating duplicate OCI artifacts
- **Submission Receipt Cache**: No local cache of recently-submitted attestation hashes to short-circuit redundant submissions within the same scan session
## Implementation Plan
1. Add `AttestationIdempotencyKey` generation in `StellaOps.Scanner.Evidence` using SHA-256 of the canonical DSSE envelope payload
2. Add Rekor search-by-hash pre-check in `EnhancedRekorProofBuilder` before submitting new entries
3. Add retry policy to `VerdictPushStageExecutor` with idempotency-aware error classification (409 Conflict = success, 5xx = retry, 4xx = fail)
4. Add OCI manifest existence check in `VerdictOciPublisher` before pushing attestation artifacts
5. Add in-memory submission receipt cache with TTL for short-circuiting redundant submissions
6. Add unit tests for idempotency key generation, duplicate detection, and retry classification
## E2E Test Plan
- [ ] Submit a verdict attestation to Rekor and verify a log entry is created with correct content hash
- [ ] Resubmit the same attestation and verify no duplicate Rekor entry is created; the existing entry reference is returned
- [ ] Simulate a transient Rekor failure (503) during submission and verify the retry logic resubmits successfully without creating duplicates
- [ ] Push a verdict attestation to OCI and verify the artifact tag is created
- [ ] Re-push the same attestation to OCI and verify no duplicate artifact is created
- [ ] Verify the idempotency key is deterministically derived from the DSSE envelope payload (same payload = same key across scanner instances)
- [ ] Verify the submission receipt cache prevents redundant network calls for attestations submitted within the same scan session
## Related Documentation
- Source: See feature catalog
- Architecture: `docs/modules/scanner/architecture.md`