DEV Community

Authora Dev
Authora Dev

Posted on

Solving AI Agent Auth: Why Your Bots Need Real Identities

If you’ve put an AI agent anywhere near real infrastructure, you’ve probably hit this problem already: the agent can do things, but you can’t clearly answer who did what, under which permissions, and on whose behalf.

At first, most teams glue this together with shared API keys, environment variables, and a few “service accounts” nobody really owns. That works until your agent starts opening PRs, reading customer data, calling internal tools, or chaining actions across systems. Then the questions get uncomfortable:

  • Was this action approved by a user or just initiated by a prompt?
  • Which agent made the call?
  • Can this agent delegate work to another agent?
  • How do you revoke access without breaking everything?
  • What shows up in your audit logs?

This is the auth problem for AI agents: they act like users, services, and automation all at once, but most auth systems only model one of those cleanly.

Why “just use an API key” stops working

A shared API key tells your backend that something is allowed in. It does not tell you much about the actual actor.

For AI agents, that creates a few predictable failures:

1. No durable identity

If five different agents use the same token, your logs can’t distinguish them. You lose accountability immediately.

2. No delegation model

A user asks Agent A to do something. Agent A asks Tool B to perform part of it. Tool B triggers Worker C. Who is acting on whose behalf?

Without delegation, every hop either becomes overprivileged or unauditable.

3. No least privilege

Agents often need scoped access:

  • read one repo, not all repos
  • create draft PRs, not merge to main
  • query one dataset, not the full warehouse

Shared credentials push you toward broad access because narrow access is hard to manage manually.

4. No meaningful audit trail

If an agent deletes a record or deploys code, “used API_KEY_7” is not an answer your security team will love.

What “real identity” means for an agent

A useful mental model is: an agent should authenticate like a workload, authorize like a principal, and audit like a user.

In practice, that usually means:

  • a unique cryptographic identity per agent or agent instance
  • scoped permissions attached to that identity
  • support for delegation when an agent acts for a user or another service
  • policy checks before sensitive actions
  • audit logs that preserve the full chain of responsibility

You do not necessarily need a huge new platform to start doing this. Depending on your stack, you might use:

  • OAuth 2.0 token exchange / delegation patterns
  • SPIFFE/SPIRE for workload identity
  • OPA for policy evaluation
  • JWTs with clear actor / subject semantics
  • signed requests from agents using asymmetric keys

If OPA plus your existing identity provider solves your problem, that’s a good answer.

But the key idea is non-negotiable: your agents need identities that are first-class, not implied by infrastructure secrets.

A simple pattern: signed agent identity + delegated access

Here’s a lightweight pattern that scales better than shared secrets:

  1. Give each agent its own keypair
  2. Register the public key with your control plane or auth service
  3. Issue short-lived access tokens for that agent
  4. When acting for a user, mint a delegated token that records:
    • the user
    • the agent
    • the scope
    • expiration
  5. Enforce authorization with policy, not prompt text

A simplified example in TypeScript might look like this:

import nacl from "tweetnacl";
import { createHash } from "crypto";

// Generate an Ed25519 identity for an agent
const keypair = nacl.sign.keyPair();

const agentIdentity = {
  agent_id: "agent-code-reviewer-01",
  public_key: Buffer.from(keypair.publicKey).toString("base64"),
  capabilities: ["repo:read", "pr:write:draft"]
};

console.log(agentIdentity);
Enter fullscreen mode Exit fullscreen mode

Then, when the agent calls your API, it can sign a challenge:

const message = Buffer.from("approve-request:174325");
const signature = nacl.sign.detached(message, keypair.secretKey);

const request = {
  agent_id: "agent-code-reviewer-01",
  message: message.toString("base64"),
  signature: Buffer.from(signature).toString("base64")
};
Enter fullscreen mode Exit fullscreen mode

Your backend verifies the signature against the registered public key and then evaluates policy before allowing the action.

That’s already much better than “whoever has this bearer token can do anything.”

Delegation matters more than people expect

The hardest part of agent auth isn’t proving the agent exists. It’s proving why it’s allowed to act.

Say a user asks an agent to summarize billing anomalies. The agent may need to:

  • read invoices
  • query a warehouse
  • open a ticket
  • notify Slack

You probably don’t want the agent to have permanent, direct access to everything. Instead, the user should delegate a limited set of rights for a short period.

This is where token exchange and delegation chains become useful. RFC 8693 is worth understanding if you’re building serious agent workflows. It lets you represent “Agent X is acting on behalf of User Y with Scope Z.”

A policy engine can then evaluate rules like:

package agent.authz

default allow = false

allow {
  input.actor.type == "agent"
  input.actor.id == "agent-code-reviewer-01"
  input.on_behalf_of.user_id == "user_123"
  input.action == "pr.create"
  input.resource.repo == "acme/api"
  input.scope[_] == "pr:write:draft"
}
Enter fullscreen mode Exit fullscreen mode

That’s the kind of control surface you want when bots start touching production workflows.

Where MCP fits in

As more teams adopt MCP-based tool calling, auth gets even more important. MCP makes tools easier to expose to agents, but tool access is still access.

If your MCP server exposes:

  • GitHub operations
  • database queries
  • deployment actions
  • ticketing systems

…then every tool invocation needs to answer:

  • which agent is calling?
  • what is it allowed to do?
  • is it acting directly or on behalf of someone?
  • should this call require approval?

Without that, MCP can become a very efficient way to distribute overprivileged automation.

Getting started: a practical path

You don’t need to solve everything on day one. A good rollout looks like this:

Step 1: Stop sharing credentials across agents

Every agent gets its own identity, even if that identity is initially just a separate keypair or client credential.

Step 2: Make permissions explicit

Write down what each agent can do. Prefer scopes like:

  • repo:read
  • pr:write:draft
  • db:query:billing
  • ticket:create

Step 3: Add short-lived tokens

Avoid long-lived secrets where possible. Rotate automatically.

Step 4: Introduce delegation

If an agent acts for a user, encode that in the token or request context. Don’t rely on “the prompt said the user asked for it.”

Step 5: Add policy checks for sensitive actions

Use OPA or another policy engine for approvals, environment restrictions, and high-risk operations.

Step 6: Improve audit logs

Record:

  • agent identity
  • delegated user, if any
  • action
  • resource
  • timestamp
  • approval context
  • outcome

If you want to build less of this yourself

This is the problem space platforms like Authora Identity are trying to make less painful: cryptographic agent identities using Ed25519, RBAC, delegation chains, MCP authorization, policy enforcement, approval workflows, and audit logging, with SDKs in TypeScript, Python, Rust, and Go.

That said, the important part is not choosing one vendor-shaped answer. The important part is recognizing that AI agents are now real actors in your system. Once that clicks, the architecture gets clearer.

Treat them like first-class principals. Give them identities. Scope their permissions. Model delegation explicitly. Log everything.

Your future self — and your security team — will thank you.

Further reading

If you’re digging into this space, this curated resource list is a good place to start:

-- Authora team

This post was created with AI assistance.

Top comments (0)