We raised $6M in Seed FundingRead more
+
+
+
+
+
+
+
+
Blog/Developer Resources

Is OAuth Enough to Verify an AI Agent?

OAuth authorizes; it does not identify. The same request under an OAuth access token, an OpenID Connect id_token from a human identity provider, and an AgentID token, and what an app can conclude from each about who is asking and who is accountable.

TL;DR

OAuth is the standard most people reach for when an AI agent needs access, but it was built to grant permission, not to say who is asking. This post shows what an app can and can't conclude from an OAuth token, what OpenID Connect adds on top, and what an identity provider built for agents adds after that, using the same request three times.

No, OAuth alone is not enough to verify an AI agent, because an OAuth access token says what its holder may do, not who the holder is or who is accountable for it. OpenID Connect adds an identity token that names a subject, and an identity provider built for agents adds a claim that the subject is an agent and, for apps that ask, the human who owns it.

The confusion is understandable. OAuth is in every sign-in button, so it feels like an identity system, and for years the difference didn't matter because the one holding the token was always a person who had just logged in. Agents break that assumption. The token might be held by software acting for a user, by software acting for itself, or by software that copied it from somewhere. The way to see the gap is to take one request and look at what an app actually knows under each kind of token.

What does an OAuth access token actually prove?

An OAuth access token proves that whoever holds it was granted certain scopes, and nothing about who that holder is. It is a bearer credential: presenting it is the whole proof. When agents stall in sign-in flows, as what happens when your AI agent hits 2FA or an email OTP describes, this is part of why, since the flows around OAuth assume a person at the keyboard.

Take a request to read a customer's orders. Here is what an app learns when it introspects the access token presented with it:

{
  "active": true,
  "scope": "orders:read",
  "client_id": "shopping-assistant",
  "sub": "user_8412",
  "exp": 1767225600
}

The app knows the token is valid, that it allows reading orders, that it was issued to a client called shopping-assistant, and that it was granted by user 8412. Many access tokens are opaque strings, so even this much requires a call back to the authorization server; others are JWTs the app can read directly, and they say the same kinds of things. It doesn't know whether a person or an agent sent this request, which agent it was if it was one, or who to call if the request was abuse.

What does OpenID Connect add?

OpenID Connect adds an id_token: a signed statement from an identity provider about who signed in. Here is one from an identity provider for people:

{
  "iss": "https://accounts.example.com",
  "sub": "10769150350006150715113082367",
  "aud": "your-client-id",
  "email": "maya@acme.com",
  "email_verified": true,
  "iat": 1767225000,
  "exp": 1767225600
}

Now the app knows who signed in: a stable subject, confirmed by an issuer it trusts, with a verified address. What it still can't tell is whether that subject is the person or an agent using the person's login. The token has no field for that, because the provider was never built to tell the difference.

An identity provider built for agents fills that gap. Here is an id_token from one, issued to an app that didn't register, so it carries no owner name or email:

{
  "iss": "https://auth.agentid.com",
  "aud": "https://yourapp.com",
  "sub": "lM9vT2aR7sK4qN8wE1xC6bY0uF3hJ5pD9gL2zV7oA4Q",
  "actor_type": "agent",
  "email": "support@acme.agentmail.to",
  "email_verified": true,
  "owner_sub": "oW7xN2pQ4mT8vL1kR6sC9dF3gH5jB0aE2uY4zI6nP8A",
  "iat": 1767225000,
  "exp": 1767225600,
  "jti": "9f1c2a44-3e77-4c19-9a2e-6b0d5f8e1c33"
}

This one comes from AgentID, our sign-in for AI agents. actor_type says the subject is an agent, sub names that agent at every app, and owner_sub is shared by every agent the same person runs. A registered app can also request the owner's name and email.

What can an app conclude from each token?

An app can conclude a little more from each token. Only the last one answers the question this post started with, which is whether the caller is an agent and whose it is.

What the app wants to knowOAuth access tokenOIDC id_token for a personAgent id_token
What may the holder do?Yes, the scopesNo; that is your app's policyNo; that is your app's policy
Who signed in?NoYes, a stable subjectYes, a stable subject
Is it an agent?NoNoYes, actor_type is "agent"
Same agent at another app?NoNoYes, the same sub
Who is accountable?The user who granted it, if anyoneThe person, assuming they signed in themselvesThe owner, as a claim

Notice what doesn't change across the three. None of them tells the app what the agent is allowed to do inside the product. Permissions stay with your app, which is where they belong, because only your app knows what an order or a refund is. The agent token is still a normal OpenID Connect token underneath. It is signed with ES256, its keys are published for any app to check, and the sign-in is an ordinary authorization code flow with PKCE. What makes it verifiable is the standard; what makes it useful for agents is the two extra facts it carries.

When is OAuth alone the right tool?

OAuth alone is the right tool when the agent is acting inside a person's own account, with that person's permission. An agent reading a user's calendar or filing a ticket in the user's name should hold a scoped grant from that user, and the user is rightly the one accountable, because the actions are theirs.

That model has a clear accountability story, and it keeps working as long as the agent never needs an account of its own. Revoking the grant cuts the agent off from that user's data and nothing else. It stops being enough when the agent is the one with the account: signing up for a service, holding its own history, getting its own receipts. There the app needs to know which agent it is dealing with and who stands behind it, and a grant of permission can't tell it either. The parts an agent identity needs to carry are laid out in what is an agent ID, and how an AI agent proves its identity with AgentID goes through every claim.

AgentMail gives your agents real inboxes. Create inboxes via API. Send and receive Emails with 0 complexity. Free to start.

FAQ

Ready to build? Start integrating AgentMail into your AI agents today.

All systems onlineSOC 2 Compliant

Email Inboxes for AI Agents

support@agentmail.cc

Subscribe to our weekly newsletter.

© 2026 AgentMail, Inc. All rights reserved.

Privacy PolicyTerms of ServiceSOC 2Subprocessors