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

3.0 KiB

Auth Rules

Use this document during the Auth / Runtime / Realm stage defined in prompts/general-prompt.md.

Purpose

Generate and preserve the auth contracts that let the CRUD app run as a React Admin SPA backed by a NestJS API protected by external Keycloak.

Mandatory Inputs

  • prompts/general-prompt.md
  • prompts/runtime-rules.md
  • current repository auth/runtime defaults

Expected Outputs

  • client/src/auth/
  • client/src/dataProvider.ts
  • server/src/auth/
  • toir-realm.json

Frontend Auth Invariants

  • use keycloak-js with redirect-based login only
  • initialize Keycloak before rendering the SPA
  • use Authorization Code Flow + PKCE (S256)
  • keep authProvider, dataProvider, getIdentity(), getPermissions(), and checkError() as stable seams
  • derive identity from token claims already present in the token
  • do not call loadUserProfile()
  • 401 forces re-authentication; 403 remains an authorization error
  • keep token handling in memory with one shared in-flight refresh path

Backend Auth Invariants

  • verify JWTs with jose
  • validate issuer, audience, and signature via JWKS
  • resolve JWKS in this order:
    1. KEYCLOAK_JWKS_URL
    2. OIDC discovery at /.well-known/openid-configuration
    3. ${issuer}/protocol/openid-connect/certs
  • extract roles only from realm_access.roles
  • keep /health public
  • generated CRUD routes stay protected by default

Working Runtime Defaults

Keep these defaults unless a task explicitly overrides them:

  • VITE_KEYCLOAK_URL=https://sso.greact.ru
  • VITE_KEYCLOAK_REALM=toir
  • VITE_KEYCLOAK_CLIENT_ID=toir-frontend
  • KEYCLOAK_ISSUER_URL=https://sso.greact.ru/realms/toir
  • KEYCLOAK_AUDIENCE=toir-backend
  • CORS_ALLOWED_ORIGINS=http://localhost:5173,https://toir-frontend.greact.ru

Anti-regression rule:

  • do not revert shared examples to localhost Keycloak defaults unless a task explicitly requests a local Keycloak baseline

Realm Artifact Contract

The root realm artifact is mandatory and must:

  • be importable and versioned
  • align with generated frontend/backend env contracts
  • parameterize:
    • realm name
    • frontend client id
    • backend client id / audience
    • local and production frontend URLs
    • artifact filename
  • explicitly deliver:
    • sub
    • aud
    • realm_access.roles
  • define:
    • realm roles admin, editor, viewer
    • a public SPA client with PKCE S256
    • a bearer-only backend client
    • an explicit audience client scope
    • protocol mappers for baseline identity and role claims

Completion Expectations

Auth/runtime generation is incomplete if any of the following is true:

  • frontend and backend auth seams drift from each other
  • JWKS resolution order changes
  • /health stops being public
  • shared Keycloak defaults regress to localhost examples
  • the realm artifact no longer matches backend/frontend expectations