# auth.md

This document tells AI agents and automated clients how to authenticate to the
WardByWard platform (The Gear Merchant) — ward-by-ward civic crowdfunding for
South Africa.

## Audience

This applies to agents and automated clients acting on behalf of a registered
user of the platform. Public read-only endpoints under `/api/` do not require
credentials; any write endpoint does.

## Registration

New users register by POSTing `application/x-www-form-urlencoded` fields to
`/register`:

- `phone` — South African phone number, e.g. `082 123 4567`
- `pin` — 4-6 digit PIN
- `full_name` — full legal name
- `id_number` — 13-digit South African ID number (Luhn-validated)
- `whatsapp` — optional WhatsApp number (defaults to `phone`)

Registration creates a Merchant record, a vault, and a session, then responds
with a `302` redirect that sets the session cookies below.

## Login

Agents authenticate by POSTing `application/x-www-form-urlencoded` to
`/login` with:

- `phone`
- `pin`

On success the server responds `302` and sets two HttpOnly cookies:

- `tgm_token=<token>; Path=/; HttpOnly; SameSite=Strict`
- `tgm_phone=<phone>; Path=/; HttpOnly; SameSite=Strict`

Present both cookies (e.g. the `Cookie` header `tgm_token=...; tgm_phone=...`)
on every subsequent request. Sessions expire after `SESSION_EXPIRY_DAYS`
days of inactivity. Rate limits (10 attempts/minute per client IP) apply to
login; 5 failed PIN attempts lock an account for 15 minutes.

## Bearer / OAuth

The platform does not currently issue OAuth 2.0 bearer tokens and does not
advertise an OAuth authorization server, so
`/.well-known/oauth-authorization-server` and
`/.well-known/oauth-protected-resource` are not published. Session-cookie
authentication (above) is the supported method for agents.

## Policy

- Never log, share or commit credentials.
- Agent requests are subject to the same rate limits, fraud checks and terms
  as browser traffic.
- The platform complies with the Protection of Personal Information Act
  (POPIA); account data is processed only with user consent.
