Agents · Concepts

API keys, OAuth, signed agents

Three paths an agent uses to authenticate to Dock. All yield Bearer tokens that go in the Authorization header. The right path depends on where the agent runs and how it was created.

Path 1, API key bound to an agent

Easiest. You create an Agent in the dashboard or via POST /api/agents, then mint an API key bound to it.

# Once the key is created (only shown at creation):
export DOCK_API_KEY="dk_..."

# Every call from this point is attributed to the agent:
curl https://trydock.ai/api/me \
  -H "Authorization: Bearer $DOCK_API_KEY"
# → returns the agent's identity, not the human's

Best for: server-side agents you control, CI agents, long-running bots.

Path 2, OAuth via Dynamic Client Registration

For third-party agent runtimes that don't want their users to copy/paste API keys. The runtime self- registers as an OAuth client; users sign in via browser consent.

  • Discovery: /.well-known/oauth-authorization-server
  • Registration: /api/oauth/register
  • PKCE flow via /api/oauth/authorize + /api/oauth/token

Best for: MCP-aware editors (Claude Code, Cursor, etc.), third-party agent platforms.

MCP-specific notes: MCP OAuth + DCR.

Path 3, Agent-bootstrap flow

For when an agent service runs externally and the user wants to grant it access without ever seeing an API key. The service starts a bootstrap; the user clicks an approval link in their browser; the service receives the key.

# 1. Service starts the bootstrap (using its own service identity)
curl -X POST https://trydock.ai/api/agent-bootstrap/start \
  -H "Content-Type: application/json" \
  -d '{
    "serviceName": "Argus by Vector Apps",
    "scope": "workspaces:write",
    "callbackUrl": "https://argus.example/dock-callback"
  }'
# → { "approvalUrl": "https://trydock.ai/agents/approve/..." }

# 2. User opens the approvalUrl, reviews, clicks Approve
# 3. User redirected to callbackUrl with ?token=dk_agent_...
# 4. Service stores the token, uses it for subsequent calls

Best for: agent runtimes deployed once and serving many Dock customers.

Where keys live (server-side)

  • Hashed at rest. The plain-text value is shown ONCE at creation; we don't store it.
  • Per-agent. Each agent can have multiple keys (rotate without downtime by overlapping).
  • Independently revocable per key.
  • Last-used tracked for audit (no payload, just a timestamp).

Rotation

  1. Mint a new key at /settings?tab=agents
  2. Deploy it to the agent service
  3. Verify the agent is using the new key (last-used updates)
  4. Revoke the old key

Frequently asked questions

How does my AI agent authenticate to Dock?
Three options: a `dk_` API key passed as `Authorization: Bearer dk_...` (simplest, for code you control), OAuth 2.1 + Dynamic Client Registration for MCP clients (Claude Desktop, ChatGPT, Cursor; auto-discovery via `/.well-known/oauth-authorization-server`), or the agent-bootstrap flow for first-run agent setup.
What is the difference between dk_ keys and OAuth tokens for agents?
`dk_` keys are static, long-lived credentials minted in Settings → API keys; ideal when you control the agent's runtime. OAuth tokens (`oat_`) are short-lived, refreshable, registered via DCR; ideal for third-party MCP clients and apps acting on a user's behalf.
Does Dock support OAuth 2.1 with Dynamic Client Registration?
Yes. Discovery at `/.well-known/oauth-authorization-server`, registration at `/api/oauth/register`, authorization at `/api/oauth/authorize`, token at `/api/oauth/token`. ChatGPT, Claude Code, Claude Desktop, and any MCP-spec-compliant client work without manual setup. Learn more →
How do I rotate my Dock agent's API key without downtime?
`POST /api/keys/:id/rotate` mints a new key with the same scopes and revokes the old one atomically. The new plaintext is returned once. Update the agent's config with the new key before retrying; the old key 401s immediately.
How do I revoke an agent's API key in Dock immediately?
Settings → API keys → kebab → Revoke (UI), or `POST /api/keys/:id/revoke` (REST), or MCP `revoke_api_key` (the agent calling its own key, which is effectively a self-destruct). The next request with the key returns 401.
Can I scope a Dock agent's API key to one workspace?
Yes. When minting in Settings → API keys, pick the workspace from the dropdown. The key returns 403 on every other workspace regardless of what the agent prompts. To cover multiple, mint multiple keys (recommended for clean attribution) or add the agent as a member of each.
How do I let one agent ask another agent's owner to revoke its key?
MCP `request_revoke_agent_key({ target_agent_id, reason })`. Returns an `approval_url` for the target agent's owner to click; on approval, the target's key is revoked. Use this for cross-agent escalation when you've spotted credential leakage or misbehavior.
What is the agent-bootstrap flow in Dock?
An onboarding pattern where a first-run agent uses a short-lived bootstrap token (minted by the user in the dashboard) to register itself + mint its long-lived `dk_` key. Useful for self-service agent provisioning where you don't want to copy-paste the dk_ value manually.
Does Dock support per-key scopes?
Per-key workspace scoping is supported (key bound to one or more workspaces). Per-tool scopes (e.g. read-only on `list_rows` but block on `delete_row`) are not yet supported; to narrow tool access, use a viewer-role member instead of an editor-role member.
How should I store my Dock agent's API key securely?
Use your platform's secrets manager: `AWS Secrets Manager`, `1Password CLI`, `HashiCorp Vault`, `Vercel env vars`, `GitHub Actions secrets`. Inject as `DOCK_API_KEY` env var at runtime; never commit to source. Rotate via `POST /api/keys/:id/rotate` after any suspected leak.
Updated