---
title: "Service Accounts"
description: "Give CI, scripts, and integrations their own account in your organization, with a role and keys that don't depend on any person"
---

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](/account/api-keys/) 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](/account/trust-rules/), needs a Business or Enterprise plan.

## Who can manage service accounts

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.

## Create a service account

1. In the [Shorebird Console](https://console.shorebird.dev), 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](#choose-a-role), then give it a way to sign in: under **GitHub Actions**, [add a workflow](/account/trust-rules/), or under **API keys**, [create a key](#create-and-revoke-keys) 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](#manage-service-accounts-from-the-cli).

## Choose a role

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](/enterprise/audit-logs/) 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 and revoke keys

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](/account/trust-rules/) 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](/account/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](#manage-service-accounts-from-the-cli).

## Use a key from CI or a script

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](/account/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](/code-push/ci/scripting/) for running the CLI unattended, and the CI guides for [GitHub Actions](/code-push/ci/github/), [GitLab](/code-push/ci/gitlab/), [Codemagic](/code-push/ci/codemagic/), and [other CI systems](/code-push/ci/generic/).

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.

## Sign in from GitHub Actions without a key

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

## Delete a service account

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.

## Manage service accounts from the CLI

`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](#create-and-revoke-keys) 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](/account/cli/#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.

## Service accounts in the audit log

The [audit log](/enterprise/audit-logs/) records each service account’s actions with the account, `name[bot]`, as the actor, along with the key or trust rule it used.
