Skip to content

Add RUNNER_TOOL_CACHE support to cache cosign binaries - #238

Open
mikesir87 wants to merge 1 commit into
sigstore:mainfrom
mikesir87:add-tool-cache-support
Open

mikesir87 wants to merge 1 commit into
sigstore:mainfrom
mikesir87:add-tool-cache-support

Conversation

@mikesir87

Copy link
Copy Markdown

Summary

Resolves #183 by adding RUNNER_TOOL_CACHE support. There was a previous PR, so I leveraged both its changes and

Release Note

  • Adds RUNNER_TOOL_CACHE support support to cache and validate cosign binaries

Documentation

Good question. The cache does require an opt-in, so might be worth including in some documentation somewhere.

AI Disclaimer

I did use AI to help produce this PR, but did manually validate the changes.

Additionally, the agent provided the following description:


Summary

Adds a use-tool-cache input that caches the cosign binary in $RUNNER_TOOL_CACHE for reuse across runs. This is particularly useful for self-hosted runners with restricted or expensive network access, and for workshop/lab environments where the same binary is installed repeatedly.

What changed

action.yml

  • New use-tool-cache input (default: 'false'). When enabled, install-dir is ignored and the binary is stored at $RUNNER_TOOL_CACHE/cosign/<version>/<arch>/.
  • New cache-hit output — 'true' when the cached binary passed verification and the download was skipped.
  • On a cache hit, the cached binary's checksum is re-verified before use:
    • Bootstrap version (v3.0.6): compared against the hardcoded SHA embedded in the action itself, providing tamper-detection without any network access.
    • Other versions: compared against a cosign.sha256 sidecar file written to the cache directory during the original cryptographically-verified install. A mismatch triggers a full re-download and re-verification.
  • A cosign.sha256 sidecar is written after every successful verified install (bootstrap, custom, and go install paths).
  • Backwards-compatible: the default behaviour (install-dir: $HOME/.cosign, no caching) is unchanged.

README.md: Documents the new input and output.

test-action.yml: Two new CI jobs:

  • test_tool_cache — cross-platform (Linux, macOS, Windows); asserts cache-hit=false on first install and cache-hit=true on the second.
  • test_tool_cache_tamper_detection — installs cosign, overwrites the cached binary with garbage to simulate cache poisoning, re-runs the action, and asserts cache-hit=false (the tampered binary is rejected and cosign is re-downloaded and re-verified).

Security notes

The checksum stored in cosign.sha256 is derived from a cryptographically verified install (keyless/KMS signature via cosign verify-blob), so it reflects a known-good binary. A cache-poisoning attempt that replaces only the binary will be caught by the checksum mismatch and trigger a fresh download. Replacing both the binary and the sidecar file requires write access to $RUNNER_TOOL_CACHE; on GitHub-hosted runners each job gets a fresh VM, so this is not a concern. On self-hosted runners, administrators are assumed to control the cache directory — the same trust model used by all other GitHub Actions tool-cache integrations (e.g. actions/setup-go).

Signed-off-by: Michael Irwin <mikesir87@gmail.com>

Resolves sigstore#183

@cpanato cpanato left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems good
thanks

@bobcallaway would you mind to have a look as well?

@mikesir87

Copy link
Copy Markdown
Author

Happy to have helped out. Any updates on this?

@bobcallaway

Copy link
Copy Markdown
Member

Happy to have helped out. Any updates on this?

looking now

Comment thread action.yml
outputs:
cache-hit:
description: 'Whether cosign was found in the tool cache and installation was skipped (only meaningful when use-tool-cache is true)'
value: ${{ steps.installer.outputs.cache-hit }}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
value: ${{ steps.installer.outputs.cache-hit }}
value: ${{ steps.installer.outputs.cache-hit || 'false' }}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sets a default value

Comment thread action.yml
if [[ "${input_cosign_release}" == "${bootstrap_version}" ]] && [[ "${cached_sha}" == "${bootstrap_sha}" ]]; then
# Bootstrap version: compare against the hardcoded SHA embedded in this action
cache_valid=true
elif [[ -f "${cache_dir}/cosign.sha256" ]]; then

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if someone can change the binary they can also just change this so I'm not sure this check does much.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support RUNNER_TOOL_CACHE for caching the cosign binary

3 participants