Skip to content

Service Accounts

A service account is an account that belongs to an organization instead of a person. It holds one role in that organization, and its API keys do what that role allows. Use one for CI, release scripts, and integrations, so they keep working when the person who set them up leaves or changes roles, and so the audit log can tell automation from people.

A personal API key acts as you: it can do at most what your own role allows, and it stops working if your account is deleted. Use a personal key for your own scripts, and a service account for anything your team depends on.

Service accounts and their keys are available on every plan. Signing in from GitHub Actions without a stored key, with a trust rule, needs a Business or Enterprise plan.

The organization’s Admins and Owner can see, create, change, and delete its service accounts, their keys, and their trust rules. Other members can’t see them.

A service account is not a member. It doesn’t appear on the Members page, and it belongs to its organization for as long as it exists.

  1. In the Shorebird Console, open your organization’s Settings and select Service accounts.
  2. Click Create service account.
  3. Enter a name for what will use it, such as GitHub Actions. The name can’t be changed later.
  4. Click Create.

The account opens with the Developer role and nothing that can sign in as it yet. Pick its role, then give it a way to sign in: under GitHub Actions, add a workflow, or under API keys, create a key for other CI systems.

The audit log shows the account as its name followed by [bot], such as GitHub Actions[bot].

To do this from the command line, see Manage service accounts from the CLI.

A service account can hold one of four roles. Pick the narrowest one that does the job:

  • Viewer: sees apps, releases, patches, channels, and insights, and also the organization’s members, pending invitations, plan, and usage. Use it for dashboards and other read-only integrations.
  • Developer (the default): can also create releases and patches, create channels, and promote and roll back patches. Use it for CI that ships releases and patches.
  • App Manager: can also create, update, and delete apps. Use it when automation creates apps, for example by running shorebird init.
  • Auditor: reads the organization’s audit log and nothing else. Use it for a tool that exports the audit log, so that tool doesn’t need an Admin’s key. Reading the audit log needs the Enterprise plan, so on other plans an Auditor service account can’t read anything.

Every plan lets you give a service account any of these four roles. A service account can’t be an Admin or Owner, so a leaked key can’t manage members, billing, other service accounts, or the organization itself.

To change the role, open the account in the console and pick another one under Role. The change applies right away to every key the account holds and to every job signed in as it, so the console asks you to confirm once anything can sign in as the account.

A service account’s keys have no permission level of their own. To give one pipeline less access than another, create a separate service account with a narrower role.

Create more than one key to rotate them without downtime: create a new key, update your CI secret, then revoke the old one. Every key acts as the same account, so the audit history stays in one place.

To create a key, open the account, click Create key under API keys, enter a name for where it will be stored, and choose an expiration: 30 days, 90 days, 1 year (the default), or never. A key that never expires works until someone revokes it, so prefer an expiration, or sign in with a trust rule where you can.

The key is shown once: copy it into your CI platform’s secrets manager, for example as SHOREBIRD_TOKEN.

To revoke a key, click Revoke next to it and confirm. Requests using it fail right away, and this can’t be undone.

To create a key from a script, call the API signed in as an Admin or Owner with shorebird login, with SHOREBIRD_TOKEN unset: no API key can create one. Leave out expires_in_days for a 1-year key, or pass -F expires_in_days=null for one that never expires. The key is in the api_key field of the response, and it is shown only once.

shorebird api -X POST organizations/<org id>/service-accounts/<service account id>/keys \
  -f name=github-actions -F expires_in_days=90

shorebird service-accounts keys create doesn’t create a key; it opens the account’s page in the console, where you click Create key. keys list and keys revoke list and revoke keys from the command line; see Manage service accounts from the CLI.

The Shorebird CLI reads a key from the SHOREBIRD_TOKEN environment variable, the same way it reads a personal API key:

export SHOREBIRD_TOKEN="<service account key>"
shorebird patch android --release-version=latest --track=stable

To call the Shorebird API directly, send the key as a bearer token:

curl -H "Authorization: Bearer $SHOREBIRD_TOKEN" https://api.shorebird.dev/api/v1/apps

See Running in CI and scripts for running the CLI unattended, and the CI guides for GitHub Actions, GitLab, Codemagic, and other CI systems.

A service account can do what its role allows on every app in its organization. Requests about the caller’s own account, such as its profile, its plan and billing, its usage, and invitations sent to it, are refused with service_account_forbidden, and so is creating an organization.

A GitHub Actions workflow can sign in as a service account with no stored key, through a trust rule on that account. Trust rules need a Business or Enterprise plan.

Open the account, click Delete account, and confirm. Deleting it revokes all its keys and deletes its trust rules, so anything using them loses access right away. Its apps, releases, and patches belong to the organization and are not affected, and its entries in the audit log stay.

shorebird service-accounts (Shorebird 1.6.135 or newer) does from the command line what the console’s Service accounts page does, except create keys. On its own it lists the organization’s service accounts.

# Create an account, then change its role
shorebird service-accounts create release --role developer --org-id <org id>
shorebird service-accounts set-role release --role viewer --org-id <org id>

# List the account's keys that haven't been revoked, and revoke one
shorebird service-accounts keys list release --org-id <org id>
shorebird service-accounts keys revoke release <key id> --org-id <org id>

# Delete the account
shorebird service-accounts delete release --org-id <org id>

create prints the account’s ID and the console link where you create a key for it.

--org-id is the organization’s ID: the number after /orgs/ in the console’s address bar, or the first column of shorebird orgs list. Without it, a command uses the organization that owns the app in the current directory’s shorebird.yaml, or your only organization. Name an account by its name or its ID. When that matches more than one account, such as two accounts with the same name, the command lists them and stops; name the one you mean as id:<id>, such as id:383.

You need the Admin or Owner role. Listing and showing accounts, keys, and trust rules also works with an Admin’s or Owner’s personal API key in SHOREBIRD_TOKEN, but not with a release and patch only key. Creating, changing, and deleting need a shorebird login session with SHOREBIRD_TOKEN unset: the API refuses API keys and GitHub Actions OIDC for them.

delete, keys revoke, and trust remove ask you to confirm in a terminal. Without a terminal, in CI, or with --json, pass --yes, or they exit with a usage error and change nothing. keys create exits with console_required there; see Commands that finish in the console.

With --json, the commands return the accounts, keys, and trust rules they read or changed, by ID. A key’s secret is never in the output. Run shorebird service-accounts <command> --help for each command’s options and an example.

The audit log records each service account’s actions with the account, name[bot], as the actor, along with the key or trust rule it used.