# auth.md

You are an agent. **Abant Makine** (`https://abantpack.com`) supports agentic registration for read access to product catalog, news, and site content (including Markdown negotiation via `Accept: text/markdown`).

- **Resource server:** `https://abantpack.com`
- **Authorization server:** `https://abantpack.com`

Follow the steps in order: discover → register → (claim if needed) → use the credential.

## Step 1 — Discover

Discovery is two hops. A `401 Unauthorized` response includes a `WWW-Authenticate` header pointing at Protected Resource Metadata (PRM):

```http
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="https://abantpack.com", resource_metadata="https://abantpack.com/.well-known/oauth-protected-resource"
```

If you do not have a 401 in hand, fetch PRM at the conventional path:

```http
GET /.well-known/oauth-protected-resource
Host: abantpack.com
Accept: application/json
```

Response shape:

```json
{
  "resource": "https://abantpack.com",
  "resource_name": "Abant Makine - Paketleme ve Etiketleme",
  "authorization_servers": ["https://abantpack.com"],
  "scopes_supported": ["agent"],
  "bearer_methods_supported": ["header"]
}
```

Then fetch Authorization Server metadata from the first entry in `authorization_servers`:

```http
GET /.well-known/oauth-authorization-server
Host: abantpack.com
Accept: application/json
```

Read the `agent_auth` block in full — `skill`, `register_uri`, `claim_uri`, `identity_types_supported`, and the per-type `*_supported` arrays. The PRM is authoritative if anything in this file conflicts with it.

## Step 2 — Pick a method

This service currently supports **anonymous** registration only:

| What you have | Method |
|---|---|
| No verified user identity | `anonymous` |

Cross-check your choice against `agent_auth.identity_types_supported` and `agent_auth.anonymous.credential_types_supported` before sending a registration request.

## Step 3 — Register (anonymous)

```http
POST /agent/auth
Host: abantpack.com
Content-Type: application/json

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

Success response:

```json
{
  "registration_id": "reg_...",
  "registration_type": "anonymous",
  "credential": "<access_token>",
  "credential_type": "access_token",
  "credential_expires": "2026-06-11T09:00:00.000Z",
  "scopes": ["agent"],
  "claim_token": "<claim_token>",
  "claim_token_expires": "2026-06-18T08:00:00.000Z",
  "post_claim_scopes": ["agent"]
}
```

The pre-claim credential lets you begin reading public site content immediately at the `agent` scope.

## Step 4 — Claim ceremony (optional)

To associate the registration with a human operator, trigger a claim email:

```http
POST /agent/auth/claim
Host: abantpack.com
Content-Type: application/json

{
  "claim_token": "<claim_token from Step 3>",
  "email": "user@example.com"
}
```

The user receives a one-time code. Submit it to complete the claim:

```http
POST /agent/auth/claim/complete
Host: abantpack.com
Content-Type: application/json

{
  "claim_token": "<claim_token>",
  "otp": "123456"
}
```

## Step 5 — Use the credential

Send the access token on every request:

```http
GET /
Host: abantpack.com
Authorization: Bearer <access_token>
Accept: text/markdown
```

On `401 Unauthorized`, discard the credential and restart at Step 1.

## Errors

| Code | Endpoint | Action |
|---|---|---|
| `anonymous_not_enabled` | `POST /agent/auth` | Stop; this service does not accept anonymous registration |
| `unsupported_credential_type` | `POST /agent/auth` | Pick a supported method from Step 2 |
| `invalid_claim_token` | `POST /agent/auth/claim` | Restart at Step 3 |
| `otp_invalid` / `otp_expired` | `POST /agent/auth/claim/complete` | Request a new OTP via Step 4a |
| `credential_expired` | Any protected request | Restart at Step 1 |

## Revocation

Agents do not initiate revocation. If a previously working credential returns `401`, restart registration at Step 1.
