Skip to content

docs: service accounts and trust rules - #733

Open
eseidel wants to merge 3 commits into
mainfrom
docs-service-accounts
Open

eseidel wants to merge 3 commits into
mainfrom
docs-service-accounts

Conversation

@eseidel

@eseidel eseidel commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Why

Every API key today belongs to a person, so CI breaks or keeps too much access when that person leaves or changes role. Service accounts fix that: an organization owns them, they hold one role, and their keys and OIDC sign-ins act with that role. The console page for them exists, but the docs only reached it through the GitHub Actions OIDC walkthrough. This adds task-oriented pages so a reader can decide when to use a service account, set one up, and keep it narrow.

What

  • New /account/service-accounts/: when to use one instead of a personal key, who can manage them, creating one (console and shorebird api; the console creates it by name, with no first key, and keys or workflows are added in its sheet afterward), choosing a role (Viewer, Developer, App Manager, Auditor; never Admin or Owner; all four on every plan), creating, rotating and revoking keys (default 1 year, at most 1 year or never), using a key via SHOREBIRD_TOKEN or Authorization: Bearer, what a service account is refused (service_account_forbidden), deleting one.
  • New /account/trust-rules/: when to use a trust rule, the plan requirement (adding needs Business or Enterprise; existing rules keep working after a downgrade), exactly what a rule matches (owner ID pinning, workflow file, reusable workflows, environment, ref pattern with a trailing *), the one-service-account-per-match rule, the 15-minute access token the CLI renews, listing and deleting rules, and the refusal messages. The setup walkthrough stays on the GitHub Actions page and is linked, not repeated.
  • GitHub Actions page: step 1 now goes through Settings rather than a pasted URL, links the role and matching sections, and keeps the project ID explanation next to the CLI commands that use it.
  • API Keys, CI authentication partial, Organizations: one or two sentences each pointing at service accounts.

