# Scanner Cache Key & DSSE Validation Contract Scope: unblocks SCAN-CACHE-186-013 by defining cache key inputs, validation, and storage layout. ## Cache key - Key components (concatenate with `|`, then SHA256): 1. `subject_digest` (image digest) 2. `manifest_hash` (replay manifest canonical hash) 3. `tool.id` + `tool.version` 4. `policy.hash` 5. feed hashes (sorted, joined with `;`) 6. determinism toggles (clock seed, rng seed, max_parallel) - Resulting cache key encoded as hex SHA256; used as folder name under CAS: `cache/{tenant}/{cache_key}/`. ## Stored entries - `sbom.cdx.json`, `vex.json`, `findings.ndjson`, `entropy.report.json` (when present). - `cache-manifest.json`: summary containing all key components, file hashes, created_at UTC. - `checksums.txt`: SHA256 for every file in folder. - Optional `cache-manifest.json.dsse`: DSSE envelope signed by replay signer profile; payload type `application/vnd.stellaops.cache-manifest+json`. ## Validation on hit 1. Recompute cache key from incoming request; must match folder name. 2. Recompute SHA256 over stored files and compare with `checksums.txt`. 3. If DSSE present, verify signature using replay trust root. 4. Compare `manifest_hash` in `cache-manifest.json` with current scan manifest. 5. Reject (miss) on any mismatch; log reason for determinism audit. ## Idempotency & TTL - Cache entries are immutable; if folder exists, compare manifests and return existing entry. - TTL controlled by policy; default 30 days; purge job removes expired entries by created_at. ## API notes - Worker -> WebService: `POST /api/v1/cache/{subjectDigest}` with bundle metadata; returns cache URI or 404 (miss). - WebService -> Worker: `GET /api/v1/cache/{subjectDigest}?cacheKey=...` returns cache-manifest + artifacts stream.