# auth.md

This service supports agentic registration and automated authentication per the Auth.md specification.
- Resource Server: `https://api.sivec.com.ar`
- Authorization Server: `https://www.sivec.com.ar`
- Web Application & User Claim: `https://app.sivec.com.ar/login`

---

## 1. Discover

Agents discover authentication capabilities through standard discovery metadata:

1. Fetch Protected Resource Metadata (PRM) at `https://www.sivec.com.ar/.well-known/oauth-protected-resource`:
   - `resource`: `https://www.sivec.com.ar`
   - `authorization_servers`: `["https://www.sivec.com.ar"]`
   - `scopes_supported`: `["vehicles:read", "leads:write", "stock:manage"]`
   - `bearer_methods_supported`: `["header"]`

2. Fetch Authorization Server Metadata at `https://www.sivec.com.ar/.well-known/oauth-authorization-server`:
   - `issuer`: `https://www.sivec.com.ar`
   - `token_endpoint`: `https://www.sivec.com.ar/oauth2/token`
   - `revocation_endpoint`: `https://www.sivec.com.ar/oauth2/revoke`
   - `agent_auth.identity_endpoint`: `https://www.sivec.com.ar/agent/identity`
   - `agent_auth.claim_endpoint`: `https://www.sivec.com.ar/agent/identity/claim`
   - `agent_auth.events_endpoint`: `https://www.sivec.com.ar/agent/event/notify`

---

## 2. Pick a method

Select the registration method according to your available agent credentials:

- **ID-JAG / Attested Session** (`identity_assertion`): Agent possesses a provider-signed assertion (`urn:ietf:params:oauth:token-type:id-jag`).
- **User Email Only** (`service_auth`): User provided an email (`login_hint`), requiring a claim ceremony.
- **Anonymous Start** (`anonymous`): Agent self-registers without prior identity and defers claim until ownership is assigned.

---

## 3. Register

### identity_assertion (Agent Verified)

```http
POST /agent/identity HTTP/1.1
Host: www.sivec.com.ar
Content-Type: application/json

{
  "type": "identity_assertion",
  "assertion_type": "urn:ietf:params:oauth:token-type:id-jag",
  "assertion": "<ID_JAG_ASSERTION_JWT>"
}
```

Response:
```json
{
  "registration_id": "reg_01SIVEC123DEF456",
  "registration_type": "identity_assertion",
  "identity_assertion": "<service-signed JWT>",
  "assertion_expires": "2026-12-31T23:59:59.000Z",
  "scopes": ["vehicles:read", "leads:write", "stock:manage"]
}
```

### service_auth (Email Claim Flow)

```http
POST /agent/identity HTTP/1.1
Host: www.sivec.com.ar
Content-Type: application/json

{
  "type": "service_auth",
  "login_hint": "concesionaria@sivec.com.ar"
}
```

Response:
```json
{
  "registration_id": "reg_01SIVEC123DEF456",
  "registration_type": "service_auth",
  "claim_url": "/agent/identity/claim",
  "claim_token": "clm_sivec987654321",
  "claim_token_expires": "2026-12-31T23:59:59.000Z",
  "post_claim_scopes": ["vehicles:read", "leads:write", "stock:manage"],
  "claim": {
    "user_code": "481920",
    "expires_in": 600,
    "verification_uri": "https://app.sivec.com.ar/login?claim=clm_sivec987654321",
    "interval": 5
  }
}
```

### anonymous (Self-Registration)

```http
POST /agent/identity HTTP/1.1
Host: www.sivec.com.ar
Content-Type: application/json

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

Response:
```json
{
  "registration_id": "reg_01SIVECANON123",
  "registration_type": "anonymous",
  "identity_assertion": "<service-signed JWT>",
  "assertion_expires": "2026-12-31T23:59:59.000Z",
  "pre_claim_scopes": ["vehicles:read"],
  "claim_url": "/agent/identity/claim",
  "claim_token": "clm_sivecanon12345",
  "claim_token_expires": "2026-12-31T23:59:59.000Z",
  "post_claim_scopes": ["vehicles:read", "leads:write", "stock:manage"]
}
```

---

## 4. Claim ceremony

For `anonymous` and `service_auth` flows:

1. **4a. Get ceremony materials:** The agent receives `user_code` and `verification_uri`.
2. **4b. Hand off to user:** The agent displays the `verification_uri` and 6-digit `user_code` to the dealership manager.
3. **4c. Poll for completion:** The agent polls `/oauth2/token` with the claim grant:

```http
POST /oauth2/token HTTP/1.1
Host: www.sivec.com.ar
Content-Type: application/x-www-form-urlencoded

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

---

## 5. Exchange the assertion

Exchange the service-signed `identity_assertion` for an access token via RFC 7523 JWT-Bearer grant:

```http
POST /oauth2/token HTTP/1.1
Host: www.sivec.com.ar
Content-Type: application/x-www-form-urlencoded

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=<identity_assertion>&resource=https://api.sivec.com.ar
```

Response:
```json
{
  "access_token": "siv_sec_token_987654321",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "vehicles:read leads:write stock:manage"
}
```

---

## 6. Use the access_token

All authenticated requests to the SIVEC resource server (`https://api.sivec.com.ar`) must include the bearer credential:

```http
GET /v1/public/vehicles HTTP/1.1
Host: api.sivec.com.ar
Authorization: Bearer siv_sec_token_987654321
Accept: application/json
```

---

## 7. Errors

| Error Code | Endpoint | Description |
| :--- | :--- | :--- |
| `invalid_issuer` | `/agent/identity` | Unrecognized ID-JAG provider issuer. |
| `invalid_signature` | `/agent/identity` | Cryptographic signature mismatch. |
| `interaction_required` | `/agent/identity` | First-link step-up required by user. |
| `authorization_pending` | `/oauth2/token` | User has not yet completed code entry. |
| `expired_token` | `/oauth2/token` | Claim attempt timed out. |
| `invalid_grant` | `/oauth2/token` | Invalid assertion or revoked delegation. |

---

## 8. Revocation

- **Credential Layer (RFC 7009):** `POST /oauth2/revoke` with `token=<access_token>&token_type_hint=access_token`.
- **Registration Layer (RFC 8935 SET):** Provider sends `secevent+jwt` push notification to `https://www.sivec.com.ar/agent/event/notify` with schema `https://schemas.workos.com/events/agent/auth/identity/assertion/revoked`.
