Authentication Contract

Current Choice

  • whatsapp-adapter-app uses SimpleAuth.
  • whatsapp-adapter-api uses bearer-token authentication for non-browser clients.

Scope

  • whatsapp-adapter-app is the user-facing module.
  • whatsapp-adapter-api is intended for other systems and operator tooling.
  • whatsapp-adapter-waha is not a public auth boundary and should stay private.
  • Public API publication and versioning rules live in docs/api-publication.md.

Integration Rules

  • whatsapp-adapter-app reads SIMPLE_AUTH_* configuration from env.
  • whatsapp-adapter-app stores authenticated user identity in the Flask session cookie.
  • whatsapp-adapter-app protects browser routes by default and keeps only a short allowlist for auth entrypoints, static assets, health checks, and the signed-out page.
  • whatsapp-adapter-app talks to whatsapp-adapter-api with Authorization: Bearer <token>.
  • whatsapp-adapter-app keeps its client token in API_BEARER_TOKEN.
  • whatsapp-adapter-api keeps its token registry in whatsapp-adapter-api/data/api-tokens.csv.
  • whatsapp-adapter-api reads the registry path from API_TOKENS_FILE.
  • whatsapp-adapter-api treats GET /healthz as the only public endpoint.
  • whatsapp-adapter-api denies every other request by default when API_AUTH_ENABLED=true.
  • whatsapp-adapter-api accepts a request only when the bearer token value exactly matches a row in the CSV registry.
  • Public API docs must describe the HTTP bearer scheme and the expected 401 and 403 responses for protected endpoints.
  • The token registry CSV header is token,issued_to,date.
  • Each CSV row stores the raw token value, who it was issued to, and the issue date for operator orientation.
  • Changing the token registry requires restarting whatsapp-adapter-api so the process reloads the file.
  • When SIMPLE_AUTH_ENABLED=false, whatsapp-adapter-app allows local bootstrap access without remote auth.

Exceptions

  • GET /logged-out is intentionally public so the browser can show a logout confirmation page with a link back to /, which starts a fresh SimpleAuth login when needed.