Use a machine-to-machine (M2M) application when a workload must authenticate without a person: backend-to-backend calls, jobs, CI automation, or agents. Authdog registers a confidential OIDC client for the environment and uses OAuth 2.0 `client_credentials`; no browser session or interactive sign-in is involved.

## Create an M2M application

In the [Authdog console](https://console.authdog.com):

1. Create a new project or application.
2. Choose **Machine-to-machine** as its type.
3. Enter a descriptive name and, optionally, what the workload will access.
4. Create the application.
5. Copy the generated client ID and client secret before closing the dialog.

Creation provisions a default environment and registers a client authorized only for `client_credentials`, using `client_secret_basic` authentication. The client secret is shown once.

Use a separate M2M application per workload and environment. This gives each workload an independent credential lifecycle and avoids sharing production secrets with development jobs.

## Discover the token endpoint

Use the OIDC metadata for the environment or identity host and read its `token_endpoint`. Authdog's token endpoint path is `/oauth2/token`; discovery avoids hard-coding a deployment origin and continues to work with an environment [custom domain](/docs/custom-domains).

## Exchange credentials for a token

Send an `application/x-www-form-urlencoded` request. Client ID and secret use HTTP Basic authentication:

```bash
curl -X POST "$TOKEN_ENDPOINT" \
  -u "$AUTHDOG_CLIENT_ID:$AUTHDOG_CLIENT_SECRET" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=client_credentials"
```

Successful responses contain `access_token`, `token_type` (`Bearer`), `expires_in`, and scope `client_credentials`. `expires_in` comes from the registered client's access-token lifetime. Client-credentials exchanges return an access token only, not a refresh token.

## Call a protected service

Send the access token as a bearer token:

```http
Authorization: Bearer <access_token>
```

The receiving service must validate authentication and then enforce authorization for the operation. A valid machine token identifies a caller; it does not by itself grant every action.

## Security guidance

- Store client secrets in a secret manager, never source control, browser code, command history, or logs.
- Keep token exchange and API calls in trusted workloads.
- Use one client per workload and least-privilege authorization around the resources it calls.
- Cache access tokens only in memory and only until shortly before `expires_in`.
- On suspected exposure, stop using the client and replace its credentials. Do not wait for leaked access tokens to expire.
- Never use a human user's cookie or personal token for unattended automation.

The token endpoint rejects inactive or unknown clients, incorrect authentication methods, bad secrets, and clients not authorized for `client_credentials`.

## Operational notes

- Refresh by repeating the client-credentials exchange; no refresh token is issued.
- Add jitter when many instances refresh so they do not all exchange credentials simultaneously.
- Record client ID and workload name in audit context, but redact secrets and access tokens.
- Test development and production independently because clients and signing context are environment-scoped.
- If application creation succeeds but credential generation fails, create or inspect the client under **Security > Clients** in the console.

## Service accounts

Service accounts represent organization-owned automation with explicit scopes.
Public REST endpoints support lifecycle management:

- `GET /v1/service-accounts`
- `GET /v1/service-accounts/{id}`
- `POST /v1/service-accounts`
- `DELETE /v1/service-accounts/{id}`

Create with a descriptive `name`, optional `description`, and least-privilege
`scopes`. The response includes service-account metadata, `clientId`, and
`clientSecret`. The secret is credential material; capture it from the creation
response, store it in a secret manager, and never expose it to browser code.
Deleting a service account is the revocation path, so use a separate account per
workload so one compromise does not require rotating unrelated automation.

## Personal access tokens

A personal access token (PAT) delegates the current user's access to scripts
and developer tooling. It is not preferred for shared services because
ownership and lifecycle remain attached to a person.

- `GET /v1/personal-access-tokens`
- `POST /v1/personal-access-tokens`
- `POST /v1/personal-access-tokens/{id}/revoke`

The create request accepts `name`, optional `expiresAt`, and optional `scopes`.
Creation is the only operation that returns `fullToken`; later list responses
expose the prefix and metadata, not the secret. Set an expiry, choose narrow
scopes, and revoke the token when the task ends or its owner leaves.

Use:

- **M2M application** for OAuth-compatible workload tokens with a bounded
  lifetime.
- **Service account** for organization-owned automation managed through the
  Authdog API.
- **PAT** for one person's local script or developer tool.

## Related

- [Backend requests](/docs/backend#service-to-service-m2m): accepting machine tokens
- [Sessions and tokens](/docs/concepts/sessions-tokens#service-to-service-tokens): token model
- [Authorization](/docs/concepts/authorization): enforcing access after authentication
- [Deployments](/docs/deployments): environment isolation
- [Security](/docs/security): key and credential guidance
