Today there is no real onboarding for autonomous agents. A human signs up for the service, fills the form, verifies the email, mints an API key, and pastes it into the agent’s config. The agent inherits a credential a human had to obtain for it.
That is not autonomy.
We believe in a future where agents onboard products the same way humans do today. Sign up, use, pay, all of it, without a person bootstrapping the relationship first. Every other layer of agent readiness improves each quarter.
Auth doesn’t.
The sign-up surface was built for humans with browsers, mailboxes, phones, and patience, and an agent has none of those.
A few days ago WorkOS published auth.md, the first open protocol that gives an agent a real self-serve registration path. Deep Scan v1.2 ships first-class support for it, alongside a perf rewrite that takes a full scan from ~120s to ~15s. This post is what we think about the broader space, where we still see gaps, and what v1.2 now grades.
The onboarding gap
Pick any product an agent might use on a user’s behalf: a CRM, a booking system, a payment processor. The agent can find it, read it, call its API, plan against its MCP. None of that matters if it cannot get a credential it can use to act for the user.
The gap is not just the consent screen, though that is real. It is the whole funnel before it. Sign-up forms assume a browser. Email verification assumes a mailbox. SMS 2FA assumes a phone. Developer portals assume someone willing to fill out a company name and accept terms. Even where OAuth exists, getting an OAuth client created is usually a human task. Every fence adds a human dependency, and a hundred agents acting in parallel for a thousand users collapses into a queue of people confirming OTPs.
The agent inherits a credential a human had to obtain for it. That is not autonomy. That is a faster handoff.
What agents can do today
The Access layer in Deep Scan (Layer 3) grades every auth surface an agent might negotiate. None is wrong; each solves part of the problem and leaves a human standing in for the rest.
- Static API keys. Universal, but the key represents the account not the user; scope is all-or-nothing; revoking one kills every agent using it; a leaked key is indistinguishable from a prompt-injection payload. We test:
developer-portal,agent-auth-docs. - OAuth 2.0 / 2.1 with PKCE. Mature, scoped, audience-restrictable (RFC 8707) - but requires a browser and a consent screen, and the consent screen is the wall most autonomous agents can’t cross. We test:
oauth-support,oauth-protected-resource(RFC 9728),scoped-permissions,mcp-pkce-s256, andauth-flow-simulation(a deep check that runs the full OAuth dance against live endpoints). - Client credentials (M2M). Short-lived, scoped, audit-friendly - but the token represents the service, not the user. Wrong primitive the moment an agent acts on user data.
- Dynamic Client Registration (RFC 7591). Removes the human-creates-the-app step, but an open
/registeris a trust-bootstrap problem. Production deployments gate it with initial-access tokens, putting the human back at the door. MCP demoted DCR to a fallback in November 2025 in favour of Client ID Metadata Documents. - Web Bot Auth (RFC 9421). Cryptographic proof of which agent sent a request; Cloudflare wired it into Verified Bots. But it proves the agent’s identity, not the user’s. Different problem. We test:
web-bot-auth-directory.
The pattern: every option either proves the agent without user delegation, or delegates with a human in the consent loop, or neither. None lets an agent walk up with only the user’s email, prove who the user is, and walk away with a scoped credential.
The bypass: x402, and where it stops
One real alternative is to skip auth entirely. x402 (Coinbase’s protocol, recently picked up by AWS Bedrock AgentCore Payments) embeds payment directly in the HTTP request. The agent calls a resource, the server responds 402 Payment Required with a payment header, the agent attaches a stablecoin payment and retries, the resource comes back. No account, no signup, no token. The payment is the credential. We grade this with x402-support, plus its sibling protocols (mpp-support, acp-support, acp-delegate-payment, ucp-support).
x402 is an honest answer for stateless, transactional calls: pay-per-fetch, pay-per-inference, pay-per-search. It is the right primitive for a class of interactions that does not need an account on the other end. But it is not an answer for relational ones - any product where an agent needs an ongoing scoped relationship with the user (writing to a CRM, holding a booking, mutating a doc, issuing per-user audit trails) still needs real auth. Most useful agent work is in the second bucket, and the merchant side of x402 also assumes a stablecoin acceptance most services don’t have yet.
And the deeper limit: x402 lets an agent transact with a product, but it has no way to do that on behalf of a human. The payment proves money, not identity; the service has no idea which user the agent is acting for, so it cannot scope, audit, or revoke per-user. That is the gap auth.md is built to close. x402 and auth.md are parallel bets, not competitors.
Why we are bullish on auth.md
auth.md is a markdown file an application publishes at /auth.md that tells an agent how to register a user on its behalf. It composes existing standards rather than inventing new ones: PRM (RFC 9728) for resource discovery, AS metadata (RFC 8414) for endpoint discovery, ID-JAG identity assertions for the agent-verified flow, OTP for the user-claimed flow, and OIDC backchannel logout for revocation. It is open and any service can publish one with no WorkOS account required.
The AS metadata carries a structured agent_auth block:
{
"agent_auth": {
"skill": "https://service.com/auth.md",
"register_uri": "https://auth.service.com/agent/auth",
"claim_uri": "https://auth.service.com/agent/auth/claim",
"revocation_uri": "https://auth.service.com/agent/auth/revoke",
"identity_types_supported": ["anonymous", "identity_assertion"],
"identity_assertion": {
"assertion_types_supported": [
"urn:ietf:params:oauth:token-type:id-jag"
],
"credential_types_supported": ["access_token", "api_key"]
}
}
}Two flows, a service can advertise either or both:
Agent verified. The agent’s IdP (OpenAI, Anthropic, Cursor, anyone the service trusts) mints an ID-JAG asserting “this agent is acting for this user.” The agent POSTs it to register_uri; the service verifies the signature against the provider’s JWKS and returns a scoped credential. No consent screen, no OTP, no email round-trip.
User claimed. For services that don’t accept the agent’s IdP. The user types a six-digit OTP from email back to the agent and the registration binds. One touch, not a consent screen on every action. Two sub-modes a service can pick from: email required (service holds the credential until the OTP verifies) or anonymous start (service issues a scoped credential immediately and lets the agent upgrade scopes after the user runs the OTP claim). Anonymous start is the one that lets an agent begin work at low trust and graduate later.
Concretely: where signing up a user for an API today is a human flow - open the site, fill the form, verify the email, mint an API key, paste it into the agent - auth.md collapses that whole sequence. The agent hits the API, gets a 401 with WWW-Authenticate pointing to PRM, reads the agent_auth block, posts an ID-JAG to the registration endpoint, and the credential lands in the same response. One POST, one signature verification, no human in the loop. (The /auth.md file itself is the human-readable guide for agents that don’t yet know the protocol; trained agents skip straight to the metadata.)
What makes this the most promising shape we have seen: no new IdP to ship, no contracts to sign, no WorkOS to trust. Roughly twenty lines of JSON plus an OTP state machine. The two flows handle the trust gradient honestly - IdPs the service trusts get a no-touch path, the rest still get a working one.
Caveats we are tracking. Adoption is thin (workos.com, here.now, mailbox.bot, resend.com). ID-JAG is still an IETF draft and the spec will move. The agent-verified flow only works where the agent’s IdP and the service already trust each other, which is a social problem the protocol cannot solve. We are betting the shape is right, not that the rollout is done.
What Deep Scan v1.2 grades
Six new bonus checks in the Access layer. All are bonus - they only widen the denominator when a product earns them, so non-adopters are never penalised.
auth-md-exists(2 pts) - markdown body at/auth.md, with a guard that rejects SPA catch-alls.auth-md-structure(2 pts, deep) - an LLM grades each canonical section on content quality and extracts the facts the document exposes (hosts, URIs, identity types, scopes), persisting them onto the scan.auth-md-walkthrough-simulation(2 pts, deep) - a GET-only agent walks/auth.md→ PRM → AS metadata → registration template. Never POSTs.agent-auth-discovery-metadata(3 pts) - validates the full PRM ↔ AS ↔agent_auth↔ skill back-pointer chain.agent-auth-www-authenticate(1 pt) - 401 carryingWWW-Authenticate: Bearer resource_metadata=...pointing at the PRM.agent-auth-endpoints-reachable(2 pts) - OPTIONS-probes URIs from the metadata block and from fencedhttpblocks in the prose (workos.com pattern).
Closing notes
v1.2 also rewires the scan pipeline. A 132-check scan now completes in ~15s, down from a ~120s user-reported baseline; scoring math is unchanged.
Auth is the last mile, and the products that close it first will be the ones agents reach for. Publishing a real /auth.md is a small, cheap bet on a future that is coming whether the spec we are betting on lands or a different one does.
Run a fresh scan at /#scan. The full check catalog is at /methodology. Every check still maps to the same AgentReady requirement; the standard is open at agentready.org.