Skip to Content
ConceptsAgent identity

Agent identity

Every agent in AgentValet has its own cryptographic identity. Not a username, not a shared API key — a private signing key that lives only on the machine the agent runs on.

When an agent calls AgentValet, it signs the request. AgentValet verifies the signature against the public key it has on file for that agent. If the signature doesn’t match, the request is rejected before any permission check, audit write, or platform call happens.

What’s actually issued

When you register an agent, AgentValet generates a fresh RS256 keypair. The public key is stored in your account; the private key is delivered to you once, and never stored on our side after that.

  • Public key — kept by AgentValet (agents.public_key_pem)
  • Private key — shown once at registration, then it’s yours to safeguard
  • Token format — JWT signed with the private key, 15-minute expiry per call

Every call from the agent is a fresh signed JWT. There is no long-lived bearer token, no shared secret, no cookie. If a JWT leaks, it’s useless 15 minutes later.

Where the private key lives

Different surfaces store the key in different places:

SurfaceStorage
MCPB (Claude Desktop)Pasted into the extension’s user-config fields; held by Claude Desktop’s secure storage
CLI~/.agentvalet/agent.key, file mode 0600
Dashboard-created agentsDownloaded once at creation; you’re responsible for placement

If you lose the private key, you can’t recover it. Delete the agent and register a fresh one — the old identity stays in your audit log but can no longer sign anything.

What the verification check covers

On every action call, AgentValet’s proxy:

  1. Parses the JWT from the Authorization: Bearer … header
  2. Looks up the agent record by the sub claim (the agent_id)
  3. Verifies the signature against the stored public key
  4. Checks expiry
  5. Confirms the agent’s status is active (not revoked, not suspended)

Only after all five pass does the request proceed to permission evaluation.

Identity vs authorisation

It’s worth separating two things that get conflated elsewhere:

  • Identity answers “who is this?” — handled by the signing key.
  • Authorisation answers “is this caller allowed to do this?” — handled by scopes & permissions.

A valid signature gets you past the door. It does not get you any particular action. An agent with no granted scopes can sign requests all day; every one of them comes back denied.

Why this matters

Shared API keys are the default failure mode in the agent ecosystem. One key leaks, one config file gets checked in, one ex-employee keeps a copy — and you can’t tell which actions were “real” and which were the leak. The audit log says “Slack API used Stripe key” and you have no idea who.

Per-agent keypairs solve the attribution problem. Every action in your audit log carries a specific agent_id. You can revoke that one identity without touching any others. You can see which agent acted, when, and with which scopes.

On the roadmap

  • CIMD public identity documents at /agents/[agent-id]. The architecture spec includes a published identity document per agent (the way SPIFFE IDs work). The data exists; the public endpoint isn’t yet wired.
  • ZeroID-based delegation chains to replace the in-house JWT plumbing. Today’s keys are AgentValet’s own; the plan is to migrate to a SPIFFE-compatible identity layer.

Next

Last updated on