Authentication Guide
This guide covers JWT-based authentication, role-based access control, and integration with external auth providers. For complete technical details, see .context/api/authentication.md.Overview
The CMS uses JWT (JSON Web Token) authentication with RS256 signature verification:- Token Format: JWT (Bearer token)
- Algorithm: RS256 (RSA Signature with SHA-256)
- Provider: Keycloak, Auth0, or custom OAuth2
- Roles:
ROLE_CMS_EDITOR,ROLE_CMS_ADMIN
Quick Start
Development Mode
Generate a development token (DEV ONLY, disabled in production):Using the Token
Include the token in all authenticated requests:JWT Token Structure
Token Example
Header
Payload (Claims)
suboremail- User identifierexp- Expiration timestampiat- Issued at timestamp
roles- Array of role stringstenant_id- Tenant ID (optional, can be from user table)
Role-Based Access Control (RBAC)
Available Roles
ROLE_CMS_EDITOR
Permissions:- ✅ Read all content (articles, pages, media)
- ✅ Create content
- ✅ Update own content
- ✅ Schedule and publish content
- ✅ Generate preview tokens
- ❌ Delete content (admin only)
- ❌ Manage users, menus, blocks
ROLE_CMS_ADMIN
Permissions:- ✅ All ROLE_CMS_EDITOR permissions
- ✅ Delete content
- ✅ Archive/unarchive content
- ✅ Manage users (CRUD, reset passwords)
- ✅ Manage menus, blocks, settings
- ✅ Access all admin endpoints
Role Hierarchy
Endpoint Protection
Integration Examples
Keycloak Integration
1. Configure Keycloak:- Create realm:
cms - Create client:
cms-api(confidential) - Add roles:
cms_editor,cms_admin - Map roles to token claims
Auth0 Integration
1. Create Auth0 Application:- Type: Machine to Machine
- Authorized API: CMS API
- Permissions:
read:articles,write:articles, etc.
Frontend Integration
Nuxt 3 (Front-Office)
Vue 3 (Back-Office)
API Request Interceptor
Security Best Practices
Token Storage
✅ DO:- Store access token in memory (JavaScript variable)
- Store refresh token in httpOnly cookie (server-side)
- Use secure cookies in production (https only)
- Never store tokens in localStorage (XSS vulnerable)
- Never store tokens in sessionStorage
- Never log tokens to console in production
- Never include tokens in URLs
Token Expiration
Recommended Lifetimes:- Access token: 5-15 minutes (short-lived)
- Refresh token: 30 minutes - 1 hour
- Dev token: 1 hour (development only)
Automatic Refresh
Troubleshooting
”Invalid JWT Token”
Causes:- Token expired (
expclaim in past) - Invalid signature (wrong public key)
- Token format incorrect
- Check token expiration:
jwt.ioto decode - Verify JWKS URL is correct and accessible
- Clear JWKS cache:
php bin/console cache:clear
”User not found”
Causes:- User doesn’t exist in
cms_userstable - Email mismatch between token and database
- Create user with matching email
- Check
suboremailclaim in token matches DB
”Access Denied”
Causes:- Missing required role
- Tenant mismatch (user not in tenant)
- Check user roles in database
- Verify
X-Tenant-Idheader matches user’stenant_id - Check endpoint security requirements