# auth.md — TravelShifu agent authentication

TravelShifu publishes a **public, read-only agent surface**. Reading site
content, Markdown mirrors, `/llms.txt`, open datasets and MCP tools **needs no
authentication**. Optional OAuth client registration is available for agents
that want a client identity; it does not unlock private data today.

| Field | Value |
|---|---|
| Issuer | `https://travelshifu.com` |
| Protected resource | `https://travelshifu.com` |
| Identity types supported | `software_agent`, `anonymous` |
| Credential types supported | `client_secret` |
| Anonymous access | Supported for all published read paths and MCP tools |
| `register_uri` | `https://travelshifu.com/oauth/register` |

## Step 1 — Discover

Fetch the two metadata documents. Everything else is derived from them; do not
hard-code endpoints.

```http
GET https://travelshifu.com/.well-known/oauth-authorization-server
GET https://travelshifu.com/.well-known/oauth-protected-resource
```

The authorization-server document returns `issuer`, `token_endpoint`,
`authorization_endpoint`, `registration_endpoint`, `jwks_uri`,
`grant_types_supported` and an `agent_auth` block (including
`anonymous_access`). The protected-resource document returns the resource
identifier, its `authorization_servers`, `scopes_supported` and
`bearer_methods_supported`.

A future `401` from a protected path will carry:

```
WWW-Authenticate: Bearer realm="TravelShifu",
  resource_metadata="https://travelshifu.com/.well-known/oauth-protected-resource"
```

Today, MCP tools and public content do not return `401`.

## Step 2 — Register (optional)

Dynamic client registration (RFC 7591) is open and immediate — there is no
approval queue. **Skip this step for anonymous read access.**

```http
POST https://travelshifu.com/oauth/register
Content-Type: application/json

{ "client_name": "My travel research agent", "redirect_uris": [] }
```

Returns `client_id` and `client_secret`. Send an empty `redirect_uris` for
machine-to-machine use. Store both values — the secret is not recoverable.

## Step 3 — Claim

Not applicable for public editorial data. There is no agent-level identity
claim; registered clients are pseudonymous.

## Step 4 — Exchange credentials for a token (optional)

Machine-to-machine:

```http
POST https://travelshifu.com/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_id=...&client_secret=...&scope=travelshifu:read
```

Or authorization-code with PKCE (`S256`) via
`https://travelshifu.com/oauth/authorize`. Public MCP tool calls do not
require the resulting bearer token.

## Step 5 — Use

```http
POST https://travelshifu.com/mcp
Content-Type: application/json

{"jsonrpc":"2.0","id":1,"method":"tools/list"}
```

No `Authorization` header is required. Optionally send
`Authorization: Bearer <access_token>` once tokens are issued — tools remain
read-only either way.

Markdown negotiation (no auth):

```http
GET https://travelshifu.com/
Accept: text/markdown
```

## Step 6 — Revoke

Tokens are short-lived. Discard credentials at end of use. To retire a client,
discard `client_id` / `client_secret`. Contact security@travelshifu.com if a
secret leaks.

## Other agent surfaces

- MCP: `https://travelshifu.com/mcp` — card at `/.well-known/mcp/server-card.json`
- A2A: `https://travelshifu.com/a2a` — card at `/.well-known/agent-card.json`
- Skills: `/.well-known/agent-skills/index.json`
- Site map for LLMs: `/llms.txt`
- Markdown negotiation: send `Accept: text/markdown` on any editorial URL
- OpenAPI: `/openapi.json`
- Readiness notes: `/AGENT-READINESS.md`
