# auth.md

> District.org agent registration and authentication metadata.
> Spec: <https://workos.com/auth-md> · <https://github.com/workos/auth.md>

District.org is a marketing + signup surface. Today there are **no
OAuth-protected APIs** here — every endpoint advertised in
[`/.well-known/api-catalog`](/.well-known/api-catalog) is public and
unauthenticated. Authentication happens inside the District product at
`https://app.district.org/`, not on this domain.

This file exists so that agent scanners can discover (a) what credentials
are required for the public API surface (none), (b) where to register if
an integration needs higher rate limits or a real client identity, and
(c) where the placeholder OAuth/OIDC metadata lives for the day a real
issuer ships.

## Audience

| Audience | Allowed | Method |
| --- | --- | --- |
| Anonymous AI agents | yes | Direct `https` calls to endpoints in [`/.well-known/api-catalog`](/.well-known/api-catalog). No registration required. |
| Identified AI agents | yes (light) | Send a `User-Agent` describing the agent + vendor; District may grant elevated rate limits after manual review (see registration below). |
| Authenticated human users | n/a here | Use `https://app.district.org/` instead. |

## Registration endpoint

Auto-registration is **not** implemented yet. Submit an integration
request through the contact form:

- **URL:** <https://district.org/en/contact>
- **Method:** `POST /api/floor-feedback-submit.php`
- **Spec:** <https://district.org/.well-known/api/feedback.openapi.json>

Include: agent name, vendor, technical contact, expected QPS, list of
endpoints you intend to call. We will respond by email.

## Supported registration methods

### Anonymous (no credentials)

This is the default. Any agent can call public endpoints without a
token. Honor `429 Too Many Requests` and the `Retry-After` header.

- `identity_types_supported`: `anonymous`
- `credential_types_supported`: (none — calls are unauthenticated)
- `claim_uri`: <https://district.org/en/contact>

### Verified email (manual)

Once an integration request has been approved District may issue a
shared secret or an allow-listed API key out of band by email.

- `identity_types_supported`: `verified_email`
- `assertion_types_supported`: `verified_email`
- `credential_types_supported`: `api_key` (out of band)
- `claim_uri`: <https://district.org/en/contact>

### ID-JAG / OAuth client credentials

Not available yet. The agent_auth block in
[`/.well-known/oauth-authorization-server`](/.well-known/oauth-authorization-server)
lists empty arrays for these flows. They will be populated when a real
OAuth issuer is published.

- `revocation_uri`: not implemented
- `claim_uri`: <https://district.org/en/contact>

## OAuth / OIDC discovery (placeholders)

| Document | URL |
| --- | --- |
| Authorization Server Metadata (RFC 8414) | <https://district.org/.well-known/oauth-authorization-server> |
| OpenID Connect Discovery 1.0 | <https://district.org/.well-known/openid-configuration> |
| Protected Resource Metadata (RFC 9728) | <https://district.org/.well-known/oauth-protected-resource> |

Each currently advertises an empty `grant_types_supported` /
`authorization_servers` array, signalling **no live OAuth on this
origin**. The PRM document still declares `bearer_methods_supported:
["header"]` so that — once a real authorization server ships — agents
that pre-fetched these documents know which transport to use.

## Where authentication actually lives

| Resource | Where | Method |
| --- | --- | --- |
| Freemium signup | `https://app.district.org/signup` | Email + password / Google / Apple |
| Membership signup | `https://app.district.org/membership` | Same |
| Founder Package checkout | `https://buy.stripe.com/eVqeVe0pu4NOgMAfArfnO07` | Stripe-hosted |

## Contact

- Web form: <https://district.org/en/contact>
- LinkedIn: <https://www.linkedin.com/company/districtorg/>
- X / Twitter: <https://x.com/DistrictO64339>
