> ## Documentation Index
> Fetch the complete documentation index at: https://docs.entire.com/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenID Connect (OIDC)

> Sign in to Entire from a platform that issues OIDC tokens to its jobs, functions, or agents.

Platforms such as GitHub Actions and Cursor give each job or agent a short-lived, signed token that names its repository or project. This standard is called OpenID Connect (OIDC). Your jobs and agents can exchange this token to sign in as a [service account](https://docs.entire.com/guides/configuration/service-accounts.md), with no secret to store.

The job can then clone and push repositories, open Trails, and read review results.

## How It Works

Every platform follows the steps below, but differs in which pins it uses and how a job gets its token.

### Bind the Platform

**1. Create the service account**

Create a service account and grant it access to the repositories your jobs need, [in entire.com or with the CLI](https://docs.entire.com/guides/configuration/service-accounts.md#set-up-a-service-account).

**2. Find the platform's pins**

`entire service-account providers` lists the platforms. `entire service-account providers <name>` lists a platform's pins, which ones are required, and the format of each value.

**3. Bind the platform to the service account**

Each `--pin name=value` adds a condition that the token must match:

```bash theme={null}
entire service-account bind acme/deploy --provider github-actions \
  --pin repository=acme/web \
  --pin workflow_ref=acme/web/.github/workflows/deploy.yml@refs/heads/main
```

The command prints three values you'll need later:

| Value | Use |
| - | - |
| `audience` | The audience you ask your platform to put in its token, such as `https://us.auth.entire.io/api/authz/sts`. |
| `endpoint` | Where you send the token. |
| `resource` | The service account ID. |

If you bound the platform in entire.com, `resource` is the service account's ID. `audience` and `endpoint` are its Auth URL followed by `/api/authz/sts` and `/oauth/token`.

A service account holds one binding per platform. `entire service-account bindings acme/deploy` lists its bindings with their `eib_` IDs, and `entire service-account unbind acme/deploy <binding-id>` removes one. Tokens already issued keep working for up to 45 minutes after you remove a binding. To cut access sooner, revoke the service account's grants.

### Choose Pins

Any job whose token matches the pins can sign in as the service account. You should pin as narrowly as the job allows:

* Pin the branch, environment, or workflow, along with the repository or organization.
* Pin values that only the job you trust can get a token for.
* Pins match by name. Remove a binding before you rename or delete a pinned repository or pipeline. Otherwise a new one with the old name could sign in.
* Pins marked `EXACT` in `entire service-account providers <name>` take one value. The others also take a glob, such as `deploy-*`.

### Exchange the Token

Exchange your platform's token for a service account token that the `entire` CLI and `git` can use:

```bash theme={null}
ENTIRE_AUTH_URL=https://us.auth.entire.io
export ENTIRE_TOKEN=$(curl -sS -X POST "$ENTIRE_AUTH_URL/oauth/token" -u entire-cli: \
  --data-urlencode grant_type=urn:ietf:params:oauth:grant-type:token-exchange \
  --data-urlencode subject_token_type=urn:ietf:params:oauth:token-type:jwt \
  --data-urlencode subject_token=$OIDC_TOKEN \
  --data-urlencode audience=$ENTIRE_AUTH_URL \
  --data-urlencode resource=svc_01ABC... | jq -r '.access_token // error(.error_description)')
```

Most platform tokens expire within minutes, so make sure to exchange the token right after you get it.

The service account token lasts around 45 minutes. If your job runs longer, get a new platform token and exchange it again before the next Entire command, or after a `401`.

### Use the Token

[Install the CLI](https://docs.entire.com/installation.md) where the job runs. With `ENTIRE_TOKEN` set, the `entire` CLI and `git-remote-entire` use it in place of a login:

```bash theme={null}
entire repo clone /et/acme/web web
```

The clone's `origin` remote points at Entire, so `git fetch` and `git push` in that clone run as the service account too.

For the API, send the token as a bearer token. See [Authentication](https://docs.entire.com/guides/api/authentication.md) for more details.

## Platforms

> [tab] Amp
>
> Each Amp orb can request a token for the project it runs in. Bind the Amp project to a service account to let its orbs sign in.
>
> **1. Find the project ID**
>
> Find the project's ID with `amp projects list`.
>
> **2. Bind the Amp project to the service account**
>
> ```bash theme={null}
> entire service-account bind acme/orbs --provider amp \
>   --pin project=b6201409-e9f5-4a14-82a3-7ea1aac91f37
> ```
>
> The pins you can set:
>
> | Pin | Required | Matches |
> | - | - | - |
> | `project` | Yes | The Amp project ID, in lower case. |
> | `workspace` | No | The Amp workspace ID. |
> | `user` | No | The Amp user whose thread it is, such as `user_01ABC...`. |
> | `thread` | No | The thread ID, such as `T-01ABC...`. |
> | `subject` | No | The token's `sub` claim. Its shape varies, so pin the IDs above instead. |
>
> Any orb in the project can sign in, whoever started it. To limit it to one person's orbs, add `--pin user=...`.
>
> #### Use It in an Orb
>
> Amp tokens last 10 minutes. Get one inside the orb:
>
> ```bash theme={null}
> ENTIRE_AUTH_URL=https://us.auth.entire.io
> OIDC_TOKEN=$(amp orb id-token --audience $ENTIRE_AUTH_URL/api/authz/sts)
> ```
>
> Then [exchange](#exchange-the-token) and [use](#use-the-token) the token.
>
> > [!NOTE]
> >
> > Only a thread that runs in an orb and belongs to an Amp project can sign in. Run `amp orb id-token` inside the orb.
>
> If sign-in fails, refer to [Service Account Troubleshooting](https://docs.entire.com/guides/configuration/service-accounts-troubleshooting.md).

> [tab] Buildkite
>
> > [!TIP]
> >
> > To use Buildkite for CI on your Entire repositories, use our [Buildkite plugin](https://docs.entire.com/guides/ci/connect-ci.md).
>
> Each Buildkite job can request an OIDC token for its pipeline. Bind your pipeline to a service account, and the job can sign in with that token.
>
> Pin your organization slug and the pipeline slug:
>
> ```bash theme={null}
> entire service-account bind acme/deploy --provider buildkite \
>   --pin organization=acme \
>   --pin pipeline=deploy
> ```
>
> The pins you can set:
>
> | Pin | Required | Matches |
> | - | - | - |
> | `organization` | Yes | Your Buildkite organization slug. |
> | `pipeline` | Yes | The pipeline slug. A glob such as `deploy-*` matches several pipelines. |
> | `branch` | No | The build branch, such as `main`. |
> | `commit` | No | The build commit SHA. |
> | `step` | No | The step key. |
> | `job` | No | The job ID. |
> | `agent` | No | The agent ID. |
> | `subject` | No | The token's `sub` claim, `organization:<org>:pipeline:<pipeline>:ref:refs/heads/<branch>:commit:<sha>:step:<key>`. |
>
> A `pipeline` glob also matches pipelines created later. Use one only if you control who can create pipelines in the organization.
>
> Any build of the pipeline can sign in, on any branch and in any step. To limit it, add `--pin branch=main` or `--pin step=deploy`. Anyone who can start a build chooses its branch and commit. Pin a pipeline whose builds only trusted people can start.
>
> #### Use It in a Pipeline
>
> Buildkite tokens last 5 minutes. Get the token, exchange it, and export the result as `ENTIRE_TOKEN` in the same step. Every command after that runs as the service account:
>
> ```yaml .buildkite/pipeline.yml theme={null}
> steps:
>   - label: "Clone from Entire"
>     command: |
>       ENTIRE_AUTH_URL=https://us.auth.entire.io
>       OIDC_TOKEN=$$(buildkite-agent oidc request-token --audience $$ENTIRE_AUTH_URL/api/authz/sts)
>       export ENTIRE_TOKEN=$$(curl -sS -X POST $$ENTIRE_AUTH_URL/oauth/token -u entire-cli: \
>         --data-urlencode grant_type=urn:ietf:params:oauth:grant-type:token-exchange \
>         --data-urlencode subject_token_type=urn:ietf:params:oauth:token-type:jwt \
>         --data-urlencode subject_token=$$OIDC_TOKEN \
>         --data-urlencode audience=$$ENTIRE_AUTH_URL \
>         --data-urlencode resource=svc_01ABC... | jq -r '.access_token // error(.error_description)')
>       entire repo clone /et/acme/web web
> ```
>
> `$$` stops `buildkite-agent pipeline upload` from expanding the variable at upload time.
>
> If sign-in fails, see [Service Account Troubleshooting](https://docs.entire.com/guides/configuration/service-accounts-troubleshooting.md).

> [tab] Cursor
>
> A Cursor Cloud Agent can request a token for the repository it works on. Bind the repository and your team to a service account to let your agents sign in.
>
> **1. Find your team ID**
>
> Your team ID is a number. Find it in the Cursor dashboard. On a personal account, use your user ID instead.
>
> **2. Bind the repository and team to the service account**
>
> ```bash theme={null}
> entire service-account bind acme/agents --provider cursor \
>   --pin repo_url=github.com/acme/web \
>   --pin team=19262307
> ```
>
> The pins you can set:
>
> | Pin | Required | Matches |
> | - | - | - |
> | `repo_url` | Yes | The agent's primary repository as `host/path`, such as `github.com/acme/web` or `origin.cursor.com/git/acme/web`. |
> | `team` | One of these | The Cursor team ID. |
> | `user` | One of these | The Cursor user ID of the agent's owner. |
> | `service_account` | One of these | The Cursor service account ID of the agent's owner. |
> | `environment` | No | The Cursor environment ID. |
> | `branch` | No | The branch the agent works on. |
> | `runtime` | No | `managed` on Cursor's machines, `self_hosted` on a Self-Hosted Machines worker. |
> | `source` | No | How the agent started: `WEBSITE`, `API`, `SLACK`, or `AUTOMATIONS`. |
> | `automation` | No | The automation ID, when `source` is `AUTOMATIONS`. |
> | `agent` | No | The Cloud Agent ID. |
> | `subject` | No | The token's `sub` claim. Its shape varies, so pin the IDs above instead. |
>
> A binding needs the repository plus one of `team`, `user`, or `service_account`. Anyone can open a public repository in a Cloud Agent. Pinning the repository alone doesn't limit sign-in to your agents. On an agent with several repositories, the token names only the primary one.
>
> > [!WARNING]
> >
> > Pin `runtime=managed` unless you trust every process on your Self-Hosted Machines workers. Any of them can request a token.
>
> #### Use It in a Cloud Agent
>
> Cursor tokens last 5 minutes. The agent requests one from Cursor's local socket. Put this in a setup step, a script in the repository, or the prompt:
>
> ```bash theme={null}
> ENTIRE_AUTH_URL=https://us.auth.entire.io
> OIDC_TOKEN=$(curl -sS --unix-socket "$CURSOR_AGENT_SOCKET" -H 'Content-Type: application/json' \
>   -d "{\"aud\":\"$ENTIRE_AUTH_URL/api/authz/sts\"}" http://cursor-agent/v1/tokens/oidc | jq -r .token)
> ```
>
> Then [exchange](#exchange-the-token) and [use](#use-the-token) the token.
>
> If sign-in fails, see [Service Account Troubleshooting](https://docs.entire.com/guides/configuration/service-accounts-troubleshooting.md).

> [tab] Devin
>
> Devin gives each session a token for your organization. Bind the organization to a service account to let sessions sign in.
>
> Pin your Devin organization ID. You can find it in the `sub` value that `devin-oidc token` prints, or ask your Devin administrator:
>
> ```bash theme={null}
> entire service-account bind acme/devin --provider devin \
>   --pin organization=org-b5148187ac634e3ea4371c95e4f05edf
> ```
>
> The pins you can set:
>
> | Pin | Required | Matches |
> | - | - | - |
> | `organization` | Yes | The Devin organization ID, `org-` and 32 hex characters. |
> | `user` | No | The Devin user who started the session, `user-...`. |
> | `trigger` | No | How the session started: `webapp`, `slack`, or `api`. |
> | `service_user` | No | The service user, for sessions started through the API. |
> | `automation` | No | The automation ID, for sessions an automation started. |
> | `environment` | No | The Devin environment ID. |
> | `account` | No | The Devin account ID, `account-...`. |
> | `session` | No | The Devin session ID, `devin-...`. |
> | `subject` | No | The token's `sub` claim. Its shape varies, so pin the IDs above instead. |
>
> Any session in the organization can sign in. To limit it to one person's sessions, add `--pin user=...`. To allow only sessions started through the API, add `--pin trigger=api`.
>
> #### Use It in a Session
>
> Devin tokens are short-lived. Add Devin's `setup-devin-oidc` action to your environment blueprint to get the `devin-oidc` CLI, then get a token:
>
> ```bash theme={null}
> ENTIRE_AUTH_URL=https://us.auth.entire.io
> OIDC_TOKEN=$(devin-oidc token --audience $ENTIRE_AUTH_URL/api/authz/sts)
> ```
>
> Then [exchange](#exchange-the-token) and [use](#use-the-token) the token.
>
> If sign-in fails, see [Service Account Troubleshooting](https://docs.entire.com/guides/configuration/service-accounts-troubleshooting.md).

> [tab] GitHub Actions
>
> > [!TIP]
> >
> > For a full walkthrough, see [Push from GitHub Actions](https://docs.entire.com/guides/ci/github-actions.md).
>
> Every GitHub Actions job can get a token for the repository it runs in. Bind the repository to a service account, and the `entireio/setup-entire` action signs the job in.
>
> Pin the GitHub repository that runs the workflow, as `owner/name`:
>
> ```bash theme={null}
> entire service-account bind acme/deploy --provider github-actions \
>   --pin repository=acme/web \
>   --pin workflow_ref=acme/web/.github/workflows/deploy.yml@refs/heads/main
> ```
>
> The command prints a ready-made `entireio/setup-entire` step with the `service-account` and `auth-url` values filled in. Copy it into your workflow.
>
> The pins you can set:
>
> | Pin | Required | Matches |
> | - | - | - |
> | `repository` | Yes | One GitHub repository, as `owner/name`, such as `acme/web`. No wildcards. |
> | `ref` | No | The ref that started the run, such as `refs/heads/main`. |
> | `workflow_ref` | No | The top-level workflow file and ref, such as `acme/web/.github/workflows/deploy.yml@refs/heads/main`. |
> | `job_workflow_ref` | No | The workflow file the job runs. Pins a reusable workflow. |
> | `event_name` | No | The event that started the run, such as `push`. |
> | `actor` | No | The GitHub login that started the run. |
> | `subject` | No | The token's `sub` claim. |
>
> Any workflow in the repository can sign in, on any branch. To limit it, add `--pin ref=...` for one branch or `--pin workflow_ref=...` for one workflow file. Each service account serves one GitHub repository, because `repository` takes no wildcard.
>
> > [!WARNING]
> >
> > `ref` alone doesn't stop `pull_request_target`, `issue_comment`, or `workflow_run` runs, which run on the default branch and can be started from a fork. Pin `workflow_ref` to the workflow file that should sign in.
>
> #### Use It in a Workflow
>
> The [`entireio/setup-entire`](https://github.com/entireio/setup-entire) action installs the CLI, gets the job's OIDC token with the Entire audience, exchanges it, and exports the result as `ENTIRE_TOKEN`. Every later step runs as the service account:
>
> ```yaml .github/workflows/clone-from-entire.yml theme={null}
> name: Clone from Entire
>
> on:
>   push:
>     branches: [main]
>
> permissions:
>   id-token: write
>
> jobs:
>   build:
>     runs-on: ubuntu-latest
>     steps:
>       - uses: entireio/setup-entire@v1
>         with:
>           service-account: svc_01ABC...
>       - run: entire repo clone /et/acme/web web
> ```
>
> The job needs `permissions: id-token: write`, or GitHub issues no OIDC token.
>
> | Input | Default | Description |
> | - | - | - |
> | `service-account` | | The `svc_` ID, from the `create` or `bind` output. Omit it to install the CLI only. |
> | `auth-url` | `https://us.auth.entire.io` | The auth URL for your region, from the `bind` output. |
> | `version` | The release pinned in the action | The `entire` CLI release to install. |
> | `install` | `true` | Put `entire` and `git-remote-entire` on `PATH`. |
> | `export-env` | `true` | Export the token as `ENTIRE_TOKEN` for later steps. |
>
> The action sets two outputs. `token` holds the token, masked in logs, for a step that doesn't read `ENTIRE_TOKEN`. `expires-in` is the token's lifetime in seconds. If a job runs longer than 45 minutes, run the action again before the next step that needs Entire. To keep the token away from steps that don't need it, set `export-env: false` and pass the `token` output only to the steps that use Entire.
>
> If the action can't run, such as under a policy that blocks third-party actions or on a Windows runner, [exchange the token yourself](#exchange-the-token).
>
> If sign-in fails, refer to [Service Account Troubleshooting](https://docs.entire.com/guides/configuration/service-accounts-troubleshooting.md).

> [tab] Google Cloud
>
> Code on Google Cloud runs as a Google service account, and it can ask Google for an ID token for that account. Bind the Google service account to an Entire service account to let your code sign in.
>
> Pin the email of the Google service account your code runs as:
>
> ```bash theme={null}
> entire service-account bind acme/deploy --provider google-cloud \
>   --pin service_account=deploy@my-project.iam.gserviceaccount.com
> ```
>
> The pins you can set:
>
> | Pin | Required | Matches |
> | - | - | - |
> | `service_account` | Yes | The Google service account email, in lower case. |
> | `subject` | No | The service account's unique ID, from `gcloud iam service-accounts describe <email> --format='value(uniqueId)'`. |
>
> The unique ID changes when a Google service account is deleted and recreated under the same email. To refuse a recreated account, add `--pin subject=...`.
>
> #### Use It on Google Cloud
>
> A Google ID token lasts one hour. Request it with the `audience` value from `bind`. On Compute Engine, Cloud Run, Cloud Functions, and GKE, ask the [metadata server](https://cloud.google.com/docs/authentication/get-id-token#metadata-server):
>
> ```bash theme={null}
> ENTIRE_AUTH_URL=https://us.auth.entire.io
> OIDC_TOKEN=$(curl -sS -H "Metadata-Flavor: Google" \
>   "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=$ENTIRE_AUTH_URL/api/authz/sts")
> ```
>
> Client libraries take the same audience, such as `idtoken.NewTokenSource` in Go or `id_token.fetch_id_token` in Python. For a test from your own machine, run:
>
> ```bash theme={null}
> ENTIRE_AUTH_URL=https://us.auth.entire.io
> OIDC_TOKEN=$(gcloud auth print-identity-token \
>   --impersonate-service-account=deploy@my-project.iam.gserviceaccount.com \
>   --audiences=$ENTIRE_AUTH_URL/api/authz/sts \
>   --include-email)
> ```
>
> The token must carry the `email` claim. Tokens from the metadata server include it. `gcloud` and the `generateIdToken` API include it only with `--include-email` or `includeEmail: true`.
>
> Then [exchange](#exchange-the-token) and [use](#use-the-token) the token.

> [tab] Vercel
>
> Vercel Functions can request a token for your team and environment. Bind your Vercel team to a service account to let your Functions sign in. A [Vercel Sandbox](https://vercel.com/docs/vercel-sandbox) can run the `entire` CLI with the service account token kept out of the sandbox.
>
> **1. Use the Team issuer**
>
> In your Vercel project, open **Settings → Security → Secure backend access** and set the OIDC **Issuer Mode** to **Team**.
>
> **2. Find your team ID**
>
> In Vercel, open your team's **Settings → General** and copy the **Team ID**. It starts with `team_`. Use the ID, which stays the same when the team is renamed.
>
> **3. Bind Vercel to the service account**
>
> ```bash theme={null}
> entire service-account bind acme/deploy --provider vercel \
>   --pin team_id=team_abc123 \
>   --pin environment=production
> ```
>
> The pins you can set:
>
> | Pin | Required | Matches |
> | - | - | - |
> | `team_id` | Yes | The Vercel team ID, such as `team_abc123`. |
> | `environment` | Yes | `production`, `preview`, `development`, or a custom environment. |
> | `project_id` | No | One Vercel project ID, such as `prj_abc123`. |
> | `subject` | No | The full token subject, `owner:<team>:project:<project>:environment:<env>`. |
>
> Any Vercel project in the team can sign in in the pinned environment. To allow only one project, add `--pin project_id=...`.
>
> > [!WARNING]
> >
> > Bind `development` only if every member of your Vercel team may sign in as the service account. Any team member can get a development token with `vercel env pull`.
>
> #### Use It from a Function
>
> Install the Vercel OIDC package:
>
> ```bash theme={null}
> npm install @vercel/oidc
> ```
>
> Add a helper that gets a Vercel token with the Entire audience and exchanges it. Here's how you can set the values from the `bind` output:
>
> ```ts lib/entire.ts theme={null}
> import { getVercelOidcToken } from "@vercel/oidc";
>
> const ENTIRE_AUTH_URL = "https://us.auth.entire.io";
> const SERVICE_ACCOUNT = "svc_01ABC...";
>
> let cached: { token: string; expiresAt: number } | undefined;
>
> export async function getEntireToken(): Promise<string> {
>   if (cached && cached.expiresAt - Date.now() > 60_000) {
>     return cached.token;
>   }
>   const subjectToken = await getVercelOidcToken({
>     audience: `${ENTIRE_AUTH_URL}/api/authz/sts`,
>   });
>   const res = await fetch(`${ENTIRE_AUTH_URL}/oauth/token`, {
>     method: "POST",
>     headers: {
>       "content-type": "application/x-www-form-urlencoded",
>       authorization: "Basic " + btoa("entire-cli:"),
>     },
>     body: new URLSearchParams({
>       grant_type: "urn:ietf:params:oauth:grant-type:token-exchange",
>       subject_token_type: "urn:ietf:params:oauth:token-type:jwt",
>       subject_token: subjectToken,
>       audience: ENTIRE_AUTH_URL,
>       resource: SERVICE_ACCOUNT,
>     }),
>   });
>   if (!res.ok) {
>     throw new Error(`Couldn't exchange the Vercel token: ${res.status} ${await res.text()}`);
>   }
>   const body = await res.json();
>   cached = { token: body.access_token, expiresAt: Date.now() + body.expires_in * 1000 };
>   return cached.token;
> }
> ```
>
> Then use the token. For example, call the API:
>
> ```ts theme={null}
> import { getEntireToken } from "@/lib/entire";
>
> const res = await fetch("https://us.console.entire.io/api/v1/me", {
>   headers: { authorization: `Bearer ${await getEntireToken()}` },
> });
> ```
>
> To run the `entire` CLI, use a [Vercel Sandbox](#use-it-in-a-vercel-sandbox).
>
> #### Use It in a Vercel Sandbox
>
> The code that creates the sandbox exchanges the token. The sandbox gets only a placeholder `ENTIRE_TOKEN`, and its firewall adds the real token to requests to Entire. `ENTIRE_TELEMETRY_OPTOUT` and `ENTIRE_NO_AUTO_UPDATE` stop the CLI from calling other hosts, which the firewall blocks.
>
> ```ts theme={null}
> import { Sandbox } from "@vercel/sandbox";
> import { getEntireToken } from "@/lib/entire";
>
> const ENTIRE_AUTH_URL = "https://us.auth.entire.io";
>
> // A JWT whose only claim is the auth URL. The CLI reads the URL from it.
> const placeholder = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9."
>   + Buffer.from(JSON.stringify({ aud: ENTIRE_AUTH_URL })).toString("base64url")
>   + ".placeholder";
>
> const entirePolicy = (token: string) => ({
>   allow: { "*.entire.io": [{ transform: [{ headers: { authorization: `Bearer ${token}` } }] }] },
> });
>
> const sandbox = await Sandbox.create({
>   env: {
>     ENTIRE_TOKEN: placeholder,
>     ENTIRE_TELEMETRY_OPTOUT: "1",
>     ENTIRE_NO_AUTO_UPDATE: "1",
>   },
> });
>
> // Install the CLI before you restrict the network.
> await sandbox.runCommand("bash", ["-c", "curl -fsSL https://entire.com/install.sh | bash"]);
>
> await sandbox.update({ networkPolicy: entirePolicy(await getEntireToken()) });
>
> await sandbox.runCommand("bash", ["-lc", "entire repo clone /et/acme/web web"]);
> ```
>
> Call `sandbox.update` again before the token expires. `getEntireToken` returns a fresh token when the cached one has less than a minute left.
>
> > [!NOTE]
> >
> > To let the sandbox reach other hosts, such as a package registry, add each one to `allow`. Only the Entire hosts need the `transform`.
>
> If sign-in fails, see [Service Account Troubleshooting](https://docs.entire.com/guides/configuration/service-accounts-troubleshooting.md).

## Continue With

> [card] [Service Accounts](https://docs.entire.com/guides/configuration/service-accounts.md)
>
> Learn what a service account can access and how it signs in.

> [card] [Troubleshooting](https://docs.entire.com/guides/configuration/service-accounts-troubleshooting.md)
>
> Fix access, sign-in, and secret errors.
