Verify cache archive digest before restore (#2) #7

Merged
stephen merged 1 commit from feat/2-verify-archive-digest into main 2026-06-16 23:50:40 +00:00
Owner

What changed

Caches restore from shared object storage with no integrity check, so a corrupted or poisoned object expands straight into the workspace/home cache paths (#2). Save now writes a sha256 sidecar (<archive>.sha256) beside each archive, and restore recomputes the downloaded archive's digest and compares it against the sidecar before extracting.

  • A digest mismatch fails closed: the restore aborts rather than extracting untrusted bytes.
  • An archive with no sidecar (saved before this change) restores with a warning by default; RASTER_CACHE_REQUIRE_DIGEST=true refuses unverified archives outright (missing-but-expected fails closed too).
  • A present-but-malformed sidecar is treated as a failed check, not a missing one.
  • The sidecar is filtered out of restore-key listings by the existing .tar.gz/.tar.zst extension check, so it is never matched as a cache entry.

How it was tested

  • make lint clean (actionlint/yq absent locally and skipped)
  • make test green (62 tests)
  • new behavior has a test: matching digest round-trips and verifies, a tampered archive is refused with nothing written, a missing sidecar restores with a warning by default and is refused under RASTER_CACHE_REQUIRE_DIGEST, plus unit coverage for the sidecar parser and that save writes a digest matching the archive bytes
  • e2e workflow green on a runner

CHANGELOG updated? yes

**What changed** Caches restore from shared object storage with no integrity check, so a corrupted or poisoned object expands straight into the workspace/home cache paths (#2). Save now writes a sha256 sidecar (`<archive>.sha256`) beside each archive, and restore recomputes the downloaded archive's digest and compares it against the sidecar before extracting. - A digest mismatch fails closed: the restore aborts rather than extracting untrusted bytes. - An archive with no sidecar (saved before this change) restores with a warning by default; `RASTER_CACHE_REQUIRE_DIGEST=true` refuses unverified archives outright (missing-but-expected fails closed too). - A present-but-malformed sidecar is treated as a failed check, not a missing one. - The sidecar is filtered out of restore-key listings by the existing `.tar.gz`/`.tar.zst` extension check, so it is never matched as a cache entry. **How it was tested** - [x] `make lint` clean (actionlint/yq absent locally and skipped) - [x] `make test` green (62 tests) - [x] new behavior has a test: matching digest round-trips and verifies, a tampered archive is refused with nothing written, a missing sidecar restores with a warning by default and is refused under `RASTER_CACHE_REQUIRE_DIGEST`, plus unit coverage for the sidecar parser and that save writes a digest matching the archive bytes - [ ] e2e workflow green on a runner **CHANGELOG updated?** yes
Verify cache archive digest before restore
All checks were successful
test / e2e (pull_request) Successful in 6s
test / unit (pull_request) Successful in 6s
test / e2e-post-save (pull_request) Successful in 5s
dd0214738f
Caches restore from shared object storage with no integrity check, so a
corrupted or poisoned object expands straight into the workspace. Save now
writes a sha256 sidecar (<archive>.sha256) beside each archive, and restore
recomputes the downloaded archive's digest and compares it before extracting.

A mismatch fails closed (the restore aborts rather than extracting untrusted
bytes). An archive with no sidecar (saved before this change) restores with a
warning by default; RASTER_CACHE_REQUIRE_DIGEST=true refuses unverified
archives outright. The sidecar is filtered out of restore-key listings by the
existing extension check, so it is never treated as a cache entry.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
rasterstate/cache-action!7
No description provided.