# auth.md: how agents authenticate to Necto Consulting

Reading is open: every surface marked "none" below answers an anonymous request, with no key and no login.

## Agent registration

Writing (the Publishing API) needs a Bearer token in the `Authorization` header. Tokens are issued by a person, not by an endpoint: write to info@necto-consulting.com with your organisation, the purpose of the integration, the expected volume and the scope you need (read or write). There is no self-service registration, on purpose.

## Steps this site does not offer

- **Claim**: none. A key is issued by a person after the review above and handed over out of band: no claim token, no code to enter, nothing to poll.
- **Revocation**: no revocation endpoint. A key is withdrawn by rotating it: the site's owner sets a new key and gives it to every client that keeps access (the new Publishing API key works beside the old one until the old one is retired, so such a client moves without a refusal); the old key then answers 401.
- **Token lifetime**: the Bearer token is the key itself. It does not expire; it stops working when it is rotated.

## Deliberately not built

- `/.well-known/oauth-authorization-server` (OAuth 2.0 authorization server metadata): Not built. Publishing uses a static token issued by a person; advertising an authorization server that does not exist would break every client that trusts it.
- `/.well-known/oauth-protected-resource` (OAuth 2.0 protected resource metadata): Not built, for the same reason.
- `/.well-known/agent-card.json` (A2A agent card): Not built: no A2A agent answers here, and a card without one is a promise nobody keeps.

## Surfaces

| Surface | What | Auth | CORS | Note |
|---|---|---|---|---|
| `GET https://necto-consulting.pages.dev/` | Every page as HTML; with Accept: text/markdown, as markdown at the same URL | none | no | pages send no CORS header: they are documents for browsers, and an agent reads the markdown server-side |
| `GET https://necto-consulting.pages.dev/robots.txt` | Crawler rules and Content-Signal | none | yes |  |
| `GET https://necto-consulting.pages.dev/sitemap.xml` | Every public URL, with lastmod and hreflang | none | yes |  |
| `GET https://necto-consulting.pages.dev/llms.txt` | An index of the site for language models: it names one index per section and language | none | yes |  |
| `GET https://necto-consulting.pages.dev/insights/llms.txt` | Llms.txt of a section: every published article by rubric, newest first, with its excerpt | none | yes |  |
| `GET https://necto-consulting.pages.dev/services/llms.txt` | Llms.txt of a section: the services, each with its page and summary | none | yes |  |
| `GET https://necto-consulting.pages.dev/developers/llms.txt` | Llms.txt of a section: the MCP tools, the HTTP endpoints, the rate limits and the discovery documents | none | yes |  |
| `GET https://necto-consulting.pages.dev/feed.xml` | RSS 2.0, full text (en) | none | yes |  |
| `GET https://necto-consulting.pages.dev/feed.json` | JSON Feed 1.1, full text (en) | none | yes |  |
| `GET https://necto-consulting.pages.dev/.well-known/agent-skills/index.json` | Agent skills index, each SKILL.md with its sha256 | none | yes |  |
| `GET https://necto-consulting.pages.dev/.well-known/auth.md` | This document | none | yes |  |
| `GET https://necto-consulting.pages.dev/auth.md` | This document, at the root | none | yes |  |
| `GET https://necto-consulting.pages.dev/.well-known/api-catalog` | API catalog (RFC 9727 linkset) | none | yes |  |
| `GET https://necto-consulting.pages.dev/api/health` | Liveness | none | yes |  |
| `GET https://necto-consulting.pages.dev/openapi.json` | OpenAPI 3.1 description of the public API | none | yes |  |
| `GET https://necto-consulting.pages.dev/.well-known/mcp/server-card.json` | MCP server card | none | yes |  |
| `POST https://necto-consulting.pages.dev/mcp` | MCP server, read-only tools (JSON-RPC over POST) | none | yes |  |
| `GET https://necto-consulting.pages.dev/.well-known/ai-catalog.json` | ARD catalog | none | yes |  |
| `GET https://necto-consulting.pages.dev/.well-known/ard.json` | ARD catalog, byte-identical | none | yes |  |
| `GET https://necto-consulting.pages.dev/api/` | The API's endpoint list: method, path and authentication of each, and where the docs are | none | yes |  |
| `GET https://necto-consulting.pages.dev/api/content/version` | Publishing API: render capabilities | none | yes |  |
| `POST https://necto-consulting.pages.dev/api/content/` | Publishing API: create an article (PUT and DELETE /api/content/{slug} likewise) | Bearer token | no | server to server: no CORS |
| `GET https://necto-consulting.pages.dev/api/content/catalog` | Publishing API: categories, tags and articles | Bearer token | no | server to server: no CORS |
| `GET https://necto-consulting.pages.dev/api/content/tags` | Publishing API: the tags of the published articles | Bearer token | no | server to server: no CORS |
| `POST https://necto-consulting.pages.dev/api/content/images` | Publishing API: upload an image into the site's own storage (multipart: file, slug, variant) | Bearer token | no | server to server: no CORS |

Generated from the table the site's own check (`scripts/auth-check.mjs`) walks against this host.
