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

# Authentication

> Choose a credential, configure it for the SDK, CLI, or HTTP API, and resolve authorization errors.

Every Antigen request is authorized against an organization. There are two credential kinds, and
which one you want depends on whether a person or an application is acting.

| Credential           | Use it for                             | Sent as                         |
| -------------------- | -------------------------------------- | ------------------------------- |
| Organization API key | Applications, services, and automation | `x-api-key`                     |
| User access token    | An interactive member at a terminal    | `authorization: Bearer <token>` |

API keys begin with `atg_sk_` and belong to the organization rather than to the person who created
them. Your organization administrator issues and revokes them. An interactive member does not need a
key at all: `antigen login` stores a user access token for the CLI.

## Roles

Organization roles are admin, member, and read-only. Admins manage membership and API keys, members
create and operate Runs, and read-only members read Runs and findings without creating them.

Neither knowing a target value nor holding a Run ID grants access. Every request is authorized in the
caller's organization context, which is also why the safe response to a permission error is to fix
the permission rather than to create a second Run.

If the approved target list is empty, a target is rejected, or a request is refused, stop rather than
editing a target string or borrowing another organization's credential. Ask your administrator to
verify membership and the credential, and request a target change from Antigen if the target you need
is absent.

## Configure a credential

Read the key from your secret source at startup. Keep it out of URLs, source files, command
arguments, and logs, where shell history and process listings expose it.

From TypeScript:

```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
import Antigen from "@antigenco/sdk";

const apiKey = process.env.ANTIGEN_API_KEY;
if (!apiKey) throw new Error("Set ANTIGEN_API_KEY to an organization API key.");

const antigen = new Antigen(apiKey);
```

From the CLI, sign in once as a member. The organization ID is a UUID:

```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
antigen login --organization-id 00000000-0000-0000-0000-000000000000
```

Over HTTP, send the key in `x-api-key` on every request:

```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --fail-with-body --silent --show-error \
  -H "x-api-key: $ANTIGEN_API_KEY" \
  https://api.antigen.sh/v1/targets | jq .
```

The SDK also accepts a user access token through its object form. Pass exactly one of `apiKey` and
`accessToken`; see [`new Antigen`](/sdk/typescript#new-antigen) for the full option set.

## Confirm it works

The `atg_sk_` prefix identifies the credential kind, not its validity, expiry, or scope, so a shape
check cannot tell you whether a key still works. Read your approved targets instead. It is the
cheapest authenticated call and it returns something you need anyway.

Use `antigen targets`, `GET /v1/targets`, or `getApprovedTargets()`. An empty list means the
credential authenticated but your organization has no approved target yet, which is a question for
your administrator rather than an integration bug.

## Scopes

A credential carries scopes, and each endpoint requires one:

| Scope           | Grants                                                       |
| --------------- | ------------------------------------------------------------ |
| `targets:read`  | Reading the approved target list.                            |
| `runs:read`     | Listing Runs, reading one Run, and streaming its events.     |
| `runs:write`    | Creating Runs, sending guidance, and every lifecycle action. |
| `findings:read` | Reading a Run's findings.                                    |

Scopes are checked per request, so a credential that can create a Run cannot necessarily read its
findings. Grant the narrowest set each integration needs.

## Resolve an authorization error

| Code                  | HTTP  | Meaning                                                  | Do this                                                             |
| --------------------- | ----- | -------------------------------------------------------- | ------------------------------------------------------------------- |
| `UNAUTHENTICATED`     | `401` | No recognizable credential was presented.                | Check the header name, then re-read the key or run `antigen login`. |
| `FORBIDDEN`           | `403` | The credential is valid but lacks the required scope.    | Use a credential carrying the scope in the table above.             |
| `TARGET_NOT_APPROVED` | `400` | A submitted target is not approved for the organization. | Re-read the approved list rather than editing the rejected target.  |
| `RUN_NOT_FOUND`       | `404` | The Run is not visible to this credential.               | Confirm the credential's organization before assuming it is gone.   |

None of these are fixed by retrying or by starting a new assessment. A Run ID is a locator, not a
credential, so possession of an ID grants nothing and a permission problem follows you to the next
Run. Fix the credential and recover the existing assessment through its saved ID.

A Run that belongs to another organization is reported as `RUN_NOT_FOUND`, the same answer as an ID
that was never issued. The two are not distinguishable from outside, so a caller cannot use a Run ID
to discover whether it is real. Treat this response as a question about which credential you are
holding, not as proof that the assessment was deleted.

Keep the `requestId` from any error response with the saved Run ID. It lets support identify the
failing request without exposing the credential.

Related: [Get started](/getting-started), [Reliability and security](/reliability-security), and the
[TypeScript SDK](/sdk/typescript), [CLI](/cli), and [HTTP API](/http-api) references.
