---
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 create one from the command line, use [`shorebird api`](/account/api/). The ID it needs, `<project id>` below, is the number after `/orgs/` in the console’s address bar, and `shorebird account orgs` lists it too.

Run these commands signed in with `shorebird login` and with `SHOREBIRD_TOKEN` unset. API keys can’t create, change, or delete service accounts, their keys, or their trust rules.

```
shorebird api -X POST organizations/<project id>/service-accounts \
  -f name=release -f role=developer
```

Note the `id` it prints and [create a key](#create-and-revoke-keys) for it.

## 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. From the command line:

```
shorebird api -X PATCH organizations/<project id>/service-accounts/<service account id> \
  -f role=viewer
```

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.

The same from the command line. 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.

```
# Create a key that expires in 90 days
shorebird api -X POST organizations/<project id>/service-accounts/<service account id>/keys \
  -f name=github-actions -F expires_in_days=90

# List the account's keys
shorebird api organizations/<project id>/service-accounts/<service account id>/keys

# Revoke a key
shorebird api -X DELETE organizations/<project id>/service-accounts/<service account id>/keys/<key id>
```

## 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
```

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/), [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.

```
shorebird api -X DELETE organizations/<project id>/service-accounts/<service account id>
```

## 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.
