How an agent signs in
The credentials an agent holds, the three ways to get one, and the auth.md flow for an agent that registers itself.
The credentials
| Prefix | Credential | Acts for | Reaches |
|---|---|---|---|
swa_ | Agent key | A shopper, or the agent itself, at one shop | The shopper MCP server, the UCP and ACP endpoints, and storefront GraphQL |
swm_ | Merchant key | A merchant, at their shop | The merchant MCP server and the REST API |
swp_ | Publishable token | Nobody: it names a shop | The shop front's own reads, and opening a basket |
Send a key as Authorization: Bearer <key>. Every surface reads the prefix to decide how to check a key. An app's tokens are different again: see Installs and tokens.
Three ways to get one
A merchant issues it. On the AI shoppers screen in the admin, a merchant issues an agent key to a platform or an assistant, with its own spending limits and rate limit, and can revoke it there. A merchant key for driving their own shop is under Settings, then Access keys.
OAuth. An MCP client that meets a 401 follows the challenge to the authorization server and asks a member of the shop's staff to consent. The token it gets is one of the keys above, bound to the one server it was issued for. See MCP servers.
The agent registers itself. With auth.md, an agent registers on its own and a person claims it later, by signing in and typing a six digit code the agent shows them. The rest of this page is about this flow.
Registering, in two places
Storeware runs auth.md twice, once for each kind of person an agent can act for.
| At a shop | On the platform | |
|---|---|---|
| Acts for | A shopper at that shop | A merchant |
| Read first | https://<shop>/auth.md | https://storeware.ai/auth.md |
| Metadata | https://<shop>/.well-known/oauth-authorization-server | https://api.storeware.ai/.well-known/oauth-authorization-server |
| Registration types | anonymous; service_auth where the shop lets shoppers link assistants | service_auth |
| Claimed at | The shop's /account/agent-claim, signed in as a shopper | The admin's /agent/claim, signed in as staff |
| Credential | An agent key | A merchant key, for /admin/mcp only |
| Before a claim | What the merchant chose: browse only by default | Nothing |
Each metadata document carries an agent_auth block, which is the current truth about what that realm accepts. Read it rather than relying on a cached copy of either auth.md.
identity_assertion, an ID-JAG from an agent provider, is accepted only from a provider Storeware has chosen to trust for that realm, and then the metadata lists the provider's issuer. Everywhere else it is refused with issuer_not_enabled.
Acting for a merchant
The whole flow, as storeware.ai/auth.md gives it.
1. Register
POST https://api.storeware.ai/api/mcp/agent/identity
Content-Type: application/json
{ "type": "service_auth", "login_hint": "merchant@example.com" }Tell the merchant first that you are about to connect to their Storeware account as that address. The answer is the same whether or not the address has an account, and no email is sent to it:
{
"registration_id": "…",
"registration_type": "service_auth",
"claim_token": "clm_…",
"claim": {
"user_code": "123456",
"verification_uri": "https://app.storeware.ai/agent/claim?claim_attempt_token=cat_…",
"expires_in": 600,
"interval": 5
}
}Keep claim_token secret. It is the only way to collect the credential.
2. Hand off
Show the merchant the verification_uri and the user_code. They sign in to the admin as the address you named, choose which shop you may work on and whether you may change anything, and type the code. Only a person signed in as that address can finish, and five wrong codes end the attempt. If the code expires first, ask for a new one by posting the claim_token and email to https://api.storeware.ai/api/mcp/agent/identity/claim.
3. Poll
POST https://api.storeware.ai/api/mcp/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=urn:workos:agent-auth:grant-type:claim&claim_token=clm_…Wait interval seconds between polls. Once the merchant finishes, you receive an access token (swm_…, for an hour) and an identity_assertion, exactly once.
4. Use it, and renew it
Send the access token to https://api.storeware.ai/admin/mcp. It holds the merchant server's permissions, narrowed to the role of the person who claimed you, and to reads unless they allowed changes.
When it ends, exchange the assertion for a new one:
POST https://api.storeware.ai/api/mcp/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=eyJ…&resource=https://api.storeware.ai/admin/mcpEvery exchange checks that the person who claimed you is still a member of the shop's organisation and may still connect apps. If not, the answer is invalid_grant and the credential ends. The assertion lasts thirty days; after that, register again.
5. Revoke
Post token=swm_… to https://api.storeware.ai/api/mcp/oauth/revoke. The answer is always 200. The merchant can end your access at any time from the admin.
| Error | Where | What to do |
|---|---|---|
anonymous_not_enabled | Registering | Use service_auth. |
issuer_not_enabled | Registering | Use service_auth. |
rate_limited | Registering | Wait before trying again. |
authorization_pending | Polling | Keep polling at the interval. |
slow_down | Polling | Poll less often. |
expired_token | Polling | Ask for a new code, or register again. |
invalid_grant | Token | The claim or assertion is no longer good. Register again. |
invalid_target | Token | Ask for https://api.storeware.ai/admin/mcp, or leave resource out. |
Acting for a shopper
A shop's /auth.md is written for that shop as it is set up now, so read it there. The shape is the same, with the shop's own endpoints on the API:
| Step | Endpoint |
|---|---|
| Register | POST https://api.storeware.ai/api/shopper/agent/<store id>/identity |
| Ask for a claim code | POST https://api.storeware.ai/api/shopper/agent/<store id>/identity/claim |
| Poll, and exchange an assertion | POST https://api.storeware.ai/api/shopper/oauth/token |
| Revoke | POST https://api.storeware.ai/api/shopper/oauth/revoke |
An anonymous registration returns an assertion straight away, so the agent can start before anybody claims it. What it may do until then is the merchant's choice: browse only, which is the default; start a checkout but not complete one; or complete one, with every order held until the merchant approves it. After a shopper claims it, the agent acts for them, and a checkout it starts is theirs: priced as theirs, and opened only for them, signed in.
An access token lasts an hour and there is no refresh token. Exchange the same assertion again.
What ends a link
A shopper disconnecting an assistant, a merchant revoking its key or its registration, and a provider withdrawing the person behind it all end the link. The baskets that key opened for that shopper are cancelled at the same time, each with checkout.canceled.v1. A token refresh is not an ending.
What an agent key never reaches
- Subscriptions. A standing agreement is read and changed by its own customer, signed in at the shop, and by the merchant. No agent key reaches one, linked or not.
- Store credit. A balance is spent by its owner, signed in at the shop. An agent key spends none, a shopper's own linked assistant included.