auth.md: a Markdown file that tells agents how to register with your service
An open protocol that lets agents register for services on behalf of users — discoverable through a Markdown file at your domain.
At a glance
- What is it?
- WorkOS's auth.md is a reference implementation of agentic registration, where an agent discovers a service's AUTH.md, presents an identity assertion, and exchanges it for an access token. It is a protocol sketch with runnable sample code, not a drop-in library.
- Who is it for?
- Adopt auth.md if you are building an agent provider or a service that needs to accept agent identity assertions and you want a runnable reference before the ID-JAG draft stabilises. Do not adopt it if you need a supported library, a hosted endpoint, or a stable wire format today: the repository is a sample implementation with no published release.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 22 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 22, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem auth.md addresses: agents that need accounts, not API keys
An agent acting for a user has no clean way to obtain credentials from a service it has never seen. Handing it a long-lived API key ties the credential to the operator, not the user, and revocation is all-or-nothing. WorkOS's auth.md proposes a different arrangement: the service publishes a Markdown file at a known path, the agent reads it, and the two sides run a registration ceremony that ends in a scoped access token tied to a user identity.
The README names three roles. An agent acts for a user. An agent provider mints identity assertions, specifically ID-JAGs, the Identity Assertion Authorization Grant from an IETF draft. A service accepts those assertions when they are available and issues credentials. If the agent has no associated user identity, or the provider does not support ID-JAGs, the service falls back to an RFC 8628-style claim ceremony. That fallback matters: it means the protocol degrades to a device-code flow rather than failing.
This is aimed at people implementing one of those three roles, not at end users. The repository is explicit that it contains sample implementations for the provider and service sides plus a sample AUTH.md file. There is no published package to install.
How discovery and credential exchange actually fit together
The mechanism is split across two endpoints, and the README is direct about that split. `POST /agent/identity` takes whatever identity assertion the agent chose (an ID-JAG, a verified email, or anonymous) and returns a service-signed `identity_assertion`. The agent then takes that assertion to `POST /oauth2/token` as an RFC 7523 JWT-bearer grant and receives an access token.
Discovery happens in two hops. The service exposes `/.well-known/oauth-protected-resource`, which points at authorization servers, and the authorization server exposes `/.well-known/oauth-authorization-server`. The standard RFC 8414 fields (`issuer`, `token_endpoint`, `revocation_endpoint`, `grant_types_supported`) sit at the top level, and an `agent_auth` block carries the registration surface: `skill`, `identity_endpoint`, `claim_endpoint`, `events_endpoint`, `identity_types_supported`, and the supported assertion types. The `skill` value points back at the AUTH.md file itself.
The `grant_types_supported` array lists two values, `urn:ietf:params:oauth:grant-type:jwt-bearer` and `urn:workos:agent-auth:grant-type:claim`. That second URN is WorkOS-namespaced, which tells you the claim ceremony is the part of this profile that is not covered by an existing RFC. The ID-JAG path is a draft; the claim path is theirs.
Revocation is handled through `events_supported`, which lists `https://schemas.workos.com/events/agent/auth/identity/assertion/revoked`. The provider sends revocation events to the service's `events_endpoint`. The README does not document what the service does when that endpoint is unreachable, so retry semantics are an open question for anyone implementing it.
Running the sample provider and service locally
The quickstart is two commands. The repository is a pnpm workspace, and the root `dev` script builds the shared package first and then starts both sides under `concurrently`.
pnpm install
pnpm devAfter that, the README says the service listens at `http://localhost:8000` and the provider at `http://localhost:4000`. The service home page walks the three registration flows interactively, which is the fastest way to see the difference between the ID-JAG path, the verified-email path, and anonymous registration. If you only care about one side, `pnpm dev:service` or `pnpm dev:provider` runs it alone.
The root package.json pins `pnpm@8.15.8` in `packageManager`, so a mismatched pnpm version is the first thing to check if install behaves oddly. The workspace has no `dependencies` at the root, only `concurrently` and `prettier` as devDependencies, which is consistent with this being sample code rather than a published artifact.
For a first real use, the AUTH.md file at the repository root is the artifact to read. The README describes it as a procedural recipe covering discover, register, claim, exchange, use, and handle revoke. That ordering is the protocol in miniature: if you are writing an agent, that file is the specification you implement against, and the sample service is the thing you test it on.
Where the claim ceremony gets awkward
The anonymous registration flow is the weakest part of the design, and the sequence diagram makes the reason clear. The agent registers anonymously, gets an `identity_assertion` and a `claim_token`, and exchanges the assertion for an access token with a pre-claim scope. It operates in that limited state until the user wants to take ownership.
At that point the agent calls `POST /agent/identity/claim` with the `claim_token` and an email, and the service returns a `claim_attempt` containing a `user_code` and a `verification_uri`. The agent surfaces both to the user, who signs in and completes the claim at `POST /agent/identity/claim/complete` with a `claim_attempt_token` and the `user_code`. Meanwhile the agent polls `POST /oauth2/token` with `grant_type=claim` until the claim lands.
The polling loop has two failure modes, both visible in the diagram. If the user has not finished, the service returns `authorization_pending`. If the `user_code` window expires while the outer claim window is still open, the service returns `400 expired_token`, and the agent must call `POST /agent/identity/claim` again with the `claim_token` and email to get a fresh `user_code` and `verification_uri`, then surface the new code to the user. Every expiry means a second round trip through the human. That is a real cost, and the README does not state how long either window lasts, so you cannot size the retry behaviour from the documentation alone.
The design trade-off against plain OAuth device flow
The obvious alternative is the RFC 8628 device authorization grant by itself, which is what the claim ceremony resembles. The difference is what happens before the ceremony. With plain device flow, the agent has no way to present an existing user identity: the user always authorises from scratch, and the resulting token is tied to that one interaction.
With auth.md, the ID-JAG path lets an agent provider that already knows the user assert that identity to a specific audience. The agent requests an audience-specific ID-JAG from the provider, presents it at `POST /agent/identity`, and the service verifies it by fetching the provider's JSON Web Key Set from `/.well-known/jwks.json`. No user interaction is needed in that path at all, which is the whole point: the user consented at the provider, not at every service the agent touches.
The claim ceremony is then the fallback for agents that cannot do that, either because they have no user identity attached or because their provider does not mint ID-JAGs. So the comparison is not auth.md versus device flow. It is auth.md as device flow plus an optional assertion path that removes the human from the loop when the provider supports it. If your provider cannot mint ID-JAGs, you are running the device flow with extra endpoint names and a Markdown manifest, and you should ask whether that is worth the added surface.
Maintenance, licence, and what the repository does not promise
The repository is MIT licensed, and the root LICENSE file is present alongside the workspace directories. MIT means you can copy the sample code into your own service, but the README does not offer any compatibility guarantee, and there are no retrieved releases. The version field in the root package.json is `0.6.0` and the package is marked `"private": true`, so it is not published to a registry under that name. Do not plan an upgrade path around a changelog you have not read; a CHANGELOG.md exists at the top level, which is where version-to-version changes would be recorded.
The last push to the default branch was on 2026-09-01. That is recent enough that the sample code likely tracks the current draft, but it also means the protocol surface can move. The ID-JAG reference points at an IETF draft, and drafts change. If you implement against the `agent_auth` block as documented, budget for re-reading the discovery document whenever the draft is revised.
On licence implications, MIT covers the code in this repository. It does not cover the IETF draft referenced for ID-JAG, and it says nothing about the `schemas.workos.com` event schema URL, which is an external identifier rather than code you are licensing. If you need to host a compatible events endpoint, that is a question for whoever operates the schema, not something the LICENSE file answers.
Editorial conclusion
Adopt auth.md if you are building an agent provider or a service that needs to accept agent identity assertions and you want a runnable reference before the ID-JAG draft stabilises. Do not adopt it if you need a supported library, a hosted endpoint, or a stable wire format today: the repository is a sample implementation with no published release. Verify first that your agent provider can mint ID-JAGs and publish a JWKS, because without that the service falls back to the RFC 8628-style claim ceremony and the user has to copy a code.
Frequently asked questions
What is auth.md?
It is a reference implementation of agentic registration, a protocol that lets agents authenticate to services on behalf of users. The repository includes sample implementations for an agent provider that mints ID-JAGs and a service that accepts them, plus a sample AUTH.md file that the service would host to instruct agents.
What goes in the AUTH.md file?
The README describes it as a procedural recipe covering discover, register, claim, exchange, use, and handle revoke. The sample AUTH.md sits at the repository root and is the file an agent reads to learn how to authenticate with the service.
What are the ports for the auth.md sample service and provider?
The README states the service runs at http://localhost:8000 and the provider at http://localhost:4000 after `pnpm dev`. The service home page walks the three registration flows interactively.
Does auth.md require an agent provider that supports ID-JAGs?
No. If the agent is not associated with a user identity, or the agent provider does not support ID-JAGs, the README says the service uses an RFC 8628-style claim ceremony to authenticate the agent instead. The ID-JAG path is the one that avoids user interaction.
Community notes