|
| 1 | +## Bottle Attestation & Build Provenance |
| 2 | + |
| 3 | +Homebrew supports cryptographic attestation of bottle artifacts using Sigstore and GitHub's artifact attestation infrastructure. This is an **infrastructure-level** feature — it applies to the CI/CD pipeline that builds bottles, not to individual formula files. |
| 4 | + |
| 5 | +### How It Works |
| 6 | + |
| 7 | +1. Bottles are built in CI (GitHub Actions) |
| 8 | +2. The build workflow generates a Sigstore-signed attestation linking the artifact to the source repo and workflow |
| 9 | +3. On `brew install`, Homebrew verifies the attestation before installing the bottle |
| 10 | +4. Verification uses `gh attestation verify` under the hood |
| 11 | + |
| 12 | +This achieves **SLSA Build L2** provenance — users can verify that a bottle was built from a specific commit by a specific workflow. |
| 13 | + |
| 14 | +### Homebrew Core Behavior |
| 15 | + |
| 16 | +- Homebrew 5.0+ verifies attestations by default for `homebrew-core` bottles |
| 17 | +- Controlled by `HOMEBREW_VERIFY_ATTESTATIONS=1` environment variable |
| 18 | +- Requires the `gh` CLI to be installed |
| 19 | +- Falls back to a backfill repository (`trailofbits/homebrew-brew-verify`) for bottles built before attestation was enabled |
| 20 | + |
| 21 | +### Setting Up Attestation for a Custom Tap |
| 22 | + |
| 23 | +To enable attestation verification for bottles in your own tap: |
| 24 | + |
| 25 | +#### 1. Add attestation to your bottle-building workflow |
| 26 | + |
| 27 | +```yaml |
| 28 | +# .github/workflows/bottles.yml |
| 29 | +permissions: |
| 30 | + id-token: write # Required for Sigstore signing |
| 31 | + attestations: write # Required to store attestations |
| 32 | + contents: read |
| 33 | + |
| 34 | +jobs: |
| 35 | + build-bottle: |
| 36 | + runs-on: macos-latest |
| 37 | + steps: |
| 38 | + - uses: actions/checkout@v4 |
| 39 | + |
| 40 | + - name: Build bottle |
| 41 | + run: | |
| 42 | + brew install --build-bottle myformula |
| 43 | + brew bottle myformula |
| 44 | +
|
| 45 | + - name: Attest bottle artifact |
| 46 | + uses: actions/attest-build-provenance@v3 |
| 47 | + with: |
| 48 | + subject-path: '*.bottle.tar.gz' |
| 49 | +``` |
| 50 | +
|
| 51 | +#### 2. Verify attestations locally |
| 52 | +
|
| 53 | +```bash |
| 54 | +# Verify a bottle artifact against the tap repo |
| 55 | +gh attestation verify myformula--1.0.0.arm64_sonoma.bottle.tar.gz \ |
| 56 | + --repo owner/homebrew-tap |
| 57 | +``` |
| 58 | + |
| 59 | +#### 3. Programmatic verification (Ruby API) |
| 60 | + |
| 61 | +Homebrew exposes `Homebrew::Attestation` for internal verification: |
| 62 | + |
| 63 | +| Method | Purpose | |
| 64 | +|--------|---------| |
| 65 | +| `check_attestation(bottle, signing_repo, signing_workflow)` | Verify a bottle against any repo's attestations | |
| 66 | +| `check_core_attestation(bottle)` | Verify against `Homebrew/homebrew-core` | |
| 67 | +| `enabled?` | Check if attestation verification is active | |
| 68 | + |
| 69 | +For third-party taps, `check_attestation` accepts any `signing_repo` — your tap's GitHub repo. |
| 70 | + |
| 71 | +### Key Requirements |
| 72 | + |
| 73 | +| Requirement | Details | |
| 74 | +|-------------|---------| |
| 75 | +| GitHub Actions | Attestations are generated via GitHub's infrastructure | |
| 76 | +| `gh` CLI | Required on the verifying machine | |
| 77 | +| Workflow permissions | `id-token: write` and `attestations: write` | |
| 78 | +| Sigstore | Used for signing — no key management needed | |
| 79 | +| Public repo | GitHub artifact attestations require public repositories (or GitHub Enterprise) | |
| 80 | + |
| 81 | +### What This Means for Formula Authors |
| 82 | + |
| 83 | +- **You don't need to do anything in the formula file** — attestation is handled by the bottle-building CI workflow |
| 84 | +- **SHA256 in the formula** still validates the source tarball — attestation validates the pre-built bottle |
| 85 | +- **HEAD-only formulas** don't use bottles, so attestation doesn't apply |
| 86 | + |
| 87 | +### References |
| 88 | + |
| 89 | +- [Homebrew Build Provenance (Trail of Bits)](https://blog.trailofbits.com/2024/05/14/a-peek-into-build-provenance-for-homebrew/) |
| 90 | +- [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) |
| 91 | +- [GitHub Artifact Attestations](https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations) |
0 commit comments