Files
KIS-TOiR/auth/frontend-auth-rules.md

4.2 KiB

Frontend Auth Rules

This document defines mandatory frontend authentication behavior for generated applications.


Generated Files

The generator must create at minimum:

  • client/src/config/env.ts
  • client/src/auth/keycloak.ts
  • client/src/auth/authProvider.ts
  • client/src/App.tsx
  • client/src/main.tsx
  • client/src/dataProvider.ts
  • client/.env.example

App.tsx, main.tsx, and dataProvider.ts must be generated in an auth-aware form. Auth must not be bolted on later.


Login Model

The generated frontend must use:

  • Keycloak JS
  • Authorization Code Flow + PKCE
  • PKCE method S256
  • redirect-based login only

The generator must not create a custom in-app username/password login form.

The generated SPA must initialize Keycloak before rendering the application. The app must not operate anonymously once auth is enabled.


React Admin Integration

The generated frontend must use a React Admin authProvider and connect it at the Admin root.

Rules:

  1. authProvider is mandatory.
  2. The generated Admin root must enforce authenticated operation.
  3. Auth bootstrap must happen before rendering Admin.

The generated frontend must not rely on anonymous access with later lazy auth attachment.


Identity Resolution

The generated authProvider.getIdentity() must derive identity from token claims already present in the parsed access token / parsed token.

Preferred claims:

  • sub
  • preferred_username
  • email
  • name

Rules:

  1. getIdentity() must be token-claim based by default.
  2. The generated frontend must not call keycloak.loadUserProfile() during normal app startup or baseline identity resolution.
  3. The generated frontend must not depend on the Keycloak /account endpoint for baseline CRUD/admin generation.
  4. The default generator strategy is to avoid the /account request entirely, not to broaden Keycloak CORS behavior.
  5. Any network-based account-profile integration requires an explicit future prompt.

The generator must not introduce startup/profile-fetch requests that are unnecessary for authorization.


Shared Request Seam

The generated frontend must use the shared request seam in client/src/dataProvider.ts as the single place where access tokens are attached.

Rules:

  1. All backend requests must carry Authorization: Bearer <access_token>.
  2. This must cover all React Admin calls, including:
    • list
    • get one
    • get many
    • get many reference
    • create
    • update
    • delete
  3. Reference/resource lookups must flow through the same authenticated request seam.

The generator must not scatter token attachment across resource components.


Error Semantics

The generated authProvider.checkError must distinguish authentication failures from authorization failures:

  • 401 -> force logout / re-authentication
  • 403 -> do not re-authenticate; surface access denied / permission error to React Admin

The generator must not treat 401 and 403 as equivalent.


Token Refresh

The generated frontend must refresh tokens before protected API calls when needed.

Refresh behavior must be concurrency-safe:

  • use one shared in-flight refresh operation
  • parallel requests must wait for the same refresh promise
  • do not trigger multiple parallel refresh requests for the same expiry window

The generator must explicitly describe or implement the shared in-flight refresh pattern.


Browser Storage Rules

The generated frontend must not store access tokens or refresh tokens in:

  • localStorage
  • sessionStorage

In-memory handling via Keycloak JS behavior is the default rule for this repository.


Frontend Environment Contract

The generated frontend env contract must include:

  • VITE_API_URL
  • VITE_KEYCLOAK_URL
  • VITE_KEYCLOAK_REALM
  • VITE_KEYCLOAK_CLIENT_ID

The generated frontend config module must fail fast if required auth variables are missing.

The generated frontend must not silently fall back to production auth settings in code.


Default Values for Examples

client/.env.example must use these repository defaults as examples:

VITE_API_URL=http://localhost:3000
VITE_KEYCLOAK_URL=https://sso.greact.ru
VITE_KEYCLOAK_REALM=toir
VITE_KEYCLOAK_CLIENT_ID=toir-frontend