How to Issue and Rotate AI-Agent Client Credentials
Mint a dedicated AI-agent credential, scope it to the right MCP tools and repos, and rotate the secret on a schedule without breaking the agent's session.
Why a Separate Credential Type
Chainsaw distinguishes three credential types in Access → Client credentials:
| Type | Used by | Notable defaults |
|---|---|---|
end-user | A developer’s CLI on a laptop | Short rotation window, single-device assumption, broad scope |
service-token | CI runners and headless build pipelines | Long rotation window, multi-host, scope tied to repos |
AI agent | Long-running agent processes (Claude Code, Cursor, GPT, custom agents) | Distinct audit prefix (actor_kind: ai_agent), scoped to MCP/read by default, supports rolling rotation without session interruption |
The reason for the third bucket is operational. Agents call the API constantly and unpredictably — the moment you rotate a service-token, the agent’s in-flight tool call fails and you have to reach into the agent’s config to re-paste a secret. The AI-agent type supports a rolling rotation window where the old and new secret are both valid for an overlap period, so the agent can pick up the new value at its own cadence.
Prerequisites
- Admin role.
- A target agent (Claude Code, Cursor, custom MCP client) ready to receive the credential.
Step 1: Mint the Credential
- Open Access → Client credentials → New.
- Type:
AI agent. - Name: something traceable. Convention:
agent--<team>--<purpose>(e.g.,agent--secops--triage-bot). - Scopes: start with
mcp:read. Addmcp:notifyonly if the agent needs to fireroute_violation_to_owner. Never addpolicy:writeorexception:writeto an AI-agent credential — Billy’s approval card pattern is the right shape for write actions, not direct API access. - Repository scope: which repositories the agent can ask about. Defaults to all; restrict to a subset if the agent serves a single team.
- Rotation policy: 30 / 60 / 90 days. Pick what matches your rotation runbook.
- Click Create. The
client_idandclient_secretare shown once — copy them now.

Step 2: Hand the Secret to the Agent
For Claude Code:
# In your shell rc
export CHAINSAW_AGENT_TOKEN="your-client-secret-here"
# Then restart the agent — settings.json picks up ${CHAINSAW_AGENT_TOKEN}
For Cursor / GPT, store the secret in the same place you keep other API keys (your OS keychain via the agent’s secret store, NOT a shared dotfile).
Step 3: Verify the Token Works
curl -X POST https://chain305.com/chainproxy/mcp \
-H "Authorization: Bearer $CHAINSAW_AGENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | jq '.result.tools | length'
A successful response returns 4. A 401 means the secret is wrong; a 403 means the secret is right but the scope is missing the requested tool.
Step 4: Rolling Rotation
When rotation day arrives:
- Add a new secret. Open the credential’s detail page → Rotate → choose rolling. A second
client_secretis issued. The first remains valid until the rotation window expires (default 24 hours). - Hand the new secret to the agent. Update the
CHAINSAW_AGENT_TOKENenv var, restart the agent. In-flight tool calls using the old secret continue to succeed. - Wait for the window. After 24 hours (or whatever you set), the old secret stops working. The dashboard shows a “rotation completed” indicator.
- Confirm with the audit log —
event=auth.token_usedshould show only the new credential’s hash for the past hour.
If you rotate too fast (agent restart hasn’t picked up new secret yet) the agent fails over to the old secret automatically until the window closes. You cannot accidentally lock yourself out by rotating.
Step 5: Revoke
Two flavors:
- Soft revoke (rolling): keeps the old secret alive for the rotation window. Use when you’ve handed out a new secret and want the old one to age out gracefully.
- Hard revoke: invalidates immediately. Use when the secret is leaked.
Both are exposed at Access → Credentials → ⋯ → Revoke. Hard revoke is irreversible — if you hard-revoke and the agent has not received a replacement, every in-flight tool call fails with 401 immediately.
Step 6: Audit What the Agent Did
Every MCP tool call is logged with the full JSON-RPC params:
curl -H "Authorization: Bearer $CHAINSAW_TOKEN" \
"https://chain305.com/chainproxy/api/audit?actor_kind=ai_agent&actor=$AGENT_CLIENT_ID&since=7d" \
| jq '.events[] | {time, tool: .params.name, args: .params.arguments}'
Routine queries dominate. Spot-check for surprises — an agent that was meant to read inventory but is suddenly hammering route_violation_to_owner with non-standard payloads is a signal worth a closer look.
Verification
- The credential appears in Access → Client credentials with
actor_kind: ai_agent. tools/listreturns four tools when called with the new secret.- After a rolling rotation, both old and new secrets work simultaneously for the rotation window, then only the new one.
- Audit log shows
auth.token_usedevents tagged to the rightclient_id.
Related Topics
- How to Connect Claude / Cursor / GPT via MCP — what the credential is for.
- How to Create and Manage Client Credentials — the broader credential model.
- How to Use Audit Logs to Track Consumption — the same audit pipeline; agent calls are first-class.