# AudioToMidiNow auth.md

AudioToMidiNow supports the **Auth.md user-claimed agent flow** with anonymous agent registration and user confirmation using an AudioToMidiNow account secured by passkeys. It issues short-lived credentials for one read-only scope, `guide.read`, which reads the public service guide. It does not grant access to visitor files, accept audio uploads, or expose audio conversion.

## Discovery

- Protected Resource Metadata: `https://audiotomidinow.com/.well-known/oauth-protected-resource`
- Authorization Server Metadata: `https://audiotomidinow.com/.well-known/oauth-authorization-server`
- Agent identity registration: `POST https://audiotomidinow.com/agent/identity`
- Start a user claim: `POST https://audiotomidinow.com/agent/identity/claim`
- OAuth token endpoint: `POST https://audiotomidinow.com/oauth2/token`
- OAuth revocation endpoint: `POST https://audiotomidinow.com/oauth2/revoke`
- User account and claim confirmation: `https://audiotomidinow.com/auth/account/` and the verification URL returned by the claim endpoint.
- Supported registration type: `anonymous` only. Provider-signed `identity_assertion` and email-based `service_auth` registration are not accepted.

## Start an anonymous agent registration

Send JSON to `/agent/identity`:

```http
POST /agent/identity HTTP/1.1
Host: audiotomidinow.com
Content-Type: application/json

{"type":"anonymous"}
```

The response includes a registration ID, a short-lived service-signed `identity_assertion`, and a one-time-display `claim_token`. Keep the claim token private; the service stores only its hash. Registrations expire after 30 days.

```json
{
  "registration_id": "reg_<id>",
  "registration_type": "anonymous",
  "identity_assertion": "<service-signed JWT>",
  "assertion_expires": "<ISO-8601 timestamp>",
  "pre_claim_scopes": ["guide.read"],
  "claim_url": "https://audiotomidinow.com/agent/identity/claim",
  "claim_token": "clm_<private token>",
  "claim_token_expires": "<ISO-8601 timestamp>",
  "post_claim_scopes": ["guide.read"]
}
```

Before the user confirms, an agent may exchange the assertion for the same limited, read-only `guide.read` scope. There are no write scopes.

## Exchange an identity assertion

Use form encoding at `/oauth2/token`:

```http
POST /oauth2/token HTTP/1.1
Host: audiotomidinow.com
Content-Type: application/x-www-form-urlencoded

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=<identity_assertion>&resource=https%3A%2F%2Faudiotomidinow.com%2Fapi%2Fagent-guide
```

The returned opaque bearer token expires in one hour. Do not put assertions or access tokens in URLs, logs, or public source code.

## Ask the user to claim the agent

The agent starts a claim ceremony by sending its private claim token:

```http
POST /agent/identity/claim HTTP/1.1
Host: audiotomidinow.com
Content-Type: application/json

{"claim_token":"<private claim token>"}
```

The response contains a six-digit `user_code` and a `verification_uri`. Present both to the user. The user opens that URL, creates an account or signs in with a passkey, and enters the code. AudioToMidiNow does not request an email address. Never ask the user to send their passkey, private credential data, or account session to an agent.

```json
{
  "registration_id": "reg_<id>",
  "claim_attempt_id": "cla_<id>",
  "status": "initiated",
  "expires_at": "<ISO-8601 timestamp>",
  "claim_attempt": {
    "user_code": "123456",
    "expires_in": 600,
    "verification_uri": "https://audiotomidinow.com/agent/claim/?attempt_token=<private token>",
    "interval": 5
  }
}
```

The user should confirm only a claim they initiated. Codes expire after ten minutes and have a limited number of attempts. The verification URL contains a private claim-attempt token; do not share it publicly.

## Poll for user confirmation

Poll `/oauth2/token` no more frequently than once every five seconds:

```http
POST /oauth2/token HTTP/1.1
Host: audiotomidinow.com
Content-Type: application/x-www-form-urlencoded

grant_type=urn:workos:agent-auth:grant-type:claim&claim_token=<private claim token>
```

Until confirmation, the service returns `authorization_pending`; polling too quickly returns `slow_down`. After confirmation, the response contains an access token and a new service-signed identity assertion bound to the claimed account. Pre-claim access tokens are revoked when the user completes the claim.

```json
{
  "access_token": "<opaque bearer token>",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "guide.read",
  "identity_assertion": "<service-signed JWT>",
  "assertion_expires": "<ISO-8601 timestamp>"
}
```

## Call and revoke the protected guide API

Call `GET https://audiotomidinow.com/api/agent-guide` with `Authorization: Bearer <access_token>`. The endpoint returns public service guidance only. A 401 response advertises Protected Resource Metadata in `WWW-Authenticate`.

To revoke an access token, send an RFC 7009-style form request. Revocation is idempotent:

```http
POST /oauth2/revoke HTTP/1.1
Host: audiotomidinow.com
Content-Type: application/x-www-form-urlencoded

token=<access_token>&token_type_hint=access_token
```

Users can review and revoke their claimed agent registrations from the **Agent registrations** section of `https://audiotomidinow.com/auth/account/`. For support or account deletion requests, contact `contact@audiotomidinow.com`. See the [privacy policy](https://audiotomidinow.com/privacy/) for account and passkey data handling.
