-
Notifications
You must be signed in to change notification settings - Fork 1
Verifying signed downloads (for v3.0.2) #21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
68a3c7e
d9b2dc1
c47b552
cbd9a2c
65a8624
046d3c9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,7 +9,7 @@ import { Aside } from "@astrojs/starlight/components"; | |
| ## Installation | ||
|
|
||
| <Tabs> | ||
| <TabItem label="macOS"> | ||
| <TabItem label="macOS / Linuxbrew"> | ||
| ```bash | ||
| brew install ahoy | ||
| ``` | ||
|
|
@@ -43,15 +43,17 @@ import { Aside } from "@astrojs/starlight/components"; | |
| ``` | ||
| </Aside> | ||
|
|
||
| Verify it's working: | ||
| For security's sake, please [verify your download](#verifying-your-download). | ||
|
|
||
| Then verify that `ahoy` is working: | ||
|
|
||
| ```bash | ||
| ahoy --version | ||
| ``` | ||
|
|
||
| ## Start with examples | ||
|
|
||
| The quickest way to get going is to initialise a project with our curated examples file. It includes 30+ ready-to-use commands for common development workflows. | ||
| The quickest way to get going is to initialise a project with our curated examples file. It includes 20+ ready-to-use commands for common development workflows. | ||
|
|
||
| ```bash | ||
| cd my-project | ||
|
|
@@ -105,6 +107,67 @@ ahoy # Shows all commands and their usage text | |
| in your project. | ||
| </Aside> | ||
|
|
||
| ## Verifying your download | ||
|
|
||
| Every release ships an `ahoy_<version>_checksums.txt` listing a SHA-256 for each | ||
| published file, so you can confirm a download arrived intact. | ||
|
|
||
| ```bash | ||
| VERSION=3.0.1 | ||
| BASE=https://github.com/ahoy-cli/ahoy/releases/download/v$VERSION | ||
|
|
||
| curl -fsSLO $BASE/ahoy-bin-linux-amd64 | ||
| curl -fsSLO $BASE/ahoy_${VERSION}_checksums.txt | ||
|
|
||
| sha256sum -c ahoy_${VERSION}_checksums.txt --ignore-missing | ||
| ``` | ||
|
|
||
| `--ignore-missing` checks only the files you actually downloaded, rather than | ||
| complaining about the thirty or so you did not. On macOS, use | ||
| `shasum -a 256 -c` in place of `sha256sum -c`. | ||
|
|
||
| <Aside type="note" title="Older releases"> | ||
| From v3.0.1 the checksums file covers the individual `ahoy-bin-*` binaries as | ||
| well as the `.tar.gz` and `.zip` archives. In v3.0.0 and earlier it listed only | ||
| the archives and SBOMs, so the binary the install command downloads could not | ||
| be verified. | ||
| </Aside> | ||
|
|
||
| ### Checking the signature | ||
|
|
||
| Checksums prove a file arrived intact, but not who produced it: anyone able to | ||
| replace a binary could replace the checksums file alongside it. Releases are | ||
| therefore signed with [cosign](https://docs.sigstore.dev/), and the signature | ||
| covers the checksums file, which in turn covers every other artifact. | ||
|
|
||
| Signing is keyless, so there is no public key to fetch. The signature records | ||
| the GitHub Actions workflow that built the release, and you assert which | ||
| identity you expect: | ||
|
|
||
| ```bash | ||
| VERSION=3.0.2 | ||
| BASE=https://github.com/ahoy-cli/ahoy/releases/download/v$VERSION | ||
|
|
||
| curl -fsSLO $BASE/ahoy_${VERSION}_checksums.txt | ||
| curl -fsSLO $BASE/ahoy_${VERSION}_checksums.txt.bundle | ||
|
|
||
| cosign verify-blob ahoy_${VERSION}_checksums.txt \ | ||
| --bundle ahoy_${VERSION}_checksums.txt.bundle \ | ||
| --certificate-identity-regexp '^https://github.com/ahoy-cli/ahoy/\.github/workflows/release\.yml@' \ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: #!/bin/bash
set -euo pipefail
version=3.0.2
base="https://github.com/ahoy-cli/ahoy/releases/download/v${version}"
workdir="$(mktemp -d)"
trap 'rm -rf "$workdir"' EXIT
cd "$workdir"
curl -fsSLO "${base}/ahoy_${version}_checksums.txt"
curl -fsSLO "${base}/ahoy_${version}_checksums.txt.bundle"
cosign verify-blob "ahoy_${version}_checksums.txt" \
--bundle "ahoy_${version}_checksums.txt.bundle" \
--certificate-identity "https://github.com/ahoy-cli/ahoy/.github/workflows/release.yml@refs/tags/v${version}" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"Repository: ahoy-cli/ahoy-cli.github.io Length of output: 216 🏁 Script executed: #!/bin/bash
set -euo pipefail
file="src/content/docs/guides/getting-started.mdx"
sed -n '140,170p' "$file"
printf '\n--- relevant repository references ---\n'
rg -n --glob '!node_modules' --glob '!dist' 'certificate-identity-regexp|certificate-identity|checksums|ahoy-bin-linux-amd64|release\.yml|VERSION' "$file" README.md .github 2>/dev/null || trueRepository: ahoy-cli/ahoy-cli.github.io Length of output: 3676 🌐 Web query:
💡 Result: The --certificate-identity-regexp flag in cosign is used as a regular expression alternative to --certificate-identity for validating the identity of a signer in keyless flows [1][2]. When using GitHub Actions with OIDC, the certificate identity typically takes the form of a URI identifying the workflow that performed the signing [3][4][5]. The standard format for this identity is: https://github.com/ORG/REPO/.github/workflows/WORKFLOW.yml@refs/tags/TAG_OR_BRANCH_NAME [4][6][5]. Usage of --certificate-identity-regexp: 1. Flexibility: It is useful when you need to match a pattern rather than an exact string [4]. For example, when you want to allow signatures from a workflow across multiple versions (e.g., semantic versions) or various branches [4]. 2. Security Warning: A naive regular expression like.* is insecure because it would allow signatures from any GitHub Action workflow, effectively rendering the identity check useless [7][4]. 3. Recommended Pattern: For a release workflow, you might use a pattern like ^https://github.com/ORG/REPO/.github/workflows/release\.yml@refs/tags/v[0-9]+\.[0-9]+\.[0-9]+$ to restrict signatures to specific semantic version tags [4]. 4. Syntax: It accepts Go regular expression syntax (RE2) [1][2]. Important Considerations: - Mandatory Checks: When verifying keyless signatures, you must provide either --certificate-identity or --certificate-identity-regexp [1][2]. Additionally, you must provide the corresponding OIDC issuer (e.g., --certificate-oidc-issuer=https://token.actions.githubusercontent.com) to ensure the certificate was issued by the expected authority [3][8][4]. - Granular Verification: For more advanced scenarios involving reusable workflows, simply matching the workflow identity may not be enough. You can also use flags like --certificate-github-workflow-repository and --certificate-github-workflow-ref to verify the caller's repository and specific git ref, which are claims embedded in the Fulcio certificate [4][2][9]. Citations:
🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- upstream release workflow ---'
curl -fsSL https://raw.githubusercontent.com/ahoy-cli/ahoy/main/.github/workflows/release.yml |
sed -n '1,220p'
printf '%s\n' '--- release tag workflow file, if available ---'
curl -fsSL https://raw.githubusercontent.com/ahoy-cli/ahoy/v3.0.2/.github/workflows/release.yml |
sed -n '1,220p'Repository: ahoy-cli/ahoy-cli.github.io Length of output: 250 Bind the signer identity to the requested release tag. This 🤖 Prompt for AI Agents |
||
| --certificate-oidc-issuer https://token.actions.githubusercontent.com | ||
| ``` | ||
|
|
||
| `Verified OK` means the checksums file was produced by Ahoy's own release | ||
| workflow. Check the artifacts against it as above, and the whole download is | ||
| accounted for. | ||
|
|
||
| <Aside type="caution" title="Requires v3.0.2"> | ||
| Signatures are published from v3.0.2 onwards. Earlier releases have checksums | ||
| but no `.bundle` file. Note also that cosign v3 replaced the older | ||
| `--output-signature` and `--output-certificate` flags with `--bundle`, so | ||
| examples written for cosign v2 will not work. | ||
| </Aside> | ||
|
|
||
| ## Next steps | ||
|
|
||
| - [Writing Commands](/guides/writing-commands) - practical patterns and real-world examples | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Verify the artefact that the installation flow installs.
The Linux command installs
/usr/local/bin/ahoy. The checksum example downloads and verifies a separate v3.0.1 binary in the current directory. A successful check can therefore leave the installed binary unverified.For manual downloads, download, verify, and install the same versioned file in one flow. Give Homebrew a separate trust statement instead of implying that this section verifies its installed package.
Also applies to: 116-120
🤖 Prompt for AI Agents