# auth.md — mekyn Authentifizierung für Agenten

mekyn (https://mekyn.com) stellt agentische Schnittstellen bereit. Es gibt zwei Ebenen:

## 1. Öffentliche Read-Tools (ohne Auth)

SEO/AEO/GEO-Audit, Site-Quality-Check (MCS), Core-Web-Vitals und Tarif-Auskunft
sind ohne Authentifizierung nutzbar. Verzeichnis:

- API-Katalog: https://mekyn.com/.well-known/api-catalog
- OpenAPI: https://mekyn.com/openapi.json
- Agent Skills: https://mekyn.com/.well-known/agent-skills/index.json
- MCP Server Card: https://mekyn.com/.well-known/mcp/server-card.json

## 2. Agentische Registrierung (anonymous — workos/auth.md)

You are an agent. mekyn supports **agentic registration** via the workos/auth.md
profile. Supported `identity_types`: **`anonymous`** (the only type mekyn offers —
no ID-JAG `identity_assertion`, no `service_auth`). The protected resource is the
MCP server at `https://mekyn.com/mcp`. Follow the steps in order.

### Step 1 — Discover

- Protected-Resource-Metadata: https://mekyn.com/.well-known/oauth-protected-resource
- Authorization-Server-Metadata (carries the `agent_auth` block): https://mekyn.com/.well-known/oauth-authorization-server
- JWKS (verify assertions/tokens): https://mekyn.com/.well-known/jwks.json

The `agent_auth` block gives you `identity_endpoint`, `claim_endpoint` and
`identity_types_supported`. The top-level `token_endpoint` and `revocation_endpoint`
are standard OAuth.

### Step 2 — Register (anonymous)

```http
POST https://mekyn.com/agent/identity
Content-Type: application/json

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

Response (200):

```json
{
  "registration_id": "reg_…",
  "registration_type": "anonymous",
  "identity_assertion": "<service-signed JWT>",
  "assertion_expires": "…",
  "pre_claim_scopes": ["mcp:read"],
  "claim_url": "https://mekyn.com/agent/identity/claim",
  "claim_token": "clm_…",
  "claim_token_expires": "…",
  "post_claim_scopes": ["mcp:read", "mcp:tools"]
}
```

Hold `claim_token` in memory only. Exchange the `identity_assertion` for a
pre-claim access_token right away (Step 4); the claim ceremony is optional and
deferred until a human wants to take ownership.

### Step 3 — Claim ceremony (optional, to unlock post_claim_scopes)

Ask mekyn to start a ceremony, binding it to the human's email:

```http
POST https://mekyn.com/agent/identity/claim
Content-Type: application/json

{ "claim_token": "clm_…", "email": "user@example.com" }
```

Response (200) carries a `claim_attempt` block (`user_code`, `verification_uri`,
`expires_in`, `interval`). Surface `verification_uri` + `user_code` to the user —
they sign in at mekyn and type the code. Then poll the token endpoint:

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

grant_type=urn:workos:agent-auth:grant-type:claim&claim_token=clm_…
```

Returns `{ "error": "authorization_pending" }` until the user finishes, then a
post-claim access_token plus a v2 `identity_assertion` (carries the user's email).

### Step 4 — Exchange the assertion

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

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=<identity_assertion>
```

Returns `{ "access_token": "<JWT>", "token_type": "Bearer", "expires_in": 3600, "scope": "…" }`.

### Step 5 — Call the MCP server

```http
POST https://mekyn.com/mcp
Authorization: Bearer <access_token>
```

### Revocation (RFC 7009)

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

token=<access_token>
```

Tokens are RS256 JWTs verifiable against the JWKS above. Issuer = https://mekyn.com.

## 3. Konto-OAuth für Menschen-im-Loop (Authorization-Code + PKCE)

Alternativ kennt mekyn den Standard-Authorization-Code-Flow mit PKCE + dynamischer
Client-Registrierung (RFC 7591) — für Agenten, die einen eingeloggten Nutzer direkt
durch einen Consent führen:

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

{ "client_name": "Mein Agent", "redirect_uris": ["https://meinagent.example/callback"], "token_endpoint_auth_method": "none" }
```

1. `GET https://mekyn.com/oauth/authorize` (`response_type=code`, `client_id`, `redirect_uri`, `code_challenge` S256, `scope`) → Login + Zustimmung.
2. `POST https://mekyn.com/oauth/token` (`grant_type=authorization_code`, `code`, `code_verifier`, `client_id`) → JWT-Access-Token.
3. MCP-Aufrufe an `https://mekyn.com/mcp` mit `Authorization: Bearer <token>`.
