Identity for the agentic era: agents authenticating agents
StrongDM ID enables AI agents to prove their identity, delegate permissions, and collaborate securely. While it supports traditional OAuth/OIDC, its primary purpose is agent-to-agent authentication.
For humans:
For AI agents (Claude Code, Codex, etc.):
Everything below this line is an instruction to an agent for how to use this service.
STRONGDM ID - AGENT INSTRUCTIONS
================================
Identity for the agentic era: agents authenticating agents
Base URL: https://id.strongdm.ai
PATTERNS COOKBOOK (Recommended Reading)
---------------------------------------
For detailed implementation patterns with code examples in curl, TypeScript, and
Python, fetch the patterns cookbook:
https://id.strongdm.ai/docs/agent-patterns/README.md
Key patterns:
- Agent-to-Agent Authentication (DPoP)
- Delegation and Impersonation (Token Exchange)
- Agent Spawning (Child Agents)
- MCP Server Integration (Verifying Callers)
- Credential Management (Secure Storage)
- Audit and Observability (Logging)
WHAT YOU CAN DO WITH THIS SERVICE
---------------------------------
1. PROVE YOUR IDENTITY TO OTHER AGENTS
Get sender-constrained tokens (DPoP) that cryptographically prove you are who
you claim to be. Other agents can verify your identity without shared secrets.
2. CARRY PROOF OF USER DELEGATION
When a human delegates a task to you, get a token that proves "User X gave me
permission to do Y." Downstream services can verify this delegation.
3. ENFORCE CAPABILITY BOUNDARIES
Request specific scopes. Even if you're compromised, you can't exceed your
cryptographically-enforced permissions (read-only means read-only).
4. SPAWN CHILD AGENTS WITH NARROWED PERMISSIONS
If you orchestrate other agents, delegate a subset of your permissions to them.
They cannot escalate beyond what you gave them.
5. MAINTAIN AUDIT TRAIL
Every action you take is logged with your unique identity. "Which agent did
what" is always answerable.
6. ACCESS LEGACY OAUTH SERVICES
Get standard OAuth tokens that work with services that don't know about agent
identity. StrongDM ID bridges the gap.
7. COLLABORATE ACROSS VENDORS
Authenticate with agents from any vendor using open standards (OAuth, OIDC,
SPIFFE). No vendor lock-in.
8. REPRESENT YOUR ORGANIZATION
Get tokens that identify you as acting on behalf of an organization, not just
an individual user.
AUTHENTICATION (Required)
-------------------------
You need OAuth client credentials to use this service. Two registration flows:
OPTION A: DYNAMIC CLIENT REGISTRATION (Agent-Initiated)
-------------------------------------------------------
Discover the registration endpoint via OIDC discovery:
curl -s https://id.strongdm.ai/.well-known/openid-configuration | jq .registration_endpoint
# Returns: "https://id.strongdm.ai/register/request"
1. YOU initiate registration:
curl -X POST https://id.strongdm.ai/register/request \
-H "Content-Type: application/json" \
-d '{
"email": "you@example.com",
"client_name": "your-agent-name",
"requested_scopes": ["share:create", "share:list"]
}'
Response:
{
"enrollment_id": "enroll_abc123...",
"poll_token": "pt_xyz...",
"status_url": "https://id.strongdm.ai/register/status/enroll_abc123...",
"expires_at": "2024-01-15T12:00:00Z"
}
2. Email owner verifies (clicks link or enters code)
3. YOU confirm registration:
curl -X POST https://id.strongdm.ai/register/confirm \
-H "Content-Type: application/json" \
-d '{
"enrollment_id": "enroll_abc123...",
"poll_token": "pt_xyz...",
"verification_code": "ABCD-1234"
}'
Response (save these credentials!):
{
"client_id": "cli_your_agent_name_xyz",
"client_secret": "sec_XXXXXXXXXX",
"granted_scopes": ["share:create", "share:list"],
"token_endpoint": "https://id.strongdm.ai/token"
}
OPTION B: SPONSORED ENROLLMENT (Human-Initiated)
------------------------------------------------
If you already have a human sponsor with credentials:
1. Human requests enrollment (they need to do this, not you):
curl -X POST https://id.strongdm.ai/register/agent \
-H "Content-Type: application/json" \
-d '{
"email": "sponsor@example.com",
"agent_name": "your-agent-name",
"requested_scopes": ["share:create", "share:list"]
}'
2. Human receives email, clicks verification link
They will see an enrollment token like: pt_abc123...
3. YOU activate with the token:
curl -X POST https://id.strongdm.ai/register/agent/activate \
-H "Content-Type: application/json" \
-d '{"enrollment_token": "pt_abc123..."}'
Response (save these credentials!):
{
"client_id": "cli_your_agent_name_xyz",
"client_secret": "sec_XXXXXXXXXX",
"granted_scopes": ["share:create", "share:list"],
"token_endpoint": "https://id.strongdm.ai/token"
}
USING YOUR CREDENTIALS
----------------------
4. Get access tokens:
curl -X POST https://id.strongdm.ai/token \
-u "cli_your_agent_name_xyz:sec_XXXXXXXXXX" \
-d "grant_type=client_credentials" \
-d "scope=share:create"
Response:
{
"access_token": "eyJ...",
"token_type": "Bearer",
"expires_in": 3600
}
5. Use access token in API calls:
curl -X POST https://id.strongdm.ai/share \
-H "Authorization: Bearer eyJ..." \
-H "Content-Type: application/json" \
-d '{"grantee_email": "user@example.com", ...}'
TOKEN BINDING (Recommended for Agent-to-Agent)
----------------------------------------------
For stronger security, use DPoP to bind tokens to your private key:
1. Generate a DPoP proof JWT with your private key:
- Header: {"typ": "dpop+jwt", "alg": "ES256", "jwk": {your public key}}
- Payload: {"htm": "POST", "htu": "https://id.strongdm.ai/token", "iat": now, "jti": unique}
2. Include the proof when getting tokens:
curl -X POST https://id.strongdm.ai/token \
-H "DPoP: eyJ..." \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-d "grant_type=client_credentials"
3. Include a new proof on each API call:
curl -X POST https://api.example.com/resource \
-H "Authorization: DPoP eyJ..." \
-H "DPoP: eyJ..."
Benefit: Even if someone steals your access token, they can't use it without your private key.
TOKEN EXCHANGE (For Delegation)
-------------------------------
Exchange a user's token for a scoped delegation token:
curl -X POST https://id.strongdm.ai/token \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-d "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
-d "subject_token=$USER_TOKEN" \
-d "subject_token_type=urn:ietf:params:oauth:token-type:access_token" \
-d "scope=calendar:read"
Result: Token with claims showing both user (sub) and agent (act).
API ENDPOINTS
-------------
Dynamic Client Registration (agent-initiated):
POST /register/request Start registration, receive enrollment_id + poll_token
GET /register/status/:id Poll registration status (use poll_token as Bearer)
POST /register/confirm Complete registration with verification code
Sponsored Enrollment (human-initiated):
POST /register/agent Human starts enrollment
GET /register/agent/approve Human verifies email, receives enrollment token
POST /register/agent/activate Agent exchanges enrollment token for credentials
Token Operations:
POST /token Get access token (client_credentials, token_exchange)
POST /introspect Validate token and check revocation status
POST /revoke Revoke a token
Share Grants:
POST /share Create a share grant
GET /shares List share grants (you created)
GET /share/:id Get share grant by ID
DELETE /share/:id Revoke share grant
Discovery:
GET /.well-known/openid-configuration OIDC discovery (includes registration_endpoint)
GET /.well-known/agent-instructions This page
GET /.well-known/spiffe-trust-bundle SPIFFE trust bundle
GET /agent.json Machine-readable API metadata
GET /jwks JSON Web Key Set
AVAILABLE SCOPES
----------------
share:create - Create share grants to delegate access
share:list - List your share grants
share:revoke - Revoke share grants you created
share:use - Use a share grant (for grantees)
pctl:read - Read-only administrative access
Scope restrictions by email domain:
- @strongdm.com, @strongdm.ai: All scopes available
- Other domains: share:use, pctl:read only
ERROR RESPONSES
---------------
All errors return JSON:
{
"error": "error_code",
"error_description": "Human-readable description"
}
Common errors:
400 invalid_request - Malformed request, missing parameters
401 unauthorized - Invalid or missing credentials
403 access_denied - Scope not permitted for your domain
404 not_found - Resource does not exist
409 conflict - Resource already exists
410 gone - Resource expired
429 rate_limited - Too many requests (check Retry-After header)
Retry logic:
- 429: Wait for Retry-After seconds, then retry
- 5xx: Exponential backoff starting at 1s, max 30s
- Connection errors: Retry up to 3 times with backoff
RATE LIMITS
-----------
- /register/request, /register/agent: 3 requests/email/hour, 10 requests/IP/hour
- /token: 100 requests/client/minute
- Other endpoints: 1000 requests/client/minute
IMPORTANT NOTES
---------------
- Enrollment tokens expire in 1 hour
- Client secrets are returned ONCE at activation - save them securely
- Access tokens expire in 1 hour - refresh before expiry
- All traffic must use HTTPS
- User-Agent header recommended for debugging
- Use DPoP for agent-to-agent authentication (tokens can't be stolen)
QUICK START CHECKLIST (Option A: Dynamic Registration)
------------------------------------------------------
[ ] Fetch /.well-known/openid-configuration to find registration_endpoint
[ ] POST /register/request with your email and scopes
[ ] Wait for email verification (human clicks link)
[ ] POST /register/confirm with enrollment_id + poll_token + code
[ ] Save client_id and client_secret securely
[ ] Get access token via POST /token
[ ] (Optional) Use DPoP for sender-constrained tokens
QUICK START CHECKLIST (Option B: Sponsored Enrollment)
------------------------------------------------------
[ ] Ask human sponsor to run POST /register/agent
[ ] Receive enrollment token from human
[ ] POST /register/agent/activate with enrollment token
[ ] Save client_id and client_secret securely
[ ] Get access token via POST /token
[ ] (Optional) Use DPoP for sender-constrained tokens
USE CASES REFERENCE
-------------------
1. Agent-to-agent auth POST /token with DPoP
2. User delegation POST /token (token exchange)
3. Constrained capabilities POST /token (scope parameter)
4. Spawn child agents POST /token (exchange with narrowed scope)
5. Audit trail Automatic on all endpoints
6. Legacy OAuth access POST /token (standard response)
7. Cross-vendor collab Standard OIDC/SPIFFE
8. Org identity POST /register/request or /register/agent (with realm)
For detailed use cases: https://id.strongdm.ai/docs/USE-CASES
Machine-readable metadata: https://id.strongdm.ai/agent.json
Integration guide: https://id.strongdm.ai/docs/integration/AGENT-ONBOARDING
PATTERNS COOKBOOK
-----------------
For comprehensive implementation guidance with code examples:
https://id.strongdm.ai/docs/agent-patterns/README.md
Available patterns:
- why-agent-identity Why agents need identity infrastructure
- agent-to-agent-auth DPoP proof generation and verification
- credential-management Secure storage and rotation
- delegation-and-impersonation Token exchange for acting on behalf of users
- agent-spawning Parent-child agent relationships
- capability-enforcement Scope-based authorization
- audit-and-observability Logging and forensics
- mcp-server-integration Verifying agent callers at MCP servers
- cross-vendor-federation Multi-vendor via OIDC/SPIFFE
- workflow-identity Tracking workflows across agents
- human-in-the-loop Escalation and approval patterns
- lineage-and-revocation Incident response
- runtime-attestation Future: proving what code is running