mirror of
https://github.com/cargo-bins/cargo-binstall.git
synced 2025-04-20 12:38:43 +00:00
Sign our releases (#1347)
* Sign our releases * Use secrets instead of artifacts * And the universal * Apparently we can’t use secrets like that? * Minor fixes to doc * Private key requires untrusted comment * Dogfood one deeper
This commit is contained in:
parent
32beba507b
commit
ee7fcb3210
5 changed files with 88 additions and 14 deletions
16
.github/scripts/ephemeral-gen.sh
vendored
Executable file
16
.github/scripts/ephemeral-gen.sh
vendored
Executable file
|
@ -0,0 +1,16 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
cargo binstall -y rsign2
|
||||
rsign generate -f -W -p minisign.pub -s minisign.key
|
||||
|
||||
cat >> crates/bin/Cargo.toml <<EOF
|
||||
[package.metadata.binstall.signing]
|
||||
algorithm = "minisign"
|
||||
pubkey = "$(tail -n1 minisign.pub)"
|
||||
EOF
|
||||
|
||||
set +x
|
||||
echo "::add-mask::$(tail -n1 minisign.key)"
|
||||
echo "private=$(tail -n1 minisign.key)" >> "$GITHUB_OUTPUT"
|
19
.github/scripts/ephemeral-sign.sh
vendored
Executable file
19
.github/scripts/ephemeral-sign.sh
vendored
Executable file
|
@ -0,0 +1,19 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "untrusted comment: rsign encrypted secret key" > minisign.key
|
||||
cat >> minisign.key <<< "$SIGNING_KEY"
|
||||
|
||||
set -x
|
||||
|
||||
cargo binstall -y rsign2
|
||||
|
||||
ts=$(date --utc --iso-8601=seconds)
|
||||
git=$(git rev-parse HEAD)
|
||||
comment="gh=$GITHUB_REPOSITORY git=$git ts=$ts run=$GITHUB_RUN_ID"
|
||||
|
||||
for file in "$@"; do
|
||||
rsign sign -W -s minisign.key -x "$file.sig" -t "$comment" "$file"
|
||||
done
|
||||
|
20
.github/workflows/release-build.yml
vendored
20
.github/workflows/release-build.yml
vendored
|
@ -16,6 +16,10 @@ on:
|
|||
description: "Set to override default release profile codegen-units settings"
|
||||
required: false
|
||||
type: string
|
||||
secrets:
|
||||
signingkey:
|
||||
description: "Minisign private key. Required when publishing"
|
||||
required: false
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
@ -84,6 +88,14 @@ jobs:
|
|||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- if: inputs.publish
|
||||
uses: cargo-bins/cargo-binstall@main
|
||||
|
||||
- if: inputs.publish
|
||||
env:
|
||||
SIGNING_KEY: ${{ secrets.signingkey }}
|
||||
run: .github/scripts/ephemeral-sign.sh packages/cargo-binstall-*
|
||||
|
||||
- if: inputs.publish
|
||||
name: Upload to release
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
|
@ -140,6 +152,14 @@ jobs:
|
|||
- run: just repackage-lipo
|
||||
- run: ls -shal packages/
|
||||
|
||||
- if: inputs.publish
|
||||
uses: cargo-bins/cargo-binstall@main
|
||||
|
||||
- if: inputs.publish
|
||||
env:
|
||||
SIGNING_KEY: ${{ secrets.signingkey }}
|
||||
run: .github/scripts/ephemeral-sign.sh packages/cargo-binstall-universal-*
|
||||
|
||||
- if: inputs.publish
|
||||
name: Upload to release
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
|
|
39
.github/workflows/release.yml
vendored
39
.github/workflows/release.yml
vendored
|
@ -22,8 +22,8 @@ jobs:
|
|||
event-data: ${{ toJSON(github.event) }}
|
||||
extract-notes-under: '### Release notes'
|
||||
|
||||
tag:
|
||||
if: needs.info.outputs.is-release == 'true'
|
||||
libtag:
|
||||
if: needs.info.outputs.is-release == 'true' && needs.info.outputs.crate != 'cargo-binstall'
|
||||
needs: info
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
@ -35,24 +35,43 @@ jobs:
|
|||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
custom_tag: ${{ needs.info.outputs.version }}
|
||||
tag_prefix: ${{ needs.info.outputs.crate }}-v
|
||||
- name: Push cli release tag
|
||||
if: needs.info.outputs.crate == 'cargo-binstall'
|
||||
uses: mathieudutour/github-tag-action@v6.1
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
custom_tag: ${{ needs.info.outputs.version }}
|
||||
tag_prefix: v
|
||||
- name: Publish to crates.io
|
||||
run: |
|
||||
cargo publish -p '${{ needs.info.outputs.crate }}'
|
||||
env:
|
||||
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
|
||||
|
||||
clitag:
|
||||
if: needs.info.outputs.is-release == 'true' && needs.info.outputs.crate == 'cargo-binstall'
|
||||
needs: info
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Push cli release tag
|
||||
uses: mathieudutour/github-tag-action@v6.1
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
custom_tag: ${{ needs.info.outputs.version }}
|
||||
tag_prefix: v
|
||||
- uses: cargo-bins/cargo-binstall@main
|
||||
- name: Create ephemeral keypair
|
||||
id: keypair
|
||||
run: .github/scripts/ephemeral-gen.sh
|
||||
- name: Publish to crates.io
|
||||
env:
|
||||
crate: ${{ needs.info.outputs.crate }}
|
||||
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
|
||||
run: cargo publish -p "$crate"
|
||||
outputs:
|
||||
signingkey: ${{ steps.keypair.outputs.private }}
|
||||
|
||||
package:
|
||||
if: needs.info.outputs.is-release == 'true' && needs.info.outputs.crate == 'cargo-binstall'
|
||||
needs:
|
||||
- info
|
||||
- tag
|
||||
- clitag
|
||||
uses: ./.github/workflows/release-build.yml
|
||||
with:
|
||||
publish: ${{ toJSON(needs.info.outputs) }}
|
||||
secrets:
|
||||
signingkey: ${{ needs.clitag.signingkey }}
|
||||
|
|
|
@ -59,7 +59,7 @@ It may or may not include the untrusted comment; it's ignored by Binstall so we
|
|||
|
||||
## Just-in-time signing
|
||||
|
||||
To reduce the risk of a key being stolen, this scheme supports just-in-time signing.
|
||||
To reduce the risk of a key being stolen, this scheme supports just-in-time or "keyless" signing.
|
||||
The idea is to generate a keypair when releasing, use it for signing the packages, save the key in the Cargo.toml before publishing to a registry, and then discard the private key when it's done.
|
||||
That way, there's no key to steal nor to store securely, and every release is signed by a different key.
|
||||
And because crates.io is immutable, it's impossible to overwrite the key.
|
||||
|
@ -73,7 +73,7 @@ There is one caveat to keep in mind: with the scheme as described above, Binstal
|
|||
The solution here is either:
|
||||
|
||||
- Commit the Cargo.toml with the ephemeral public key to the repo when publishing.
|
||||
- Omit the `[...signing]` section in the source, and write the entire section on publish instead of just filling in the `pubkey`; signatures won't be checked for `--git` installs.
|
||||
- Omit the `[...signing]` section in the source, and write the entire section on publish instead of just filling in the `pubkey`; signatures won't be checked for `--git` installs. Binstall uses this approach.
|
||||
- Instruct your users to use `--skip-signatures` if they want to install with `--git`.
|
||||
|
||||
## Why not X? (Sigstore, GPG, signify, with SSH keys, ...)
|
||||
|
@ -84,10 +84,10 @@ We chose minisign as the first supported algorithm as it's lightweight, fairly p
|
|||
|
||||
## There's a competing project that does package signature verification differently!
|
||||
|
||||
[Tell use about it](https://github.com/cargo-bins/cargo-binstall/issues/1)!
|
||||
[Tell us about it](https://github.com/cargo-bins/cargo-binstall/issues/1)!
|
||||
We're not looking to fracture the ecosystem here, and will gladly implement support if something exists already.
|
||||
|
||||
We'll also work with others in the space to eventually formalise this beyond Binstall, for example around the `cargo-dist.json` metadata format.
|
||||
We'll also work with others in the space to eventually formalise this beyond Binstall, for example around the [`dist-manifest.json`](https://crates.io/crates/cargo-dist-schema) metadata format.
|
||||
|
||||
## What's the relationship to crate/registry signing?
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue