From c64173a7a74b5b84e4abb2e6fb3c4451a9d7540f Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Tue, 29 Sep 2026 10:36:33 -0700 Subject: [PATCH] Use a crates.io API token for the release workflow Trusted Publishing requires a one-time OIDC setup on the crates.io crate settings, which is more ceremony than is warranted right now. Switch to a CARGO_REGISTRY_TOKEN secret, which only needs to be pasted into the repository settings. - Publish using the CARGO_REGISTRY_TOKEN secret instead of obtaining a short-lived token via rust-lang/crates-io-auth-action. - Drop the now-unneeded id-token: write permission. - Fail fast when the secret is missing, rather than after the ~230 MB model download and full test run. - Document the token setup, and keep Trusted Publishing documented as the alternative for whenever we want to stop storing a long-lived credential. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/workflows/rust-release.yml | 23 +++++++++++-------- rust/RELEASING.md | 37 ++++++++++++++++++------------ 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/.github/workflows/rust-release.yml b/.github/workflows/rust-release.yml index 2f9a857..53b61f8 100644 --- a/.github/workflows/rust-release.yml +++ b/.github/workflows/rust-release.yml @@ -10,8 +10,8 @@ name: Rust release # You can also run it manually from the Actions tab; use `dry_run: true` to # rehearse everything except the actual `cargo publish`. # -# Authentication uses crates.io Trusted Publishing (OIDC) — no API token is -# stored in this repository. See rust/RELEASING.md for the one-time setup. +# Authentication uses a crates.io API token stored as the repository secret +# `CARGO_REGISTRY_TOKEN`. See rust/RELEASING.md for the one-time setup. on: push: @@ -42,10 +42,20 @@ jobs: environment: crates-io permissions: contents: write - id-token: write steps: - uses: actions/checkout@v4 + - name: Check publish credentials are configured + if: inputs.dry_run != true + run: | + if [ -z "${CARGO_REGISTRY_TOKEN:-}" ]; then + echo "::error::The CARGO_REGISTRY_TOKEN secret is not set on the crates-io environment. See rust/RELEASING.md." + exit 1 + fi + echo "Publish credentials are present." + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 @@ -100,16 +110,11 @@ jobs: - name: Package run: cargo publish --dry-run --locked - - name: Authenticate to crates.io - if: inputs.dry_run != true - uses: rust-lang/crates-io-auth-action@v1 - id: auth - - name: Publish if: inputs.dry_run != true run: cargo publish --locked env: - CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }} + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} - name: Create GitHub release if: github.ref_type == 'tag' && inputs.dry_run != true diff --git a/rust/RELEASING.md b/rust/RELEASING.md index d8e62e0..44255f3 100644 --- a/rust/RELEASING.md +++ b/rust/RELEASING.md @@ -41,21 +41,28 @@ with `dry_run` left enabled. ### One-time crates.io setup -The release workflow authenticates with -[Trusted Publishing](https://crates.io/docs/trusted-publishing), so no API -token is stored in this repository. An owner of the `trustmark` crate must -configure it once, under **Settings → Trusted Publishing** on the crate page: - -| Field | Value | -| -------------- | -------------------- | -| Repository | `adobe/trustmark` | -| Workflow file | `rust-release.yml` | -| Environment | `crates-io` | - -If you would rather use a long-lived token, add it as a repository secret -named `CARGO_REGISTRY_TOKEN` and replace the "Authenticate to crates.io" step -in the release workflow with that secret. Trusted Publishing is preferred -because the credential is short-lived and scoped to this one workflow. +The release workflow authenticates with a crates.io API token. + +1. On [crates.io](https://crates.io/settings/tokens), signed in as an account + that is an owner of the `trustmark` crate, create a new API token. Scope it + to `publish-update` and, if the option is offered, restrict it to the + `trustmark` crate so it cannot publish anything else. +2. In this repository, go to **Settings → Environments** and create an + environment named `crates-io`. The release workflow references this + environment, which is what lets you require a reviewer before any publish + actually runs. +3. Add the token as a secret named `CARGO_REGISTRY_TOKEN` on that environment + (**not** as a plain repository secret — an environment secret is only + exposed to jobs that opt into the environment). + +Rotate the token if it is ever exposed; revoking it on crates.io immediately +invalidates it. + +If you would prefer not to store a long-lived credential, crates.io also +supports [Trusted Publishing](https://crates.io/docs/trusted-publishing), which +issues a short-lived token over OIDC. That requires adding `id-token: write` +to the release job's permissions and swapping the publish step for the +`rust-lang/crates-io-auth-action` action. ## Manual release