# auth.md

You are an agent. **Gülers & Partners** supports agentic registration: discover → register → (claim if needed) → use your credential → handle revocation. Follow the steps in order.

- **Resource server** (API and MCP): `https://www.gulerspartners.com`
- **Authorization server** (registration and claim): `https://www.gulerspartners.com`

## Step 1 — Discover

### 1a. Protected Resource Metadata

Fetch `/.well-known/oauth-protected-resource` on the resource server, or read the `resource_metadata` URL from a `401` response:

```http
WWW-Authenticate: Bearer resource_metadata="https://www.gulerspartners.com/.well-known/oauth-protected-resource"
```

```http
GET https://www.gulerspartners.com/.well-known/oauth-protected-resource
```

Read `resource`, `resource_name`, `resource_logo_uri`, `authorization_servers`, `scopes_supported`, and `bearer_methods_supported`. Use `resource` as the audience when minting an ID-JAG.

### 1b. Authorization Server metadata

```http
GET https://www.gulerspartners.com/.well-known/oauth-authorization-server
```

Read the top-level OAuth fields (`issuer`, `token_endpoint`, `revocation_endpoint`, `grant_types_supported`) and the full `agent_auth` block:

| Field | Purpose |
|-------|---------|
| `skill` | URL of this document |
| `register_uri` | `POST` here to register |
| `claim_uri` | `POST` here to start or continue a claim ceremony |
| `revocation_uri` | Provider-initiated revocation target |
| `identity_types_supported` | Accepted registration methods |
| `identity_assertion.assertion_types_supported` | ID-JAG and verified-email shapes |
| `identity_assertion.credential_types_supported` | `access_token` or `api_key` for asserted identities |
| `anonymous.credential_types_supported` | `access_token` or `api_key` for anonymous registration |
| `events_supported` | Upstream identity events the service accepts |

If anything here conflicts with the PRM, treat the PRM as authoritative for resource-scoped fields.

## Step 2 — Pick a method

1. **You have an ID-JAG bound to this service's audience** → `identity_assertion` + `urn:ietf:params:oauth:token-type:id-jag`
2. **You have only the user's verified email** → `identity_assertion` + `verified_email` (claim required)
3. **You have neither** → `anonymous` (optional claim later)

Cross-check your choice against the matching `*_supported` array in `agent_auth` before sending.

## Step 3 — Register

All registrations are `POST` requests to `register_uri` (`https://www.gulerspartners.com/agent/auth`).

### identity_assertion + ID-JAG

Confirm with the user before asserting their identity. Mint an ID-JAG with `aud` = the PRM `resource`, fresh `jti`, near-term `exp`, and a recent `auth_time`.

```http
POST /agent/auth HTTP/1.1
Host: www.gulerspartners.com
Content-Type: application/json

{
  "type": "identity_assertion",
  "assertion_type": "urn:ietf:params:oauth:token-type:id-jag",
  "assertion": "<ID-JAG JWT>",
  "requested_credential_type": "access_token"
}
```

Success (immediate credential):

```json
{
  "registration_id": "reg_...",
  "registration_type": "identity_assertion",
  "credential_type": "access_token",
  "credential": "<token>",
  "credential_expires": "2026-06-06T12:00:00.000Z",
  "scopes": ["openid", "profile", "mcp.read", "content.read"]
}
```

### identity_assertion + verified email

```http
POST /agent/auth HTTP/1.1
Host: www.gulerspartners.com
Content-Type: application/json

{
  "type": "identity_assertion",
  "assertion_type": "verified_email",
  "assertion": "user@example.com",
  "requested_credential_type": "access_token"
}
```

Returns a `claim_token` and `post_claim_scopes`; no credential until the claim ceremony completes.

### anonymous

```http
POST /agent/auth HTTP/1.1
Host: www.gulerspartners.com
Content-Type: application/json

{
  "type": "anonymous",
  "requested_credential_type": "api_key"
}
```

Returns a pre-claim credential plus a `claim_token` for optional later ownership.

## Step 4 — Claim ceremony

When a flow requires claim:

1. **Trigger** (anonymous only): `POST https://www.gulerspartners.com/agent/auth/claim` with `claim_token` and the user's email.
2. **Hand off**: Surface the OTP or verification instructions to the user.
3. **Complete**: `POST https://www.gulerspartners.com/agent/auth/claim/complete` with `claim_token` and the OTP.

Poll `token_endpoint` with grant type `urn:workos:agent-auth:grant-type:claim` when the service documents authorization-pending responses.

## Step 5 — Use the credential

Send credentials as `Authorization: Bearer <credential>` on MCP and API requests. Supported scopes include `openid`, `profile`, `mcp.read`, and `content.read`.

On `401` from a previously working credential, discard it and restart at Step 1.

## Step 6 — Revocation

Agents do not initiate revocation directly.

- **ID-JAG flows**: the agent provider may POST a security event to `revocation_uri`. Expect a `401` on the next API call.
- **Email and anonymous flows**: users revoke access through the service; treat unexpected `401` responses as a signal to re-register.

## Errors

| Error | Typical cause | Action |
|-------|---------------|--------|
| `invalid_signature` | Bad ID-JAG | Re-mint at provider |
| `invalid_audience` | Wrong `aud` | Use PRM `resource` |
| `login_required` | Stale `auth_time` | Re-authenticate at provider |
| `interaction_required` | Account linking needed | Run claim ceremony |
| `unsupported_credential_type` | Type not in `*_supported` | Pick another type |
| `otp_invalid` / `otp_expired` | Claim code issue | Request a fresh claim |

## Contact

Human support: info@gulers.av.tr
