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

# Authentication

> Authenticate to the TrustGate control-plane API with an admin JWT or a machine credential access token.

The control-plane API accepts a Bearer token on almost every `/v1/...` route:

```http theme={null}
Authorization: Bearer <token>
```

| Method                           | Typical use                                                 |
| -------------------------------- | ----------------------------------------------------------- |
| **Admin JWT** (HS256)            | Self-hosted TrustGate, short-lived operator access          |
| **Machine access token** (RS256) | SaaS / Hybrid automation with `client_id` / `client_secret` |

System probes (`/healthz`, `/readyz`, `/__/version`, `/health`) do not require authentication.

## Admin JWT

Self-hosted and open-source deployments mint admin JWTs with `SERVER_SECRET_KEY`. See
[Server security](/trustgate/operate/server-security#admin-authentication) for claims,
signing, and rotation.

A console session token also works for interactive operators when you call the admin host
from a trusted environment. Prefer machine credentials for unattended automation on SaaS
and Hybrid.

## Machine credentials

A console-minted admin JWT expires and nobody renews it, which is fine for a script you run
by hand and useless for automation that has to keep working next week. **Machine credentials**
solve that: your automation holds a long-lived `client_id` / `client_secret` pair and
exchanges it for a short-lived access token whenever it needs one.

Each credential is bound to **one gateway** and carries an explicit set of scopes. A
credential issued for gateway A cannot read or change anything in gateway B, even when both
belong to the same team.

<Note>
  Machine credentials are issued by the NeuralTrust platform (SaaS and Hybrid). Self-hosted
  open-source TrustGate has no credential store — mint admin JWTs yourself as described in
  [Server security](/trustgate/operate/server-security#admin-authentication).
</Note>

### Create a credential

In the console, open **Settings → Agent Gateway → Credentials**, click **New credential**,
name it after the system that will use it, and pick the scopes it needs.

The client secret is displayed **once**. Copy it into your secret manager before closing the
dialog — it is stored only as a hash and cannot be shown again. If you lose it, rotate the
credential to get a new one.

### Scopes

| Scope                                  | Grants                                                      |
| -------------------------------------- | ----------------------------------------------------------- |
| `gateways:read`                        | Read the bound gateway.                                     |
| `consumers:read` / `consumers:write`   | List and manage [consumers](/trustgate/concepts/consumers). |
| `auths:read` / `auths:write`           | Manage [auth credentials](/trustgate/concepts/auth).        |
| `roles:read` / `roles:write`           | Manage [roles](/trustgate/concepts/roles).                  |
| `registries:read` / `registries:write` | Manage [registries](/trustgate/concepts/registries).        |
| `policies:read` / `policies:write`     | Manage [policies](/trustgate/policies/overview).            |

Creating and deleting gateways stays a console-only operation. Grant the narrowest set that
makes your automation work.

Catalog, playground, and config-sync listing routes require an interactive identity. Machine
credentials cannot call them even when the gateway binding is correct.

### Exchange the credential for a token

The token endpoint implements the OAuth2 `client_credentials` grant. Credentials go in an
HTTP Basic header, or as form fields if your client cannot set one.

```bash theme={null}
curl -X POST https://app.neuraltrust.ai/api/gateway/oauth/token \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -d grant_type=client_credentials
```

```json theme={null}
{
  "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6...",
  "token_type": "Bearer",
  "expires_in": 300,
  "scope": "gateways:read consumers:read consumers:write"
}
```

Invalid credentials always return the same generic `invalid_client` error, so the endpoint
cannot be used to discover which client IDs exist.

### Call the control-plane API

```bash theme={null}
curl https://<gateway-admin-host>/v1/gateways/$GATEWAY_ID/consumers \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```

The token is valid for 24 hours. Cache it and refresh on expiry (or on a `401`) rather than
minting one per request.

TrustGate rejects the request with `403` when the `gateway_id` in the path is not the
gateway the credential is bound to, or when the operation needs a scope the credential does
not hold. Reading a gateway that belongs to another tenant returns `404`, so the response
never reveals whether it exists.

See the [Overview](/trustgate/api/overview) for base URLs and the full endpoint list, then the
sidebar **API reference** for each operation.

### Rotate and revoke

**Rotate** issues a new secret and invalidates the old one immediately. Deploy the new
secret first if your automation cannot tolerate a failed token request; access tokens
already issued keep working until they expire.

**Revoke** stops new tokens from being issued at once. An access token the credential already
holds keeps working until it expires: TrustGate verifies tokens offline, with no introspection
call on each admin request, so the token lifetime is also the revocation window. Shorten
`ADMIN_M2M_MAX_TOKEN_TTL` if your deployment needs revocation to take effect sooner.

Both actions are recorded in the audit log, along with every token issued or denied, keyed
by credential ID. Secrets and tokens are never logged.
