Authentication
How to authenticate with Agent Platform and secure your MCP server.
Webhook Source Tokens
Each webhook source has a unique token used to authenticate incoming events. Include it in the X-Webhook-Token header.
bash
curl -X POST https://agent-platform.example.com/webhooks/events \
-H "Content-Type: application/json" \
-H "X-Webhook-Token: whk_abc123def456" \
-d '{"event_type": "invoice.uploaded", "payload": {...}}'| Field | Type | Description |
|---|---|---|
| X-Webhook-Token* | string | The webhook source token. Starts with whk_ prefix. |
Webhook tokens are sensitive credentials. Store them in your secrets manager and never commit them to source control. Rotate tokens immediately if compromised.
MCP Server Authentication
Agent Platform supports OAuth-protected MCP servers and temporary static bearer tokens during migration.
Protected MCP request
POST /mcp HTTP/1.1
Host: your-app.example.com
Content-Type: application/json
Authorization: Bearer eyJhbGciOi...
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}Protected HTTP MCP servers should expose OAuth Protected Resource Metadata and return a WWW-Authenticate challenge on unauthenticated requests. Agent Platform can use that challenge to discover the resource URL, request a scoped Ory token, and retry the MCP session.
OAuth challenge
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://your-app.example.com/mcp/.well-known/oauth-protected-resource", error="invalid_token"
Content-Type: text/plain
missing Authorization headerProtected resource metadata
{
"resource": "https://your-app.example.com/mcp",
"authorization_servers": ["https://auth.drj.ninja/"],
"scopes_supported": ["mcp:your-service"]
}Skills that still define an Authorization header continue to work as a migration fallback. Ory-backed MCP servers should validate audience/resource, issuer, expiry, org or tenant claims, and required scopes on every request.
Platform MCP Authentication
Agent Platform also exposes its own /mcp endpoint for remote management clients.
Management MCP request
POST /mcp?tenant=drj HTTP/1.1
Host: agent-platform-api.external.drj.ninja
Content-Type: application/json
Authorization: Bearer eyJhbGciOi...
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}| Field | Type | Description |
|---|---|---|
| mcp:platform.read | OAuth scope | Read management tools. |
| mcp:platform.write | OAuth scope | Write management tools when paired with a tenant admin role. |
| mcp:platform | OAuth scope | Legacy rollout scope accepted for read and write tools. |
| tenant* | query/header | Tenant slug, also accepted as X-DRJ-Tenant. |
The platform MCP endpoint rejects caller-supplied organization headers when tenant control-plane resolution is enabled. Tenant context is resolved from the validated token and selected tenant slug.
API Authentication
The ConnectRPC management API accepts Ory/Hydra access tokens.
bash
TOKEN=$(curl -s -X POST https://auth.drj.ninja/oauth2/token \
-u "$ORY_CLIENT_ID:$ORY_CLIENT_SECRET" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d grant_type=client_credentials \
-d audience=https://agent-platform-api.external.drj.ninja \
-d scope=agent-platform:write | jq -r '.access_token')
# Use the token with the API
curl https://agent-platform-api.external.drj.ninja/agentplatform.v1.AgentPlatformService/ListAgents \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-H "X-DRJ-Tenant: drj" \
-d '{}'Ory access tokens are validated through Hydra introspection. Tenant authorization is resolved through tenant-control-plane from the selected tenant slug and the validated token; do not send X-Org-ID as an authorization scope. Webhook events use source tokens instead of user OAuth tokens.