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

> ## Agent Instructions
> These docs cover three products: TrustGate (AI agent gateway), TrustGuard (runtime security), and TrustTest (AI red teaming). Start from each product overview for the definition and How it works. Prefer the .md URL next to a page in /llms.txt when you need the full article. Use /llms-full.txt for a single-file dump of the site.

# Authentication

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

The control-plane API lives on the **Admin** plane (`8080` self-hosted; SaaS and Hybrid
hostnames come from console **Settings**). Almost every `/v1/...` route accepts a Bearer
token:

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

## What is not in the reference

The rest of this **API reference** group is generated from OpenAPI and covers the Admin
plane only. The two data planes are absent from it by design: they take an application's
own credentials rather than these tokens, and their routes are fixed rather than one per
resource.

| Plane | What answers on it | Described in |
| - | - | - |
| **Proxy** (`8081`) | `/{application}/v1/…`, in whichever dialect your client speaks. | [Endpoints](/trustgate/endpoints/chat) |
| **MCP** (`8082`) | `/{application}/mcp`, streamable HTTP. `/store/mcp` is the fixed [Employee portal](/trustgate/mcp/store) endpoint. | [Connect an agent](/trustgate/mcp/connect) |
| **MCP**, sign-in | `/.well-known/oauth-protected-resource`, `/.well-known/oauth-authorization-server`, `/.well-known/jwks.json`, `/oauth/register`, `/oauth/authorize`, `/oauth/callback`, `/oauth/token` — the handshake an MCP client runs by itself. | [Authentication](/trustgate/concepts/auth) |

The MCP plane also answers `/whoami` and `/{application}/connections`, which the
[SDK](/trustgate/mcp/connect#your-own-code-the-trustgate-sdk) calls to resolve what a key
reaches and what an end user still has to connect. They exist for it; a client that holds
its URL and handles **consent required** needs neither.

On the Admin plane itself, catalog routes and the internal routes the console calls for
itself are also outside this reference — see [Scopes](#scopes).

## Admin JWT

Self-hosted and open-source deployments mint HS256 admin JWTs with `SERVER_SECRET_KEY`:

```http theme={null}
Authorization: Bearer <admin-jwt>
```

Anyone who can sign with that key can administer every gateway — keep it secret, rotate it
like any signing key, and mint short-lived tokens. 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.

Machine credentials are issued by the NeuralTrust platform (SaaS and Hybrid). Self-hosted
open-source TrustGate has no credential store — mint admin JWTs with `SERVER_SECRET_KEY`
as described above.

### Create a credential

In the console, open **Settings → Agent Gateway → Admin API**, 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. |
| `applications:read` / `applications:write` | List and manage [applications](/trustgate/access/applications). |
| `auths:read` / `auths:write` | Manage [auth credentials](/trustgate/concepts/auth). |
| `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 routes, and the internal routes the console calls for itself, require an
interactive identity. They are not in this reference, and 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.

<CodeGroup>
  ```python Python theme={null}
  import requests

  token = requests.post(
      "https://app.neuraltrust.ai/api/gateway/oauth/token",
      auth=(CLIENT_ID, CLIENT_SECRET),
      data={"grant_type": "client_credentials"},
  ).json()
  ```

  ```ts TypeScript theme={null}
  const res = await fetch("https://app.neuraltrust.ai/api/gateway/oauth/token", {
    method: "POST",
    headers: {
      Authorization: "Basic " + Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString("base64"),
      "Content-Type": "application/x-www-form-urlencoded",
    },
    body: "grant_type=client_credentials",
  })
  const token = await res.json()
  ```

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

```json theme={null}
{
  "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6...",
  "token_type": "Bearer",
  "expires_in": 300,
  "scope": "gateways:read applications:read applications: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

<CodeGroup>
  ```python Python theme={null}
  requests.get(
      f"https://<gateway-admin-host>/v1/gateways/{GATEWAY_ID}/applications",
      headers={"Authorization": f"Bearer {token['access_token']}"},
  ).json()
  ```

  ```ts TypeScript theme={null}
  const apps = await fetch(`https://<gateway-admin-host>/v1/gateways/${GATEWAY_ID}/applications`, {
    headers: { Authorization: `Bearer ${token.access_token}` },
  })
  await apps.json()
  ```

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

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.

Each operation is in the **API reference** below this page.

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


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.