Security Model
Zero-token browser principle
The browser should not store raw access or refresh tokens. Authentication is represented by a secure cookie while the BFF owns the OAuth/OIDC token lifecycle.
Recommended cookie posture
HttpOnly = trueSecurePolicy = AlwaysSameSite = Laxby default; change only when your deployment model requires it- HTTPS in production
Threat boundary
flowchart LR
JS[Browser JavaScript] -. no raw token access .-> COOKIE[HttpOnly Session Cookie]
COOKIE --> BFF[Trusted BFF Boundary]
BFF --> TOKENS[OIDC Tokens\nServer-side only]
TOKENS --> API[Protected APIs]
CSRF and cross-site behavior
SameSite is part of the CSRF defense, not a substitute for understanding your request topology. If you deliberately use SameSite=None, require secure transport and review CORS/CSRF protections for the deployment.
XSS
HttpOnly prevents JavaScript from directly reading the authentication cookie, reducing token theft exposure. It does not remove the need for normal XSS defenses such as output encoding, CSP where appropriate, dependency hygiene and avoiding unsafe DOM injection.
Secrets
Never commit production ClientSecret values. Use environment variables, secret stores or your deployment platform’s protected configuration.
Distributed deployments
Process-local MemoryCacheTicketStore is appropriate for examples and single-instance scenarios. Multi-instance systems should use a distributed ticket/session implementation with lifecycle and revocation behavior suitable for the environment.