Files
toir-automatization/.claude/worktrees/goofy-haslett/prompts/auth-rules.md
2026-04-07 19:40:41 +03:00

3.8 KiB

Auth Rules

Use this document during the D. Shared Platform Scaffold and F. Integration stages 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. The realm import is a deploy/runtime artifact and is part of the generated workspace, not a sample.

Ownership rule:

  • the parent owns the auth platform skeleton and shared auth seams
  • specialized generators may attach resource-aware bindings only inside their delegated zones
  • do not redesign the shared auth platform from inside a resource generator

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

Approved Auth Dependency Baseline

  • keycloak-js: 26.2.3
  • jose: 6.2.2

Pinning rules:

  • Keep frontend auth on the approved keycloak-js version during routine regeneration.
  • Keep backend JWT verification on the approved jose version during routine regeneration.
  • Do not upgrade auth library majors implicitly when repairing scaffolds or auth seams.

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
  • if all JWKS resolution attempts fail, reject authentication (no silent fallback)
  • 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