Authdog
Log In

AI guide

AI Agent Security

AI agents should authenticate as workloads, not borrow a human session. Prefer a named Agents identity when the agent lives inside an existing project. Use a machine-to-machine application when the whole project is the workload. Both mint confidential OIDC clients on client_credentials. Authorization stays server-side. Agents is sales-gated. Until access is approved, the console page is a locked landing with Request access. See Support. Five-minute path: Agents quickstart.

Prerequisites

  • An Authdog project and environment.
  • Approved Agents access or an M2M application (below).
  • Client ID and client secret captured at creation. The secret is shown once.
  • A trusted server, worker, job, or agent runtime. Never put credentials in browser code.
  • An API or MCP server that validates bearer tokens and enforces authorization.

Use a separate client (or Agents entry) per workload and environment.

Implementation

1. Register the identity

Agents (preferred for a named agent in a web or MCP project): console Agents → Create new agent identity, or attach an existing client ID / spiffe:// / URI. SPIFFE and URI subjects are registry labels. The issuer kill switch applies when subject is the OIDC client_id.

M2M (whole project is a machine): Projects → Machine-to-machine. Same token grant, no Agents activity or tool allowlist.

2. Request a token

Discover token_endpoint from OIDC metadata (/oauth2/token). Send client credentials with HTTP Basic auth:

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"

The response contains access_token, token_type, and expires_in. No refresh token. Repeat the exchange before expiry.

Revoke in Agents blocks new tokens for client_id subjects. Outstanding JWTs stay valid until expiry unless the resource server runs trust-store enforce.

3. Send the token to the protected service

Authorization: Bearer <access_token>

For an MCP service, examples/mcp-auth-sample authenticates before the transport runs. @authdog/mcp-sdk is source-only (packages/mcp-sdk), not on npm. It verifies JWTs through JWKS and can check issuer, audience, scopes, and the trust store.

4. Layer the boundary

Authenticate every request before dispatch. Reject the wrong issuer or audience. Require a baseline scope. Apply narrower checks at sensitive tools. Identity is input to authorization, not blanket permission.

5. Cache carefully

Keep an access token only in trusted process memory until shortly before expires_in. Add jitter when many instances refresh.

Security considerations

  • Store client secrets in a secret manager, never in prompts, command history, or logs.
  • Least privilege: service-wide scope (mcp:invoke) vs tool scopes (mcp:admin).
  • Do not give unattended automation a human cookie or personal token.
  • Record client ID and workload name in audit context. Redact secrets and complete tokens.
  • On exposure, revoke the Agents entry or replace client credentials. Do not wait for issued tokens to expire if you can enforce the trust store.

Validation checklist

  • Agent obtains a token with client_credentials, without a browser or user session.
  • Invalid client credentials are rejected by the token endpoint.
  • Protected service rejects missing, expired, or wrong-audience tokens.
  • Baseline scope failure prevents request dispatch.
  • Sensitive operations enforce their own narrower scope.
  • Development token does not grant production access.
  • Logs contain workload identifiers but no secrets or complete tokens.

Troubleshooting

Token exchange fails: confirm the client is active, uses the expected auth method, and is authorized for client_credentials. If you revoked an Agents row, new tokens fail for client_id subjects.

Protected service returns 401: inspect issuer, JWKS URI, audience, and bearer-header formatting. A 403 means authentication succeeded but a required scope is missing.

Agents page is locked: request access. The module is sales-gated.

Failures occur only across environments: verify the agent uses the client and endpoint for the same environment as the protected service.

Next steps