From c63d0638b4957f1d3f27fee232b3befe0531072e Mon Sep 17 00:00:00 2001 From: Eric Seidel Date: Thu, 15 Oct 2026 16:46:27 -0700 Subject: [PATCH 1/5] docs: sign in to Shorebird from GitHub Actions with OIDC --- src/content/docs/code-push/ci/github.mdx | 77 ++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/src/content/docs/code-push/ci/github.mdx b/src/content/docs/code-push/ci/github.mdx index f676564e..bbe1b814 100644 --- a/src/content/docs/code-push/ci/github.mdx +++ b/src/content/docs/code-push/ci/github.mdx @@ -87,6 +87,83 @@ secret: Now the `SHOREBIRD_TOKEN` can be used in the GitHub workflow to perform authenticated functions such as creating patches 🎉 +## Sign in with OIDC instead of a stored key + +A workflow can sign in with the short-lived OIDC token GitHub issues to each +job, so no Shorebird secret is stored in GitHub and nothing has to be rotated. +The job signs in as a service account in your organization and can do what that +account's role allows. + +:::note + +Trust rules are available on Business and Enterprise plans. If your organization +moves to a plan without them, its existing trust rules keep working and can +still be deleted, but new ones cannot be added. + +::: + +### Add a trust rule + +1. In the [Shorebird Console](https://console.shorebird.dev), open your + organization's **Settings → Service accounts**. +2. Create a service account for the workflow, or pick an existing one. +3. Under **GitHub Actions**, click **Add workflow** and enter: + - **Owner** and **Repository**: where the workflow lives. + - **Workflow file**: the path of the workflow, such as + `.github/workflows/release.yaml`. + - **Environment** (recommended): the + [GitHub environment](https://docs.github.com/en/actions/managing-workflow-runs-and-deployments/managing-deployments/managing-environments-for-deployment) + the job runs in. Requiring one lets you add reviewers or branch + restrictions in GitHub before a release can run. + - **Ref pattern** (optional): the branches or tags allowed to sign in, such + as `refs/heads/main` or `refs/tags/*`. Leave it empty to accept any ref. + +The console then shows your project's ID, which the workflow needs. + +### Configure the workflow + +The job needs permission to request an OIDC token, the environment the rule +names (if any), and `SHOREBIRD_PROJECT_ID` set to your project's ID. The ID is +not a secret. + +```yaml +name: Shorebird Release + +on: + workflow_dispatch: + +jobs: + release: + runs-on: ubuntu-latest + environment: production # Only if your trust rule names an environment + permissions: + contents: read + id-token: write + env: + SHOREBIRD_PROJECT_ID: '123' # Your project's ID from the console + + steps: + - name: 📚 Git Checkout + uses: actions/checkout@v7 + + - name: 🐦 Setup Shorebird + uses: shorebirdtech/setup-shorebird@v1 + with: + cache: true + + - name: 🚀 Shorebird Release + run: shorebird release android +``` + +Do not set `SHOREBIRD_TOKEN` in a job that signs in with OIDC. When +`SHOREBIRD_TOKEN` is set, the Shorebird CLI uses it instead. If you are moving a +workflow from an API key to OIDC, remove the `SHOREBIRD_TOKEN` line and the +repository secret. + +If the sign-in is refused, the CLI prints the reason, such as +`no trust rule matches`. Check that the repository, workflow file, environment +and ref of the job match the trust rule. + ## Android code signing `shorebird release android` and `shorebird patch android` run `flutter build`, From dfa8dc3eeecde8d5dc5b8771967539fb7028c33a Mon Sep 17 00:00:00 2001 From: Abhishek Doshi Date: Fri, 16 Oct 2026 17:42:35 +0530 Subject: [PATCH 2/5] docs: OIDC version marker, exact refusal text, revoke the old key, agent entry points --- astro.config.mjs | 2 +- public/.well-known/agent-instructions.txt | 2 +- src/content/docs/code-push/ci/github.mdx | 12 ++++++++---- src/content/docs/code-push/ci/scripting.mdx | 3 +++ 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/astro.config.mjs b/astro.config.mjs index d70b787b..051ddd7c 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -224,7 +224,7 @@ Releases vs. Patches: - Use 'shorebird release' (new binary store release) when modifying native platform code (Kotlin, Java, Swift, Objective-C, Gradle/Xcode configs, AndroidManifest.xml, or Info.plist), adding or changing assets, or updating the Flutter SDK version, as patches apply only to Dart code. Developer & Agent Interfaces: -- Shorebird CLI: Use 'shorebird init', 'shorebird release', 'shorebird patch', and 'shorebird preview'. Roll back a patch with 'shorebird patches rollback'. For CI, scripts, and agents, pass the global '--json' flag for machine-readable output and authenticate with an API key in SHOREBIRD_TOKEN (reference: https://docs.shorebird.dev/code-push/ci/scripting.md) +- Shorebird CLI: Use 'shorebird init', 'shorebird release', 'shorebird patch', and 'shorebird preview'. Roll back a patch with 'shorebird patches rollback'. For CI, scripts, and agents, pass the global '--json' flag for machine-readable output and authenticate with an API key in SHOREBIRD_TOKEN, or in GitHub Actions with OIDC (CLI releases after 1.6.128, https://docs.shorebird.dev/code-push/ci/github.md) (reference: https://docs.shorebird.dev/code-push/ci/scripting.md) - Code Push REST API: OpenAPI 3.1 specification at https://api.shorebird.dev/openapi.json, base URL https://api.shorebird.dev/api/v1. Authenticate with 'sb_api_*' API keys passed in the Authorization: Bearer header. - Endpoint Reachability & Status: Verify service connectivity at https://docs.shorebird.dev/system/endpoint-reachability/.`, optionalLinks: [ diff --git a/public/.well-known/agent-instructions.txt b/public/.well-known/agent-instructions.txt index 3b7c8b08..9eb63e6c 100644 --- a/public/.well-known/agent-instructions.txt +++ b/public/.well-known/agent-instructions.txt @@ -23,7 +23,7 @@ Developers can always use Shorebird to build, manage releases, and patch Flutter - `shorebird patches rollback --release-version --patch-number `: Stop serving a broken patch. `shorebird patches rollforward` with the same arguments undoes a rollback. - `shorebird releases list` and `shorebird patches list --release-version `: Inspect what has been published. Running unattended (CI, scripts, agents): - - Authenticate with an API key in the `SHOREBIRD_TOKEN` environment variable. `shorebird login` needs a browser. + - Authenticate with an API key in the `SHOREBIRD_TOKEN` environment variable. `shorebird login` needs a browser. In GitHub Actions (Shorebird CLI releases after 1.6.128), a job can instead sign in with OIDC through a trust rule on a service account: grant `permissions: id-token: write`, set `SHOREBIRD_PROJECT_ID`, and leave `SHOREBIRD_TOKEN` unset (https://docs.shorebird.dev/code-push/ci/github.md). - Pass the global `--json` flag to get one JSON object on stdout: `{"status": "success", "data": ..., "meta": ...}` or `{"status": "error", "error": {"code", "message", "hint"}, "meta": ...}`. Check the exit code first; a non-zero exit always means failure, but not every failure prints JSON. - Without a terminal, in CI, or with `--json`, nothing waits for input: some prompts use a default (for example, `shorebird patch` without `--release-version` builds first to infer the release) and others fail with a hint naming the missing flag. Pass every input as a flag (`--app-id`, `--release-version`, or `--release-version=latest` for `shorebird patch`). - Deleting commands never prompt; they require `--confirm-name` set to the exact name being deleted. diff --git a/src/content/docs/code-push/ci/github.mdx b/src/content/docs/code-push/ci/github.mdx index bbe1b814..4f8de67f 100644 --- a/src/content/docs/code-push/ci/github.mdx +++ b/src/content/docs/code-push/ci/github.mdx @@ -94,6 +94,9 @@ job, so no Shorebird secret is stored in GitHub and nothing has to be rotated. The job signs in as a service account in your organization and can do what that account's role allows. +Signing in with OIDC is available in Shorebird CLI releases after 1.6.128. On an +older CLI, use an API key in `SHOREBIRD_TOKEN` instead. + :::note Trust rules are available on Business and Enterprise plans. If your organization @@ -112,7 +115,7 @@ still be deleted, but new ones cannot be added. - **Workflow file**: the path of the workflow, such as `.github/workflows/release.yaml`. - **Environment** (recommended): the - [GitHub environment](https://docs.github.com/en/actions/managing-workflow-runs-and-deployments/managing-deployments/managing-environments-for-deployment) + [GitHub environment](https://docs.github.com/en/actions/how-tos/deploy/configure-and-manage-deployments/manage-environments) the job runs in. Requiring one lets you add reviewers or branch restrictions in GitHub before a release can run. - **Ref pattern** (optional): the branches or tags allowed to sign in, such @@ -158,11 +161,12 @@ jobs: Do not set `SHOREBIRD_TOKEN` in a job that signs in with OIDC. When `SHOREBIRD_TOKEN` is set, the Shorebird CLI uses it instead. If you are moving a workflow from an API key to OIDC, remove the `SHOREBIRD_TOKEN` line and the -repository secret. +repository secret, then +[revoke the API key](/account/api-keys/#revoking-an-api-key). If the sign-in is refused, the CLI prints the reason, such as -`no trust rule matches`. Check that the repository, workflow file, environment -and ref of the job match the trust rule. +`No trust rule matches this workflow`. Check that the repository, workflow file, +environment and ref of the job match the trust rule. ## Android code signing diff --git a/src/content/docs/code-push/ci/scripting.mdx b/src/content/docs/code-push/ci/scripting.mdx index 45f22623..39a708ab 100644 --- a/src/content/docs/code-push/ci/scripting.mdx +++ b/src/content/docs/code-push/ci/scripting.mdx @@ -42,6 +42,9 @@ To keep a job from failing or guessing, pass every input as a flag: the app with `shorebird patch`, `--release-version=latest` targets the most recently updated release. Authenticate with an [API key](/account/api-keys) in the `SHOREBIRD_TOKEN` environment variable, since `shorebird login` needs a browser. +In GitHub Actions, a job can +[sign in with OIDC](/code-push/ci/github/#sign-in-with-oidc-instead-of-a-stored-key) +instead, in Shorebird CLI releases after 1.6.128. ## JSON output From 0265db7c2f4489567d890394400606fe628922a5 Mon Sep 17 00:00:00 2001 From: Abhishek Doshi Date: Fri, 16 Oct 2026 17:45:51 +0530 Subject: [PATCH 3/5] docs: trust rules match the workflow file that defines the job --- src/content/docs/code-push/ci/github.mdx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/content/docs/code-push/ci/github.mdx b/src/content/docs/code-push/ci/github.mdx index 4f8de67f..0940ddfc 100644 --- a/src/content/docs/code-push/ci/github.mdx +++ b/src/content/docs/code-push/ci/github.mdx @@ -112,8 +112,10 @@ still be deleted, but new ones cannot be added. 2. Create a service account for the workflow, or pick an existing one. 3. Under **GitHub Actions**, click **Add workflow** and enter: - **Owner** and **Repository**: where the workflow lives. - - **Workflow file**: the path of the workflow, such as - `.github/workflows/release.yaml`. + - **Workflow file**: the path of the workflow file that defines the job, such + as `.github/workflows/release.yaml`. If the job is in a reusable workflow, + enter that file, not the workflow that calls it. A reusable workflow from + another repository cannot sign in. - **Environment** (recommended): the [GitHub environment](https://docs.github.com/en/actions/how-tos/deploy/configure-and-manage-deployments/manage-environments) the job runs in. Requiring one lets you add reviewers or branch From c4f891eb455cebc20a4e99467c86eb41d04cc3bf Mon Sep 17 00:00:00 2001 From: Eric Seidel Date: Fri, 16 Oct 2026 07:47:30 -0700 Subject: [PATCH 4/5] docs: OIDC needs 1.6.129; reach service accounts by URL or shorebird api --- astro.config.mjs | 2 +- public/.well-known/agent-instructions.txt | 2 +- src/content/docs/code-push/ci/github.mdx | 29 +++++++++++++++++---- src/content/docs/code-push/ci/scripting.mdx | 2 +- 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/astro.config.mjs b/astro.config.mjs index 051ddd7c..854bb52a 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -224,7 +224,7 @@ Releases vs. Patches: - Use 'shorebird release' (new binary store release) when modifying native platform code (Kotlin, Java, Swift, Objective-C, Gradle/Xcode configs, AndroidManifest.xml, or Info.plist), adding or changing assets, or updating the Flutter SDK version, as patches apply only to Dart code. Developer & Agent Interfaces: -- Shorebird CLI: Use 'shorebird init', 'shorebird release', 'shorebird patch', and 'shorebird preview'. Roll back a patch with 'shorebird patches rollback'. For CI, scripts, and agents, pass the global '--json' flag for machine-readable output and authenticate with an API key in SHOREBIRD_TOKEN, or in GitHub Actions with OIDC (CLI releases after 1.6.128, https://docs.shorebird.dev/code-push/ci/github.md) (reference: https://docs.shorebird.dev/code-push/ci/scripting.md) +- Shorebird CLI: Use 'shorebird init', 'shorebird release', 'shorebird patch', and 'shorebird preview'. Roll back a patch with 'shorebird patches rollback'. For CI, scripts, and agents, pass the global '--json' flag for machine-readable output and authenticate with an API key in SHOREBIRD_TOKEN, or in GitHub Actions with OIDC (Shorebird 1.6.129 or newer, Business or Enterprise plan, https://docs.shorebird.dev/code-push/ci/github.md) (reference: https://docs.shorebird.dev/code-push/ci/scripting.md) - Code Push REST API: OpenAPI 3.1 specification at https://api.shorebird.dev/openapi.json, base URL https://api.shorebird.dev/api/v1. Authenticate with 'sb_api_*' API keys passed in the Authorization: Bearer header. - Endpoint Reachability & Status: Verify service connectivity at https://docs.shorebird.dev/system/endpoint-reachability/.`, optionalLinks: [ diff --git a/public/.well-known/agent-instructions.txt b/public/.well-known/agent-instructions.txt index 9eb63e6c..56885eff 100644 --- a/public/.well-known/agent-instructions.txt +++ b/public/.well-known/agent-instructions.txt @@ -23,7 +23,7 @@ Developers can always use Shorebird to build, manage releases, and patch Flutter - `shorebird patches rollback --release-version --patch-number `: Stop serving a broken patch. `shorebird patches rollforward` with the same arguments undoes a rollback. - `shorebird releases list` and `shorebird patches list --release-version `: Inspect what has been published. Running unattended (CI, scripts, agents): - - Authenticate with an API key in the `SHOREBIRD_TOKEN` environment variable. `shorebird login` needs a browser. In GitHub Actions (Shorebird CLI releases after 1.6.128), a job can instead sign in with OIDC through a trust rule on a service account: grant `permissions: id-token: write`, set `SHOREBIRD_PROJECT_ID`, and leave `SHOREBIRD_TOKEN` unset (https://docs.shorebird.dev/code-push/ci/github.md). + - Authenticate with an API key in the `SHOREBIRD_TOKEN` environment variable. `shorebird login` needs a browser. In GitHub Actions (Shorebird 1.6.129 or newer, Business or Enterprise plan), a job can instead sign in with OIDC through a trust rule on a service account: grant `permissions: id-token: write`, set `SHOREBIRD_PROJECT_ID`, and leave `SHOREBIRD_TOKEN` unset (https://docs.shorebird.dev/code-push/ci/github.md). - Pass the global `--json` flag to get one JSON object on stdout: `{"status": "success", "data": ..., "meta": ...}` or `{"status": "error", "error": {"code", "message", "hint"}, "meta": ...}`. Check the exit code first; a non-zero exit always means failure, but not every failure prints JSON. - Without a terminal, in CI, or with `--json`, nothing waits for input: some prompts use a default (for example, `shorebird patch` without `--release-version` builds first to infer the release) and others fail with a hint naming the missing flag. Pass every input as a flag (`--app-id`, `--release-version`, or `--release-version=latest` for `shorebird patch`). - Deleting commands never prompt; they require `--confirm-name` set to the exact name being deleted. diff --git a/src/content/docs/code-push/ci/github.mdx b/src/content/docs/code-push/ci/github.mdx index 0940ddfc..17749762 100644 --- a/src/content/docs/code-push/ci/github.mdx +++ b/src/content/docs/code-push/ci/github.mdx @@ -94,8 +94,8 @@ job, so no Shorebird secret is stored in GitHub and nothing has to be rotated. The job signs in as a service account in your organization and can do what that account's role allows. -Signing in with OIDC is available in Shorebird CLI releases after 1.6.128. On an -older CLI, use an API key in `SHOREBIRD_TOKEN` instead. +Signing in with OIDC needs Shorebird 1.6.129 or newer. On an older CLI, use an +API key in `SHOREBIRD_TOKEN` instead. :::note @@ -107,9 +107,13 @@ still be deleted, but new ones cannot be added. ### Add a trust rule -1. In the [Shorebird Console](https://console.shorebird.dev), open your - organization's **Settings → Service accounts**. -2. Create a service account for the workflow, or pick an existing one. +1. In the [Shorebird Console](https://console.shorebird.dev), go to + `/orgs//settings/service-accounts`, with your project's ID in + place of ``. The ID is the number after `/orgs/` in the console's + address bar, and `shorebird account orgs` lists it too. +2. Create a service account for the workflow, or pick an existing one. Its role + decides what the workflow can do: App manager can create releases and + patches. 3. Under **GitHub Actions**, click **Add workflow** and enter: - **Owner** and **Repository**: where the workflow lives. - **Workflow file**: the path of the workflow file that defines the job, such @@ -125,6 +129,21 @@ still be deleted, but new ones cannot be added. The console then shows your project's ID, which the workflow needs. +#### Add a trust rule from the command line + +`shorebird api` can make the same changes. Create the service account, then add +a trust rule to it with the `id` the first command prints: + +```sh +shorebird api -X POST organizations//service-accounts \ + -f name=release -f role=appManager +shorebird api -X POST organizations//service-accounts//trust-rules \ + -f provider=github -f repository_owner=acme -f repository_name=app \ + -f workflow_path=.github/workflows/release.yaml -f ref_pattern=refs/heads/main +``` + +`environment` and `ref_pattern` are optional, as in the console. + ### Configure the workflow The job needs permission to request an OIDC token, the environment the rule diff --git a/src/content/docs/code-push/ci/scripting.mdx b/src/content/docs/code-push/ci/scripting.mdx index 39a708ab..01804caf 100644 --- a/src/content/docs/code-push/ci/scripting.mdx +++ b/src/content/docs/code-push/ci/scripting.mdx @@ -44,7 +44,7 @@ release. Authenticate with an [API key](/account/api-keys) in the `SHOREBIRD_TOKEN` environment variable, since `shorebird login` needs a browser. In GitHub Actions, a job can [sign in with OIDC](/code-push/ci/github/#sign-in-with-oidc-instead-of-a-stored-key) -instead, in Shorebird CLI releases after 1.6.128. +instead, with Shorebird 1.6.129 or newer. ## JSON output From cea63d1da07e636bb93becd750c9358b621bb9d8 Mon Sep 17 00:00:00 2001 From: Eric Seidel Date: Fri, 16 Oct 2026 08:24:43 -0700 Subject: [PATCH 5/5] docs: full service accounts URL, who can manage them, and least-privilege role --- src/content/docs/code-push/ci/github.mdx | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/content/docs/code-push/ci/github.mdx b/src/content/docs/code-push/ci/github.mdx index 17749762..00884d85 100644 --- a/src/content/docs/code-push/ci/github.mdx +++ b/src/content/docs/code-push/ci/github.mdx @@ -107,13 +107,16 @@ still be deleted, but new ones cannot be added. ### Add a trust rule -1. In the [Shorebird Console](https://console.shorebird.dev), go to - `/orgs//settings/service-accounts`, with your project's ID in - place of ``. The ID is the number after `/orgs/` in the console's - address bar, and `shorebird account orgs` lists it too. +1. Open + `https://console.shorebird.dev/orgs//settings/service-accounts`, + with your project's ID in place of ``. The ID is the number after + `/orgs/` in the console's address bar, and `shorebird account orgs` lists it + too. You need the Admin or Owner role to manage service accounts. 2. Create a service account for the workflow, or pick an existing one. Its role - decides what the workflow can do: App manager can create releases and - patches. + decides what the workflow can do: Developer, the default, can create releases + and patches, and App manager can also create, update, and delete apps. + Creating an account in the console also creates an API key for it. A workflow + that signs in with OIDC doesn't use the key, so you can revoke it. 3. Under **GitHub Actions**, click **Add workflow** and enter: - **Owner** and **Repository**: where the workflow lives. - **Workflow file**: the path of the workflow file that defines the job, such @@ -136,7 +139,7 @@ a trust rule to it with the `id` the first command prints: ```sh shorebird api -X POST organizations//service-accounts \ - -f name=release -f role=appManager + -f name=release -f role=developer shorebird api -X POST organizations//service-accounts//trust-rules \ -f provider=github -f repository_owner=acme -f repository_name=app \ -f workflow_path=.github/workflows/release.yaml -f ref_pattern=refs/heads/main