# auth.md

Samva's API has a protected agent resource,
`https://mcp.samva.dev`, and its authorization server is
`https://samva.dev/api/v1/auth`.

Samva supports the Auth.md user-claimed `service_auth` flow. An agent can register
with a user's email, but receives no credential until that user signs in to Samva,
chooses an organization, and confirms the registration code.

## Step 1: Discover

For live MCP tool execution, start with the protected resource metadata:

```http
GET https://mcp.samva.dev/.well-known/oauth-protected-resource
```

Unauthenticated MCP requests return a `401` with:

```http
WWW-Authenticate: Bearer resource_metadata="https://mcp.samva.dev/.well-known/oauth-protected-resource"
```

Then fetch the Authorization Server metadata:

```http
GET https://samva.dev/.well-known/oauth-authorization-server/api/v1/auth
```

Read its standard OAuth fields and complete `agent_auth` block. These structured
documents are authoritative if they differ from this guide.

## Step 2: Pick a method

Use the credential that matches who is acting:

| Method | Best for | Org scope |
| --- | --- | --- |
| API key | Customer-owned servers and CI | Bound to one organization |
| CLI OAuth login | A human or coding agent in a terminal | User session plus active org |
| Auth.md `service_auth` | An agent acting for a known Samva user | User claim plus selected org |

Use API keys for unattended production automations. Use OAuth when a human is
present to approve access or when the agent needs MCP tool discovery.

## Scope and authorization

Auth.md `service_auth` access tokens carry the OAuth scopes `openid`,
`profile`, and `email`. These scopes identify the OAuth identity; they
do not grant Samva API actions on their own. Every MCP request is also bound to
the organization selected during the claim ceremony and authorized against the
user's current role in that organization.

Interactive OAuth clients may request `offline_access`. The Auth.md
`service_auth` flow does not issue a refresh token; exchange its service-signed
`identity_assertion` for another access token while the assertion remains valid.

For unattended automation that needs a narrower action set, create an organization-
bound API key. API-key permissions use Samva's `resource:action` grants, which are
published with the OpenAPI operations and enforced by the same API authorization
layer MCP calls reach.

## Step 3: Register with service_auth

```http
POST https://samva.dev/api/v1/auth/agent/identity
Content-Type: application/json

{"type":"service_auth","login_hint":"user@example.com"}
```

The response contains `registration_id`, a one-time `claim_token`, and a
`claim` block with `user_code`, `verification_uri`, `expires_in`, and
`interval`. It intentionally contains no access token or identity assertion.

## Step 4: Claim ceremony

Show the `verification_uri` and six-digit `user_code` to the user in one
message. Samva does not email the code. The user opens the link, signs in with
the `login_hint` email, chooses an organization, and types the code.

Poll the standard token endpoint no faster than the advertised interval:

```http
POST https://samva.dev/api/v1/auth/oauth2/token
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aworkos%3Aagent-auth%3Agrant-type%3Aclaim&claim_token=<claim_token>
```

Samva returns `authorization_pending` until the user completes the ceremony.
Success returns an OAuth access token plus a service-signed
`identity_assertion`. To renew the access token while the assertion is valid:

```http
POST https://samva.dev/api/v1/auth/oauth2/token
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=<identity_assertion>&resource=https%3A%2F%2Fblue-sea-697d.quartiers047.workers.dev%3A443%2Fhttps%2Fmcp.samva.dev
```

No refresh token is issued. Present the access token as
`Authorization: Bearer <access_token>` to `https://mcp.samva.dev`.

Revoke an agent access token through the advertised RFC 7009
`revocation_endpoint`. Revoking one of these tokens invalidates its Auth.md
registration, including access tokens and assertions derived from it.

## Mailbox access

An agent that acts in a mailbox should hold a restricted API key with `mailboxes` access, not
a key for the whole organization. The key acts as itself, reaches only the mailboxes it lists, and
is capped by the member who owns it. A person approves or denies a held send, and releases or
discards quarantined mail; no key or MCP tool can. See https://samva.dev/docs/mailboxes/agents-and-keys.

## Errors and lifetime

| Error | Agent action |
| --- | --- |
| `authorization_pending` | Continue polling at the advertised interval |
| `slow_down` | Increase the polling delay |
| `expired_token` | Start a new registration |
| `invalid_grant` | Stop using the assertion and register again |

Registration revocation makes every access token and assertion derived from it
unusable.

## References

- Agent integration guide: https://samva.dev/AGENTS.md
- Full docs: https://samva.dev/docs
- Terms: https://samva.dev/legal/terms
- Privacy: https://samva.dev/legal/privacy
- Samva MCP: https://mcp.samva.dev
- Agent skill index: https://samva.dev/.well-known/agent-skills/index.json
- Integration support: support@samva.dev
