Designing API Keys for AI Agents: Scopes, Expiry and Hashing

Once other applications call your agents, API keys become your front door. Good key design limits damage from a leak and makes rotation routine. Here is how to get it right.

A key with labelled scopes unlocking a single agent

Turning an agent into an API is one of the most useful things a team can do. Suddenly the agent can be called from a backend service, a workflow tool, a spreadsheet script or another agent. It also means the agent has a front door, and API keys are the lock. Most key leaks are not dramatic hacks. They are keys pasted into a ticket, committed to a repository or shared between three services. Good design makes those mistakes cheap.

Principle 1: Make keys recognizable

Give keys a fixed prefix and a fixed length. A prefix such as bhk_ lets secret scanners in code hosts and CI tools spot a leaked key immediately, and it tells a person reading a log exactly what they are looking at. BeansHost keys are bhk_ followed by 32 characters.

Principle 2: Store only a hash

Treat keys like passwords. Show the full key once, at creation, and store only a hash such as SHA-256. If your database is ever exposed, the hashes cannot be used to call anything. The trade-off is intentional: a lost key is replaced, never recovered.

Principle 3: Scope by action

A key should allow only what its holder needs. For agents, two scopes cover most needs:

ScopeAllowsGive it to
Invoke agents (agents:invoke)Calling an agent's endpointApplications that use the agent
Report runs (executions:report)Recording runs that happened elsewhereThe agent itself, when it is called directly

Principle 4: Scope by resource

Action scopes say what a key can do. Resource limits say where. A key handed to a partner integration should call one agent, not every agent in your organization. In BeansHost, keys created from an agent's API panel are limited to that agent. Any call to a different agent answers 403 api_key_agent_mismatch before anything else is looked up. Keys created in Settings can cover an organization or a project when you need broader access.

Principle 5: Expire by default

A key that never expires is a key nobody remembers to rotate. Offer sensible defaults such as 30 days, 90 days or one year, and reserve keys with no expiry for cases with a clear owner and a rotation plan.

Principle 6: Rotate without downtime

  1. Create a new key with the same scope and limits.
  2. Deploy it to the calling application alongside the old one.
  3. Switch traffic to the new key and confirm calls succeed.
  4. Revoke the old key.
  5. Check the audit log to confirm the old key is no longer used.

Principle 7: Keep keys out of code

Read keys from the environment, never from source files. Every example the BeansHost console generates follows this rule, in curl, JavaScript and Python.

JavaScript
const response = await fetch(
  `https://app.beanshost.com/api/v1/runtime/agents/${AGENT_ID}/invoke?environment=production`,
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.BEANSHOST_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ message: "Hello" }),
  },
);
const result = await response.json();

Principle 8: Never forward the caller's key

The gateway that checks the key should not pass it on to the agent. The agent does not need it, and every extra place a key travels is another place it can leak. BeansHost strips caller credentials before forwarding the request body to the agent.

Summary

  • Recognizable prefix and fixed length.
  • Shown once, stored as a hash.
  • Scoped by action and by resource.
  • Expiry by default, rotation as routine.
  • Read from the environment, never forwarded downstream.
  • Every key event recorded.

Read the full agent API reference for request formats and error codes, or see the wider security checklist for AI agents.

Keep reading

Related articles

All articles