# auth.md — designmd.app

> Authentication and access policy for AI agents.
> Spec: agent_auth, identity_endpoint, identity_assertion, service_auth, id-jag, WWW-Authenticate

## Discover

To discover the authentication protocol for this service:

1. Fetch `/.well-known/api-catalog` for the API linkset
2. Fetch `/auth.md` (this file) for the full protocol
3. Fetch `/.well-known/agent.json` for agent card metadata
4. Check `WWW-Authenticate` response headers on 401 responses

The `WWW-Authenticate` header on 401 responses includes:
- `Bearer realm="designmd.app"`
- `error="invalid_token"`
- `error_description` pointing to this document

## Pick a method

This is a **public content site**. No authentication is required for read access.

| Resource | Auth Required | Method |
|----------|--------------|--------|
| Website content (`/*`) | No | Public |
| Library (`/library/*`) | No | Public |
| Blog (`/blog/*`) | No | Public |
| Guides (`/guides/*`) | No | Public |
| llms.txt (`/llms.txt`) | No | Public |
| llms-full.txt (`/llms-full.txt`) | No | Public |
| RSS feed (`/rss.xml`) | No | Public |
| Sitemap (`/sitemap-index.xml`) | No | Public |
| MCP server (`/.well-known/mcp/server-card.json`) | No | Public |
| Agent skills (`/.well-known/agent-skills/index.json`) | No | Public |
| API endpoints (`/api/*`) | No | Public (rate-limited) |

For write access or partnership inquiries, contact `contato@ft.ia.br`.

## Register

No registration required for read access. Agents may freely:

- Read all pages and content
- Use the MCP server endpoint
- Index and cite content with attribution
- Access design system files from the library

For API write access or partnership:

1. Send an email to `contato@ft.ia.br` with:
   - Your agent name and provider
   - Intended use case
   - Estimated request volume
2. Receive an `id-jag` (identity assertion grant) via email
3. Include the `id-jag` in your `Authorization` header

## Claim

To claim an identity for your agent:

1. Obtain an `identity_assertion` from your agent provider (e.g., Claude, GPT, Gemini)
2. The assertion must include:
   - `iss` (issuer) — your agent provider
   - `sub` (subject) — your agent's unique identifier
   - `aud` (audience) — `https://designmd.app`
   - `exp` (expiration) — must be in the future
3. Present the assertion in the `Authorization` header

## Exchange

To exchange an identity assertion for an access_token:

```http
POST /api/auth/exchange HTTP/1.1
Host: designmd.app
Content-Type: application/json
Authorization: Bearer <identity_assertion>

{
  "grant_type": "identity_assertion",
  "assertion": "<your_identity_assertion>",
  "scope": "read:library read:blog"
}
```

Response:

```json
{
  "access_token": "eyJhbGciOi...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "read:library read:blog"
}
```

The `access_token` is a signed JWT containing:
- `iss` — `https://designmd.app`
- `sub` — your agent's identifier
- `scope` — granted permissions
- `exp` — expiration timestamp

## Use the access_token

Include the access_token in all authenticated requests:

```http
GET /api/styles HTTP/1.1
Host: designmd.app
Authorization: Bearer <access_token>
```

The token is validated on each request. Expired or invalid tokens receive a `401` response with a `WWW-Authenticate` header.

## Errors

| Error | HTTP Status | Description |
|-------|-------------|-------------|
| `invalid_request` | 400 | Malformed request body |
| `invalid_token` | 401 | Token expired, revoked, or malformed |
| `insufficient_scope` | 403 | Token valid but lacks required scope |
| `rate_limit_exceeded` | 429 | Too many requests |

Error response format:

```json
{
  "error": "invalid_token",
  "error_description": "The access token has expired"
}
```

When `Accept: text/markdown` is set, errors are returned as markdown:

```markdown
# 401 — Invalid Token

The access token provided is expired, revoked, or malformed.

## How to fix

1. Re-exchange your identity assertion at `/api/auth/exchange`
2. Include the new token in the `Authorization` header
3. Retry the request
```

## Revocation

To revoke an access_token:

```http
POST /api/auth/revoke HTTP/1.1
Host: designmd.app
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "token": "<access_token>"
}
```

Revoked tokens are added to a revocation list and rejected on subsequent use.

## Rate Limits

| Endpoint | Limit |
|----------|-------|
| All pages | 60 requests/minute per IP |
| API endpoints | 30 requests/minute per IP |

## Attribution

When citing content from this site, please link back to `https://designmd.app` or the specific page URL.

## Contact

For API access questions or partnerships: contato@ft.ia.br
