reference

authentication

route access, api keys, and session auth

authentication

default: all unmatched routes require auth. GET routes default to public.

public access

all GET endpoints are public — no auth needed.

the following POST routes are also public:

method route
POST /embed/*/encrypt
POST /embed/*/decrypt
POST /tools/*/execute

everything else — any POST, PUT, PATCH, DELETE not listed above — requires authentication.

api key

pass an api key via the X-API-Key header:

curl -H "X-API-Key: sk_your_key" gnu.foo/internal/render/mermaid

keys are stored in kv with scopes and a userId. invalid keys return 401.

session

better auth handles session-based auth at /api/auth. supports cookie and bearer token via the bearer plugin.

if no api key is present, the middleware checks for an active session. no session on a protected route returns 401.

protected routes

method route rate limit
POST /internal/render/mermaid 10/60s
POST /internal/layout/elk 50/60s

these are the only explicitly protected routes with rate limits. any other non-public route also requires auth but has no per-route rate limit — just the global baseline.

middleware order

auth runs before rate limiting — failed auth doesn't count against your rate limit.

excluded from auth middleware entirely: /api/auth/*, /_admin/*.

errors

{
  "type": "https://api.gnu.foo/errors/unauthorized",
  "title": "unauthorized",
  "status": 401,
  "detail": "authentication required for this endpoint",
  "_links": { "self": { "href": "/path" } }
}