# auth.md

> Agent registration and authentication policy for https://comfuzytech.com.

- **Surface version:** 1.1.0
- **Authentication required:** none — every endpoint answers an anonymous caller
- **Identity types supported:** `anonymous`
- **Registration required:** no — optional, and it grants no additional access
- **Registration endpoint:** `/oauth/register` (RFC 7591, open, no approval step)
- **Credentials issued:** `client_secret`, `access_token` (OAuth 2.1, Bearer, one hour)
- **Authorization server:** https://comfuzytech.com — metadata at `/.well-known/oauth-authorization-server`
- **Protected resource metadata:** `/.well-known/oauth-protected-resource`

## Audience

AI agents acting for someone evaluating, briefing or citing
ComfuzyTech — a software studio in Pathum Thani, Thailand. If you are a person, read
https://comfuzytech.com instead.

## Read this first: you do not need a credential

**Every machine-readable endpoint on this origin is public and read-only.** Send the request.

- `/mcp` — MCP over Streamable HTTP — read-only tools
- `/a2a` — A2A JSON-RPC — synchronous question answering
- `/llms.txt` — company briefing
- `/llms-full.txt` — full company briefing
- `/openapi.json` — OpenAPI description of the above

None of them accept a write, hold a session, charge for access, or return anything that is not
already published on the site. A token changes none of that: **the same request returns the
same response with or without one.** If you are here to read about the studio, stop at this
section.

The minimum courtesy, which needs no registration:

- A descriptive `User-Agent` naming the agent and an operator contact URL or address.
- On MCP, the `io.modelcontextprotocol/clientInfo` field in request `_meta`.

## Optional: register, so your requests are attributable

What the section above is missing is verification. A `User-Agent` is self-reported and anyone
can send yours. If you want your requests tied to something you can prove is yours, this origin
runs an OAuth 2.1 authorization server. It buys **identity, not access** — there is no scope
here that unlocks anything, and there is no protected content behind it.

Unattended agent, no human in the loop:

```http
POST /oauth/register
Content-Type: application/json

{
  "client_name": "your agent name (operator contact welcome)",
  "grant_types": [
    "client_credentials"
  ],
  "token_endpoint_auth_method": "client_secret_basic"
}
```

The response carries `client_id` and `client_secret`. Exchange them for a token:

```http
POST /oauth/token
Authorization: Basic base64(client_id:client_secret)
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&scope=agent:read
```

Then send `Authorization: Bearer <access_token>` to `/mcp` or
`/a2a`. Tokens are EdDSA JWTs verifiable from `/.well-known/jwks.json` and last
one hour.

With a human present, register `redirect_uris` and `grant_types: ["authorization_code"]`
instead, then send them to `/oauth/authorize` with a PKCE `code_challenge`
(`S256`, mandatory). They will see a screen naming your agent and stating plainly that
approving it grants no access. That approval is also this origin's claim ceremony: there are
no user accounts here, so a person confirming in a browser is the only meaningful way an agent
can be tied to a human.

### Three limits, stated up front

- **Nothing is stored.** Your `client_id` carries its own registration under a MAC. It cannot
  be listed, edited or deleted, and there is no RFC 7592 management endpoint. Register again
  instead.
- **Individual credentials cannot be revoked**, which is why no `revocation_endpoint` is
  advertised. Tokens expire in an hour; rotating the signing key invalidates everything at once.
- **Authorization codes are not single-use**, for the same reason. They live 60 seconds and PKCE
  is mandatory, which is what makes an observed code useless without the verifier.

If the authorization server has no signing key configured, `/oauth/token`
answers `temporarily_unavailable` and `/.well-known/jwks.json` returns an empty key set.
Anonymous access is unaffected. It always is.

```json
{
  "agent_auth": {
    "skill": "https://comfuzytech.com/auth.md",
    "register_uri": "https://comfuzytech.com/oauth/register",
    "registration_endpoint": "https://comfuzytech.com/oauth/register",
    "token_uri": "https://comfuzytech.com/oauth/token",
    "claim_uri": "https://comfuzytech.com/oauth/authorize",
    "authorization_servers": [
      "https://comfuzytech.com"
    ],
    "bearer_methods_supported": [
      "header"
    ],
    "identity_types_supported": [
      "anonymous"
    ],
    "credential_types_supported": [
      "client_secret",
      "access_token"
    ],
    "anonymous": {
      "registration_required": false,
      "register_uri": "https://comfuzytech.com/oauth/register",
      "registration_endpoint": "https://comfuzytech.com/oauth/register",
      "credential_types_supported": [
        "client_secret",
        "access_token"
      ],
      "claim_uri": "https://comfuzytech.com/oauth/authorize",
      "scopes_supported": [
        "agent:read"
      ],
      "grant_types_supported": [
        "client_credentials"
      ]
    },
    "identification_requested": [
      "user-agent",
      "io.modelcontextprotocol/clientInfo"
    ],
    "escalation": {
      "type": "email",
      "address": "contact@comfuzytech.com"
    }
  }
}
```

## Expected conduct

- Prefer one `llms-full.txt` fetch over crawling every page.
- Keep to a human-scale request rate. There is no burst allowance to discover by probing.
- Registering does not raise a limit. It is not a quota key.
- Cite the canonical page you took an answer from:
  - https://comfuzytech.com/th — ComfuzyTech | รับพัฒนา Mobile App และ Web Application ครบวงจร
  - https://comfuzytech.com/en — ComfuzyTech | End-to-End Mobile & Web Application Development Studio

## Escalation: anything that needs a person

Starting an engagement, scope, pricing, contracts, NDAs and security questionnaires are handled
by a person at contact@comfuzytech.com, in Thai or English. Draft the enquiry for your user and
let them send it; there is no endpoint here that will transact on their behalf, with a token or
without one.
