# auth.md

Machine-readable registration guide for AI agents that want to call the
Hemendoktor Directory API.

- **Audience:** autonomous agents and agent frameworks (MCP clients, A2A
  clients, LLM tool runtimes). Not for human end users — people should use the
  website directly.
- **Resource server:** `https://hemendoktor.com/api/v1`
- **Authorization server:** `https://hemendoktor.com`
- **Documentation:** `https://hemendoktor.com/api/docs`
- **Contact:** info@hemendoktor.com

## Discovery documents

| Document | URL |
| --- | --- |
| OAuth Protected Resource Metadata (RFC 9728) | <https://hemendoktor.com/.well-known/oauth-protected-resource> |
| OAuth Authorization Server Metadata (RFC 8414) | <https://hemendoktor.com/.well-known/oauth-authorization-server> |
| JWKS (RFC 7517) | <https://hemendoktor.com/.well-known/jwks.json> |
| API catalog (RFC 9727) | <https://hemendoktor.com/.well-known/api-catalog> |
| OpenAPI 3.1 description | <https://hemendoktor.com/api/v1/openapi.json> |
| MCP server card | <https://hemendoktor.com/.well-known/mcp/server-card.json> |
| A2A agent card | <https://hemendoktor.com/.well-known/agent-card.json> |
| Agent skills index | <https://hemendoktor.com/.well-known/agent-skills/index.json> |

## agent_auth

```json
{
  "skill": "https://hemendoktor.com/auth.md",
  "skill_name": "hemendoktor-directory",
  "register_uri": "https://hemendoktor.com/agent/register",
  "identity_types_supported": ["anonymous"],
  "anonymous": {
    "credential_types_supported": ["client_secret"],
    "claim_uri": "https://hemendoktor.com/agent/register"
  },
  "methods": [
    {
      "type": "anonymous",
      "spec": "https://www.rfc-editor.org/rfc/rfc7591",
      "identity_types_supported": ["anonymous"],
      "anonymous": {
        "credential_types_supported": ["client_secret"],
        "claim_uri": "https://hemendoktor.com/agent/register"
      },
      "credential_types_supported": ["client_secret"],
      "claim_uri": "https://hemendoktor.com/agent/register",
      "register_uri": "https://hemendoktor.com/agent/register",
      "request_method": "POST",
      "request_content_type": "application/json",
      "required_fields": ["client_name"],
      "optional_fields": ["contacts", "scope"],
      "token_uri": "https://hemendoktor.com/oauth/token",
      "grant_types_supported": ["client_credentials"],
      "token_endpoint_auth_methods_supported": ["client_secret_post", "client_secret_basic"],
      "scopes_supported": ["doctors:read", "slots:read"],
      "bearer_methods_supported": ["header"],
      "resource": "https://hemendoktor.com/api/v1",
      "credential_lifetime": "client_secret does not expire; access_token lives 3600 seconds",
      "rate_limit": "5 registrations per IP per hour",
      "documentation": "https://hemendoktor.com/auth.md"
    }
  ]
}
```

Registration is **anonymous** by design: an agent names itself and receives a
`client_secret`. We do not require a verified e-mail or an identity assertion
(ID-JAG), because the credential only unlocks directory data that is already
public on the website. Declaring a verified-identity flow we do not enforce
would be a false claim.

## How to use the credentials

1. `POST https://hemendoktor.com/agent/register` with `client_name` → receive `client_id` and
   `client_secret`. The secret is returned once; store it.
2. `POST https://hemendoktor.com/oauth/token` with `grant_type=client_credentials`, `client_id`,
   `client_secret` and optionally `scope` → receive an RS256 JWT
   (`expires_in: 3600`).
3. Send `Authorization: Bearer <access_token>` on `https://hemendoktor.com/api/v1/...` requests.
   Verify the token signature against `https://hemendoktor.com/.well-known/jwks.json` if you
   forward it onwards.
4. On `401`, the `WWW-Authenticate` header carries
   `resource_metadata="https://hemendoktor.com/.well-known/oauth-protected-resource"` — refetch
   metadata and retry with a fresh token.

## What the credentials grant

Read-only access to public directory data:

- `doctors:read` — physician search and physician details.
- `slots:read` — open online-appointment times for physicians who enabled
  online booking.

## What they do not grant

- No appointment creation, modification, or cancellation. Booking requires a
  phone-verified member session on the website; there is deliberately no agent
  path to it.
- No access to patient data, member records, appointment owners, or physician
  panel data.
- No user-delegated flow. `authorization_code` is not implemented; requests to
  `https://hemendoktor.com/oauth/authorize` return `unsupported_response_type` on purpose rather
  than pretending to support it.

## Acceptable use

Identify your agent honestly in `client_name`. Respect `robots.txt` and the
`Content-Signal` header. Cache responses where you can — directory data changes
slowly, availability does not (do not poll `slots` faster than once a minute
per physician). Abusive clients are deactivated by `client_id`.
