Repository navigation
docs: sign in to Shorebird from GitHub Actions with OIDC - #725
Conversation
AbhishekDoshi26
left a comment
There was a problem hiding this comment.
Verdict: changes requested. The plan gating, matching rules, console flow and CLI precedence are all accurate against source. Five findings are below: a misquoted error string, no CLI version requirement, agent entry points not updated, a missing key-revocation step, and a link that redirects.
Reviewed at c63d063.
Checked
- Dependency state: _shorebird#3529, #3530, #3531 and #3532 and shorebird#4084 are all merged. CLI
version.darton shorebird main is still 1.6.128, so OIDC sign-in is not in a released CLI yet. The Service accounts settings tab still has no nav link inweb/apps/console/app/routes/orgs.$id.settings.tsx. The description declares this, so it is not a finding. - Plan gating:
oidcFederationis in_businessFeatures, which_enterpriseFeaturesinherits (packages/code_push_server/lib/src/capabilities/plan_feature.dart).- Adding a rule returns 403
shorebird_plan_insufficient_tierwithout that feature. Listing, deleting and exchanging do not check the plan (routes/.../trust-rules/index.dart; header ofweb/apps/auth/app/services/federated-exchange.server.ts, "a rule that exists keeps working after a downgrade"). - The console shows the Add button only when the plan has the feature, and keeps existing rules listed and deletable (
web/apps/console/app/components/service-accounts/trust-rules.tsx). - The note on lines 99-101 is accurate. This is a pricing fact, not internal gating.
- Console UI (
trust-rules.tsx):- The GitHub Actions heading and the Add workflow button exist.
- The fields are Owner, Repository, Workflow file, "Environment (recommended)" and "Ref pattern (optional)". The ref hint reads "e.g. refs/heads/main or refs/tags/*. Empty accepts any ref."
- The "Workflow trusted" view shows
SHOREBIRD_PROJECT_ID: {projectId},permissions: id-token: write, the environment line, and "No SHOREBIRD_TOKEN". It links tohttps://docs.shorebird.dev/code-push/ci/github/. - "Create service account" exists (
service-accounts.tsx).
- Matching (
083_add_oidc_trust_rule_table_migration.dart,match_github_oidc_trust_rules):- A null environment or ref pattern matches anything.
- A ref pattern is either an exact ref or a prefix ending in
*, sorefs/heads/mainandrefs/tags/*are valid examples. - The environment is compared without regard to case.
- Role and scope: the issued token carries no scope and acts with the service account's role (
federated-exchange.server.ts). - CLI (shorebird origin/main):
SHOREBIRD_TOKENtakes priority, and OIDC is not built when an API key is set (auth.dart, about lines 628-641).- OIDC needs
ACTIONS_ID_TOKEN_REQUEST_URL/_TOKEN(set byid-token: write) andSHOREBIRD_PROJECT_IDmatching^[0-9]+$after trimming, so the example's'123'is valid (github_actions_oidc.dart,oidc_credential_source.dart). - When the server refuses, the CLI prints "The Shorebird auth service refused to sign in with GitHub Actions OIDC (invalid_grant: )."
- Repo checks: no em-dashes in added lines. Prettier, cspell and vale all pass on
src/content/docs/code-push/ci/github.mdx.actions/checkout@v7andsetup-shorebird@v1match the rest of the page.
Findings
-
src/content/docs/code-push/ci/github.mdx:163-164: the refusal reason is misquoted.- Problem: the page shows
no trust rule matchesas the text the CLI prints. That string does not exist. - Evidence: the auth service returns
oauthError('invalid_grant', 'No trust rule matches this workflow')(web/apps/auth/app/services/federated-exchange.server.ts). The CLI prints it as... OIDC (invalid_grant: No trust rule matches this workflow).(oidc_credential_source.dart,_exchangeIdToken). A reader searching their log for the quoted text will not find it. - Fix: replace the sentence with:
If the sign-in is refused, the CLI prints the reason, such as
No trust rule matches this workflow. Check that the repository, workflow file, environment and ref of the job match the trust rule.
- Problem: the page shows
-
src/content/docs/code-push/ci/github.mdx:90-97: no CLI version requirement.- Problem: OIDC sign-in comes from shorebird#4084, which is not in v1.6.128, the latest release. On an older CLI the section does nothing and the job fails as unauthenticated. Other pages state the minimum CLI version for new features (for example
code-push/tracks.mdx:134,code-push/initialize.mdx:94). - Fix: add after the first paragraph of the section:
Signing in with OIDC is available in Shorebird CLI releases after 1.6.128. On an older CLI, use an API key in
SHOREBIRD_TOKENinstead.
- Problem: OIDC sign-in comes from shorebird#4084, which is not in v1.6.128, the latest release. On an older CLI the section does nothing and the job fails as unauthenticated. Other pages state the minimum CLI version for new features (for example
-
public/.well-known/agent-instructions.txt:26,astro.config.mjs:227andsrc/content/docs/code-push/ci/scripting.mdx:43-44: agent entry points not updated for the new CI sign-in workflow.- Problem: all three still say unattended runs authenticate only with an API key in
SHOREBIRD_TOKEN. The PR adds a second CI sign-in method with a new variable,SHOREBIRD_PROJECT_ID.scripting.mdis the "Full reference" the agent instructions and thecli-scriptingskill point to. - Fix for
agent-instructions.txt:26:- Authenticate with an API key in the
SHOREBIRD_TOKENenvironment variable.shorebird loginneeds a browser. In GitHub Actions, a job can instead sign in with OIDC through a trust rule on a service account: grantpermissions: id-token: write, setSHOREBIRD_PROJECT_ID, and leaveSHOREBIRD_TOKENunset (https://docs.shorebird.dev/code-push/ci/github.md).
- Authenticate with an API key in the
- Fix for
astro.config.mjs:227: change "authenticate with an API key in SHOREBIRD_TOKEN" to "authenticate with an API key in SHOREBIRD_TOKEN, or in GitHub Actions with OIDC (https://docs.shorebird.dev/code-push/ci/github.md)". - Fix for
scripting.mdx: after "sinceshorebird loginneeds a browser.", add:In GitHub Actions, a job can sign in with OIDC instead.
- If notes 1 and 2 above go in, include the same version marker in each.
- Problem: all three still say unattended runs authenticate only with an API key in
-
src/content/docs/code-push/ci/github.mdx:159-161: the migration step does not revoke the old key.-
Problem: deleting the repository secret does not stop the key working. It stays valid until it expires, which undercuts the section's point that nothing is stored or needs rotating. The console also tells users to revoke keys once a trust rule is in use ("Revoke this account's keys that nothing uses anymore.",
trust-rules.tsx). -
Fix:
If you are moving a workflow from an API key to OIDC, remove the
SHOREBIRD_TOKENline and the repository secret, then revoke the API key.The anchor comes from the
## Revoking an API keyheading inaccount/api-keys.mdx.
-
-
src/content/docs/code-push/ci/github.mdx:115: the GitHub environments link redirects.- Problem:
https://docs.github.com/en/actions/managing-workflow-runs-and-deployments/managing-deployments/managing-environments-for-deploymentreturns a redirect, not the page itself. - Evidence:
curl -ILends athttps://docs.github.com/en/actions/how-tos/deploy/configure-and-manage-deployments/manage-environments(200). - Fix: link to
https://docs.github.com/en/actions/how-tos/deploy/configure-and-manage-deployments/manage-environmentsdirectly.
- Problem:
AbhishekDoshi26
left a comment
There was a problem hiding this comment.
Reviewed at dfa8dc3.
Verdict: one finding left, about reusable workflows. All five findings from the previous round are fixed correctly, and everything else checks out against source.
Checked
- Previous findings: the refusal text matches
oauthError('invalid_grant', 'No trust rule matches this workflow')inweb/apps/auth/app/services/federated-exchange.server.ts. The "after 1.6.128" marker is present (CLIversion.darton main is still 1.6.128). The agent entry points are updated, the migration step revokes the old key (#revoking-an-api-keyresolves), and the GitHub environments link returns 200 with no redirect. - Dependencies: _shorebird#3529, #3530, #3531 and #3532 and shorebird#4084 are all merged.
- CLI:
SHOREBIRD_TOKENtakes priority over OIDC (auth.dart). OIDC needsACTIONS_ID_TOKEN_REQUEST_URLandACTIONS_ID_TOKEN_REQUEST_TOKEN, whichpermissions: id-token: writeprovides (github_actions_oidc.dart).SHOREBIRD_PROJECT_IDmust be numeric, so'123'is valid (oidc_credential_source.dart). - Console (
trust-rules.tsx,service-accounts.tsx,routes/orgs.$id.settings.service-accounts.tsx): the labels match the page (Service accounts, GitHub Actions, Add workflow, Owner, Repository, Workflow file, "Environment (recommended)", "Ref pattern (optional)"), and the project ID appears in the "Workflow trusted" view. - Server validation (
service_account_trust_rules.dart): the workflow path must be under.github/workflows/and end in.ymlor.yaml. The ref pattern acceptsrefs/heads/mainandrefs/tags/*, and an empty environment or ref accepts anything. - Plan gating:
oidcFederationis a Business feature that Enterprise inherits. Only adding a rule checks the plan, so the downgrade note is accurate. - Repo checks: no em-dashes. Prettier, cspell and vale are clean on the changed text, and the new anchor resolves.
Findings
src/content/docs/code-push/ci/github.mdx:115-116: the Workflow file field is wrong for reusable workflows.- Problem: the page says to enter "the path of the workflow". The auth service matches the file that defines the job, not the workflow that was triggered. If the release job lives in a reusable workflow, a rule naming the caller never matches, and the CLI only prints
No trust rule matches this workflow. A reusable workflow from another repository is refused outright. - Evidence:
web/apps/auth/app/services/oidc-providers.server.tsreads the path from thejob_workflow_refclaim ("For a job that calls a reusable workflow, that is the called workflow") and refuses a workflow from another repository ("trust rules match only workflows in the repository that runs them"). - Fix: "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."
- Problem: the page says to enter "the path of the workflow". The auth service matches the file that defines the job, not the workflow that was triggered. If the release job lives in a reusable workflow, a rule naming the caller never matches, and the CLI only prints
AbhishekDoshi26
left a comment
There was a problem hiding this comment.
Reviewed at 0265db7.
Verdict: clean, no findings. The fixes from both earlier rounds are in place, and every claim checks out against source. Content is ready; the merge still follows the conditions in the description (console Service accounts tab visible and a CLI release with shorebird#4084).
Checked
- Scope. The exchanged token carries no scope of its own and acts with the service account's role (
federated-exchange.server.ts). Nothing is stored: the job trades GitHub's per-job OIDC token for a short-lived access token. - Plan note.
oidcFederationis a Business feature that Enterprise inherits (plan_feature.dart). The exchange never reads the plan, and the console shows Add workflow only when the plan has the feature while keeping existing rules listed and deletable (trust-rules.tsx). - Console flow. Service accounts under org settings, Create service account, the GitHub Actions heading, Add workflow, and the fields Owner, Repository, Workflow file, "Environment (recommended)" and "Ref pattern (optional)" all match. The "Workflow trusted" dialog shows
SHOREBIRD_PROJECT_ID. - Workflow file. The server accepts
^\.github/workflows/[A-Za-z0-9._-]+\.ya?ml$.oidc-providers.server.tsmatches onjob_workflow_ref(the called file for a reusable workflow) and refuses a workflow from another repository, as the page now says. - Ref pattern.
^refs/(?:[^*\s]+\*?|\*)$accepts both examples, and an empty pattern accepts any ref. - CLI. An API key in
SHOREBIRD_TOKENtakes priority (auth.dart). OIDC needs theACTIONS_ID_TOKEN_REQUEST_*variables thatpermissions: id-token: writeprovides.SHOREBIRD_PROJECT_IDmust be numeric.version.dartis still 1.6.128, so the markers are right. - Refusal text matches
oauthError('invalid_grant', 'No trust rule matches this workflow'). - Agent entry points.
agent-instructions.txt, theastro.config.mjsdetailsandscripting.mdxmention OIDC with the version marker. - Links and lint. Both new anchors resolve, the GitHub environments link returns 200, there are no em-dashes, and Prettier, vale and cspell are clean on the changed text.
Findings
None.
…idc-merge # Conflicts: # astro.config.mjs # public/.well-known/agent-instructions.txt
CI jobs on GitHub Actions can sign in to Shorebird with the OIDC token GitHub issues to each job, instead of a long-lived
SHOREBIRD_TOKENstored as a repository secret. This adds a section to the GitHub Actions guide covering it. The console's "Workflow trusted" dialog links to this page.What the section covers
shorebird apifollow.permissions: id-token: write, the environment the rule names, andSHOREBIRD_PROJECT_ID.SHOREBIRD_TOKENtakes precedence over OIDC in the CLI, so it has to be removed when moving a workflow over.The job acts with the service account's role. Trust rules have no scope of their own.
Status
Everything this page describes is live: server and auth support (https://github.com/shorebirdtech/_shorebird/pull/3529, https://github.com/shorebirdtech/_shorebird/pull/3530, https://github.com/shorebirdtech/_shorebird/pull/3531, private), the console trust rules UI (https://github.com/shorebirdtech/_shorebird/pull/3532, private) on prod, and the CLI side (shorebirdtech/shorebird#4084) in Shorebird 1.6.129. The page says OIDC needs 1.6.129 or newer.