# Authenticate a backend

Discover OAuth settings and use an organization machine client to authenticate platform API requests.

Create an [automation client](/guides/deploy/automation-credentials) with the `invoke` profile for
an application that runs agents, or `observe` for a read-only integration. Keep its secret on your
backend. Never embed it in browser code or a mobile application.

Your service needs three configuration values: the platform API origin, client ID, and client
secret. For hosted Tanomis, the origin is `https://api.tanomis.com`. If you use `tanomis` in your
service, the [three environment variables](/guides/deploy/automation-credentials#give-tanomis-three-values)
handle the following steps automatically.

- Three values: the platform API origin, the client ID, and the client secret. Never in a
  browser or a mobile app.
- Discover the token endpoint from the platform; exchange the credentials with OAuth client
  credentials; send the token as a bearer with a tenant selector.
- Effective permissions are the intersection of the token's scopes and the client's current
  permissions; a denial is an access decision, not a reason to fetch more tokens.

## Discover authentication settings

Request the public configuration from your trusted platform origin:

```http
GET /v1/cli-config HTTP/1.1
Host: api.tanomis.com
```

The response's `m2m` object supplies `issuer`, `audience`, and `scopes`. If it is missing, machine
authentication is not available on that deployment. Fetch the issuer's OpenID Connect discovery
document at `issuer + /.well-known/openid-configuration` and read `token_endpoint`. For deployments
whose issuer is a base origin, `tanomis` also supports discovery at
`issuer + /oidc/.well-known/openid-configuration` if the first location is unavailable.

Do not substitute the audience for the platform origin. An audience is the identifier of the
resource receiving the token and need not be a reachable address. Discover it rather than
hardcoding a provider's domain or a hosted deployment's identifier.

## Exchange the credentials

Use your backend's HTTP or OAuth library to POST to the discovered token endpoint with HTTP Basic
authentication using the client ID and secret. Send form-encoded fields:

```text
Content-Type: application/x-www-form-urlencoded
Authorization: Basic <encoded-client-id-and-secret>

grant_type=client_credentials
resource=<discovered-audience>
scope=<space-separated-discovered-scopes>
```

The body above lists the fields separately for readability; your library must URL-encode them
as one form. Requesting a scope does not grant it: effective permissions are the intersection of
the token's scopes and the client's current permissions.

Use HTTPS for discovery and token requests, validate certificates, and do not forward credentials
through redirects. Read the returned `access_token`, `token_type`, and expiry in memory. Reuse an
unexpired token and obtain a new one before expiry; this flow does not use a human refresh token.
Keep token responses and authorization headers out of application logs.

## Call the platform

Send the token to the platform API origin and select the target tenant for tenant-scoped requests:

```http
GET /v1/agents HTTP/1.1
Host: api.tanomis.com
Authorization: Bearer <access-token>
X-Tenant-ID: <organization-tenant-id>
```

The tenant must be active and ready in the client's organization. Use the public platform API
for agent, session, and run requests. Do not send organization machine tokens directly to an
independent Registry endpoint.

Disabling or deleting the client, removing a scope, or offboarding the tenant can deny a request
while the token is still unexpired. Treat a permission denial as an access decision, not a reason
to endlessly fetch new tokens. Machines cannot call the human-only credential or tenant lifecycle
APIs to restore their own access.

## Where to go next

- [Invoke from your application](/guides/run/invoke-from-your-application): the six requests
  that run an agent.
- [Automation credentials](/guides/deploy/automation-credentials): profiles, rotation, revocation.
- [Platform API](/api): every endpoint.
