> ## Documentation Index
> Fetch the complete documentation index at: https://docs.neobank.proofof.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Auth0 BFF and approved OAuth clients

> Customer, operator, and agent authentication via Auth0 BFF sessions, approved OAuth clients, and one-use confirmation intents.

# ADR 0003: Use Auth0 BFF sessions and approved OAuth clients

This record defines customer, operator, and external-agent authentication.

## Context

The customer browser must not store identity or Perflo bearer tokens. Autonomous agents need revocable offline access tied to customer mandates.

## Decision

Use an Auth0 confidential application for the same-origin backend-for-frontend (BFF). Store session state in Redis and set an opaque HTTP-only cookie. Require cross-site request forgery protection and transaction-bound step-up for sensitive actions.

Use a separate Auth0 operator application with mandatory multifactor authentication. Register external clients manually and use authorization code with Proof Key for Code Exchange (PKCE), rotating refresh tokens, and short-lived API tokens.

Sensitive customer actions use server-issued confirmation intents. Each intent is bound to the customer, action, and canonical payload hash, expires after ten minutes, and can be consumed once. The Auth0 step-up callback confirms the intent only after matching the customer subject and multifactor claim. A recent multifactor session may confirm a new intent without another redirect, but it cannot authorize a different payload.

The customer login cannot accept an operator role. Operator sessions must originate from the dedicated operator client and carry the operator role; this prevents role leakage in the customer application from opening the restricted console.

## Consequences

OAuth scopes permit access to an API family, while the mandate binds a client and delegated customer subject to a customer, recipient, and limits. Operations and audit events retain both the subject and OAuth client ID so a different client cannot read the result and operators can attribute each delegated action. Browser compromise cannot directly read server-held tokens.

## Rejected alternatives

* **Clerk**: its standard session token must remain browser-readable.
* **Independent Privy**: it duplicates Perflo's identity and wallet control plane.
* **Cloudflare Access one-time password**: it does not cover retail identity lifecycle and transaction authorization.
