Skip to content
aknWiki

Authentication

Six credential types are accepted. Which one an endpoint takes is fixed per endpoint and is listed on the reference page for that group.

Credential Presented as Accepted by
Session cookie Cookie: __session=<value> Session, people, status and project-gated endpoints
ID token Authorization: Bearer <id_token> POST /auth/verify in the body, and project-gated endpoints in the header
API key x-api-key: <key> POST /startpage/notify
OIDC access token Authorization: Bearer <access_token> GET /auth/oidc/userinfo
OIDC client credentials Basic authorisation, or client_id and client_secret in the body POST /auth/oidc/token
Request signature ZITADEL-Signature: t=<unix>,v1=<hex> POST /auth/zitadel/claims

Public endpoints accept no credential and ignore any that is sent.

Credential How it is obtained
ID token Sign in at https://id.akn.me.uk. The sign-in produces an ID token for the account
Session cookie Exchange an ID token at POST /auth/verify. The response sets the cookie
Custom token POST /auth/otp/sign-in and the bridge callback both return a custom token, which the browser exchanges for an ID token
API key Issued by the site operator. There is no self-service path
OIDC client credentials Registered by the site operator against a fixed redirect URI allowlist
Signing secret Shared with the upstream identity provider by the site operator

POST /auth/verify sets the session cookie on a successful, approved sign-in.

Property Value
Name __session
Lifetime 14 days from issue
Domain .akn.me.uk, so every akn subdomain sends it
Flags HttpOnly, Secure, SameSite=Lax
Renewal None. A new cookie requires a fresh call to POST /auth/verify
Revocation POST /auth/logout clears the cookie in the calling browser only

Two cookie formats verify successfully: the current akn ID session token and the older provider session cookie issued before the cutover. A caller does not choose which is issued.

POST /auth/session/refresh reports whether the cookie is still valid and returns the person behind it. It does not extend the lifetime.

Authentication proves the account. Three further checks decide access.

Check Applies to Requirement
Account status Every gated endpoint The person’s status is approved
Project grant Project-gated endpoints projects contains the required name or *, or the role is admin
Admin role People administration The role is admin

The status values a caller can encounter are pending, approved and rejected. A person who has never been reviewed is pending.

Project name Gates
startpage GET /startpage/notifications, GET /calendar/events
status The /status endpoints, alongside the admin role
Condition Status Body
No credential, or one that does not verify 401 {"error":"Unauthorized"}
Verified account with no person record 403 {"error":"Forbidden"}
Verified account not approved 403 {"error":"Forbidden","reason":"pending"}
Approved account without the project grant 403 {"error":"Forbidden"}
Approved account without the admin role 403 {"error":"Forbidden"}
Account lookup unavailable 503 {"error":"Authorization unavailable"}

A 503 is not an authentication failure. Retry rather than discarding the credential and signing in again.

POST /auth/verify is the exception to the table. A sign-in that authenticates but is not approved returns 200 with approved: false and a reason. See Sessions and sign-in.

Caller origin Behaviour
https://akn.me.uk, https://www.akn.me.uk, https://id.akn.me.uk, https://halcyon.akn.me.uk, https://startpage.akn.me.uk, https://thoughts.akn.me.uk, https://status.akn.me.uk Allowed, with credentials
Any origin, on /auth/oidc/ paths and the root discovery document Allowed, without credentials
Any other origin No allow-origin header is returned. The browser blocks the response
Property Value
Methods GET, POST, PATCH, DELETE, OPTIONS
Request headers Content-Type, Authorization, x-api-key
Preflight OPTIONS answers 204
Credentialed requests Send the session cookie only from an allowed origin

A caller on an origin outside the list works server to server, where the browser policy does not apply.

Surface Limit
POST /auth/otp/send One code per address per 60 seconds, and five per address per hour
Email code attempts Five attempts per code, after which the code is destroyed
Every other endpoint No limit is applied
  • Sessions and sign-in covers the endpoints that issue and end sessions.
  • Errors covers status codes and error bodies in full.
  • Diagnostics covers refused credentials and blocked origins.