Authdog

Machine Identity

Last updated Sep 9, 2026
View as Markdown

Pick one non-human identity. Do not stack them for the same workload.

Use this When Where
M2M application The whole project is a backend, job, or CI workload. No human users in that project. Projects → Machine-to-machine
Agents entry A named AI agent or workload calls APIs or MCP tools inside an existing project. You need verify, revoke, allowed tools, and activity. Agents
Service account Organization-owned automation managed through the Authdog REST API, not the console Agents module. GET/POST/DELETE /v1/service-accounts
Personal access token One person's local script or developer tool. Lifecycle stays attached to that person. GET/POST /v1/personal-access-tokens

Agents are not users. Never put a human cookie or personal token in an unattended runtime.

Machine-to-machine application

Use an M2M application when a workload must authenticate without a person: backend-to-backend calls, jobs, or CI. Authdog registers a confidential OIDC client for the environment and uses OAuth 2.0 client_credentials. No browser session.

Create an M2M application

In the Authdog console:

  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. The client secret is shown once.

Use a separate M2M application per workload and environment so one compromise does not rotate unrelated automation.

Discover the token endpoint

Read token_endpoint from the environment's OIDC metadata. Authdog's token path is /oauth2/token. Discovery keeps working with a custom domain.

Exchange credentials for a token

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. No refresh token — repeat the exchange before expiry.

Call a protected service

Authorization: Bearer <access_token>

The receiving service must validate the token, then enforce authorization. A valid machine token identifies a caller; it does not grant every action.

If application creation succeeds but credential generation fails, create or inspect the client under Authentication > Clients.

Agents (named workloads)

When the caller is an AI agent (or a workload you want to verify, scope, and revoke independently of the project type), register it in Agents.

Create new agent identity provisions a confidential OIDC client the same way M2M does, then writes a trust-store entry whose subject is that client ID. Register existing identity attaches an existing client ID, SPIFFE ID, or URI.

Revoke in Agents is the issuer kill switch: a revoked machine identity gets no token. Pin the tool manifest if the agent talks to MCP so rug-pull drift can raise a Lidar Signal.

Public REST still lives under the trust-store path:

/v1/tenants/{tenantId}/environments/{environmentId}/mcp/trust-store

List, create, verify, revoke, and manage keys there. Console GraphQL (mcpTrustStoreEntries and related mutations) is what the Agents module calls.

Service accounts

Service accounts represent organization-owned automation with explicit scopes. They are a separate REST resource, not rows in Agents.

  • 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 create response includes clientId and clientSecret. Capture the secret once. Deleting the account is the revocation path.

Personal access tokens

A PAT delegates the current user's access to scripts and developer tooling. Do not use it for shared services.

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

Create accepts name, optional expiresAt, and optional scopes. Only create returns fullToken. Set an expiry and revoke when the task ends or the owner leaves.

Security guidance

  • Store client secrets in a secret manager, never source control, browser code, command history, or logs.
  • Keep token exchange in trusted workloads.
  • One client (or Agents entry) per workload. Least privilege on scopes and tools.
  • Cache access tokens only in memory, only until shortly before expires_in. Add jitter when many instances refresh.
  • On suspected exposure, revoke or replace credentials. Do not wait for leaked access tokens to expire.
  • Record client ID and workload name in audit context. Redact secrets and complete tokens.
  • Test dev and prod independently. Clients and signing context are environment-scoped.

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