Audit log details (the Auditor role's use, how service account actions and service_account.sign_in appear, OCSF export) are kept to a sentence and link to /account/audit-logs/, which is a separate docs PR. Those links use the absolute https://docs.shorebird.dev/account/audit-logs/ URL so this PR builds on its own; they resolve once that page is published.

No other docs PRs were open when this was written, so nothing overlaps.

Landing

After the console's service accounts sheet ships: _shorebird#3609 (top of the stack #3604, #3606, #3607, #3608, #3609) and #3605 (the Settings tab) merged and deployed to the console. The page describes that UI (Create service account, Create key, Revoke, Remove, Delete account) and Settings > Service Accounts.

Checks

npm run build (astro check plus link validation), Vale, cspell, Prettier, and the component label lint all pass locally.

🤖 Generated with Claude Code

@eseidel

eseidel commented Oct 16, 2026

Copy link
Copy Markdown
Contributor Author

Adversarial review (independent reviewer, checked against the server, console, auth service, and CLI on main)

Docs-only diff. No blockers. Five claims were wrong or incomplete:

Sev Where Issue Action
🟡 Watch account/service-accounts.mdx Auditor bullet, account/orgs.mdx roles note The page says all four roles work on every plan. But the audit log route is behind planGuard(PlanFeature.auditLogs), and only Enterprise has that feature. Auditor has no other permission, so an Auditor account on Free, Pro, or Business can't read anything. Say Auditor can be assigned on any plan but is only useful on Enterprise.
🟡 Watch account/service-accounts.mdx "Use a key" The page says plan, usage, and invitations are refused with service_account_forbidden. humanGuard covers only the caller's own /users, /plan, /usage, /invitations, plus POST /organizations. The organization-level plan, usage, and invitations routes check the role instead. Narrow the claim to the caller's own account, plan, usage, and invitations.
🟡 Watch account/service-accounts.mdx Viewer bullet Viewer is view on every resource that isn't identity-gated or admin-only, except the audit log. That includes organization members, pending invitations, and the organization's plan and usage. The page tells readers to pick the narrowest role, so leaving these out understates Viewer. List members, invitations, and plan and usage under Viewer.
🟡 Watch account/trust-rules.mdx Repository bullet match_github_oidc_trust_rules also compares the stored repository name, so renaming the repository breaks the rule too. The page only covers renaming the owner. Say "user, organization, or repository".
🟡 Watch account/trust-rules.mdx delete section The page doesn't say that deleting a rule leaves already-issued tokens valid. Federated tokens last 15 minutes and have no session to revoke, which the console's confirm dialog says. Say running jobs keep their token for up to 15 minutes, and that deleting the service account or changing its role takes effect right away.

Checked and correct: endpoint paths and body fields (name, role, expires_in_days default/max/null, api_key), the shorebird api -f/-F/-X usage, the default role, the name[bot] label, console labels and expiry options, the plan gate for adding rules and the downgrade behavior, owner-ID pinning, case-insensitive environment and owner/repository matching, the trailing-* ref prefix, the refusals for reusable workflows from another repository and for ambiguous matches, the quoted CLI messages, 15-minute renewal, SHOREBIRD_TOKEN taking precedence, the 1.6.129 minimum, the deletion cascade, and all internal links and anchors.

@eseidel

eseidel commented Oct 17, 2026

Copy link
Copy Markdown
Contributor Author

I think the thing for you to decide, out of shock, is if you like where these drugs are put. They seem correct to me. Please feel free to move them around as needed, and otherwise just land. This is your PR to take over.

eseidel and others added 3 commits October 16, 2026 23:14
Matches the console's service account sheet (_shorebird#3607-#3609): the
account is created by name with the Developer role and nothing that signs
in; keys are created afterward under API keys, revoked with Revoke, rules
removed with Remove, and the account deleted with Delete account.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@eseidel
eseidel force-pushed the docs-service-accounts branch from e6d4fdc to faa7d24 Compare October 17, 2026 06:16
@eseidel

eseidel commented Oct 17, 2026

Copy link
Copy Markdown
Contributor Author

Adversarial review: all five findings were fixed in 905f8b3.

  • Auditor: now says any plan can assign it, but reading the audit log needs Enterprise, so on other plans it can't read anything.
  • Refusals: narrowed to the caller's own account, plan and billing, usage, and invitations, plus creating an organization.
  • Viewer: now lists members, pending invitations, plan, and usage.
  • Trust rules: renaming the user, organization, or repository breaks the rule.
  • Deleting a rule: running jobs keep their token for up to 15 minutes; deleting the service account or changing its role takes effect right away.

@eseidel

eseidel commented Oct 17, 2026

Copy link
Copy Markdown
Contributor Author

Rebased on main and updated for the console's new service account sheet (_shorebird#3604 to #3609) in faa7d24:

  • Create: the account is created by name only, with the Developer role and no key. Choosing the role and adding a workflow or key come after, in its sheet.
  • Keys: Create key under API keys, Revoke to revoke. Trust rules: Remove. Account: Delete account. Changing the role asks for confirmation once anything can sign in.
  • GitHub Actions page: dropped "creating an account also creates an API key, so you can revoke it".
  • Renamed the #issue-and-revoke-keys anchor to #create-and-revoke-keys to match the console's wording.

No screenshots or embeds on these pages, so nothing to re-capture. Not merging: this should land after #3609 and #3605 are deployed (see Landing).

@eseidel

eseidel commented Oct 17, 2026

Copy link
Copy Markdown
Contributor Author

lgtm

eseidel added a commit that referenced this pull request Oct 17, 2026
#733 renamed #issue-and-revoke-keys to #create-and-revoke-keys, and the
console now creates a service account with the Developer role first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@eseidel

eseidel commented Oct 17, 2026

Copy link
Copy Markdown
Contributor Author

Landing check at faa7d24: CI is green and Eric has LGTM'd, but this can't land yet.

  • The console work it describes hasn't shipped. _shorebird#3604, #3605, #3606, #3607, #3608 and #3609 are all still open, so the service account sheet and the Settings > Service Accounts tab aren't in the console. The page would describe UI customers can't see.
  • An approving review is still needed. Branch protection requires one, and Eric opened this PR, so his can't count. @AbhishekDoshi26, this one is yours to review.

For Abhishek while reviewing: the page says a service account appears in the audit log as name[bot]. That's how the console labels it. The audit log API's actor.user.name is the name without [bot], which is what #734 documents.

The renamed #create-and-revoke-keys anchor is now matched in #734.

I'll merge through the queue once those PRs are deployed to the console and this has an approval.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant