Ratchet
Ratchet is a tool for improving the security of CI/CD workflows by automating
the process of pinning and unpinning upstream versions. It's like Bundler,
Cargo, Go modules, NPM, Pip, or Yarn, but for CI/CD workflows. Ratchet supports:
- GitHub Actions
- Google Cloud Build
Problem statement
Most CI/CD systems are one layer of indirection away from curl | sudo bash
.
Unless you are specifically pinning CI workflows, containers, and base images to
checksummed versions, everything is mutable: GitHub labels are mutable and
Docker tags are mutable. This poses a substantial security and reliability risk.
What you're probably doing:
uses: 'actions/checkout@v3'
# or
image: 'ubuntu:20.04'
What you should really be doing:
uses: 'actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b'
# or
image: 'ubuntu@sha256:47f14534bda344d9fe6ffd6effb95eefe579f4be0d508b7445cf77f61a0e5724'
But resolving those checksums and managing the update lifecycle is extremely
toilsome. That's what ratchet aims to solve!
Usage
Pin to specific versions:
# pin the input file
./ratchet pin workflow.yml
# pin a cloudbuild file
./ratchet pin -parser cloudbuild cloudbuild.yml
# output to a different path
./ratchet pin -out workflow-compiled.yml workflow.yml
Unpin existing pinned versions:
# unpin the input file
./ratchet unpin workflow.yml
# output to a different path
./ratchet unpin -out workflow.yml workflow-compiled.yml
Update all versions to the latest matching constraint:
# update the input file
./ratchet update workflow.yml
# update a cloudbuild file
./ratchet update -parser cloudbuild cloudbuild.yml
# output to a different path
./ratchet pin -out workflow-compiled.yml workflow.yml
For more information, run a command with -help
to use detailed usage
instructions.
Installation
There are a few options for installing ratchet:
- As a single-static binary from the releases page.
- As a container image from the container registry.
- Compiled from source yourself. Note this option is not supported.
Auth
-
The container resolver uses default "keychain" auth, which looks for local
system auth, similar to the Docker and gcloud CLIs.
-
The GitHub resolver defaults to public github.com. Provide an oauth access
token with appropriate permissions via the ACTIONS_TOKEN
environment
variable. To use a GitHub Enterprise installation, set the
ACTIONS_BASE_URL
and ACTIONS_UPLOAD_URL
environment variables to point
your instance.
Terminology
-
Unpinned version - An unpinned version is a non-absolute reference to a
floating tag or label, such as actions/checkout@v3
or ubuntu:20.04
.
-
Pinned version - A pinned version is an absolute hashed reference, such
as actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
or
ubuntu@sha256:82becede498899ec668628e7cb0ad87b6e1c371cb8a1e597d83a47fac21d6af3
.
Known issues
-
Indentation is always set to 2 spaces. The upstream YAML library does not
capture pre-parsing indentation. Thus, all files will be saved with 2 spaces
for indentation.
-
Leading and trailing whitespace between nodes is not preserved. Similar
indentation, the upstream YAML library does not capture truly empty nodes.
Thus, blank lines may be removed between nodes. This will not affect
multi-line values.
-
Does not support resolving values in anchors or aliases. This is technically
possible, but most CI systems also don't support these advanced YAML
features.