Auth0 Authorization — Role-Based Access Control and Permissions
In this tutorial, you will learn about Auth0 Authorization. We cover key concepts, practical examples, and best practices to help you master this topic.
Auth0 Authorization provides role-based access control (RBAC) with roles and permissions that are embedded in access tokens, enabling your application to enforce granular permissions without additional database lookups.
What You'll Learn
By the end of this lesson you will create roles and permissions in Auth0, assign roles to users, read permissions from access tokens, enforce authorization in your application, and manage authorization using the Management API.
Why It Matters
Authorization is separate from authentication. Authentication verifies who the user is, while authorization determines what they can do. Auth0 RBAC lets you manage access policies centrally.
Real-World Use
DodaZIP defines two roles: user (upload and manage own files) and admin (manage all files, view analytics, manage users). Permissions like upload:files and delete:any_file are embedded in the JWT.
flowchart LR
A[Auth0] -->|Token with permissions| App[Application]
App -->|Check permission| C[Access Decision]
U[User: Admin Role] -->|Token| App
U2[User: Basic Role] -->|Token| App
C -->|Allow| D[Admin Feature]
C -->|Deny| E[Restricted Area]
style A fill:#eb5424,color:#fff
Creating Roles and Permissions
Define your authorization model in the Auth0 Dashboard.
# rbac_setup.py
# Setting up roles and permissions
def define_roles():
print("Role and Permission Definition:")
print()
print("Roles:")
print(" admin - Full system access")
print(" user - Self-service access")
print(" viewer - Read-only access")
print()
print("Permissions for 'user' role:")
print(" upload:files - Upload new files")
print(" read:own_files - View own files")
print(" update:own_files - Modify own files")
print(" delete:own_files - Delete own files")
print()
print("Additional permissions for 'admin' role:")
print(" read:any_file - View all files")
print(" delete:any_file - Delete any file")
print(" manage:users - Create/manage users")
print(" read:analytics - View analytics")
define_roles()
Assigning Roles to Users
Assign roles via Dashboard, API, or post-login Actions.
# assign_roles.py
# Assigning roles to users
def role_assignment_methods():
print("Role Assignment Methods:")
print()
print("1. Auth0 Dashboard:")
print(" User Management > Users > Select User > Roles")
print()
print("2. Management API:")
print(" POST /api/v2/users/{id}/roles")
print(' Body: {"roles": ["rol_abc123"]}')
print()
print("3. Post-Login Action:")
print(" Automatically assign roles based on email domain")
print(" or other user attributes after login")
print()
print("4. User Registration:")
print(" Assign default role during sign-up")
print(" Upgrade via approval workflow")
print()
print("Code example:")
print(" management_client.users.assign_roles(user_id, ['rol_abc123'])")
role_assignment_methods()
Reading Permissions from Tokens
Access permissions from the access token or ID token.
# token_permissions.py
# Reading permissions from tokens
import jwt
def decode_token_permissions(token):
# Decode without verification (for demonstration)
# In production, verify the token signature
decoded = jwt.decode(token, options={"verify_signature": False})
print("Token Claims:")
print(f" Subject: {decoded.get('sub')}")
print(f" Issuer: {decoded.get('iss')}")
print(f" Audience: {decoded.get('aud')}")
print()
# Permissions are in the 'permissions' claim
permissions = decoded.get("permissions", [])
print(f"Permissions ({len(permissions)}):")
for perm in permissions:
print(f" - {perm}")
return permissions
def check_permission(token, required_permission):
permissions = decode_token_permissions(token)
has_permission = required_permission in permissions
print(f"\nRequired: {required_permission}")
print(f"Granted: {has_permission}")
return has_permission
# Simulate checking permissions
sample_token = jwt.encode(
{"sub": "auth0|123", "permissions": ["upload:files", "read:own_files"], "iss": "https://tenant.auth0.com/"},
"secret", algorithm="HS256"
)
check_permission(sample_token, "upload:files")
Enforcing Authorization
Implement permission checks in your application.
# enforce_auth.py
# Enforcing authorization
from functools import wraps
def require_permission(permission):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
user_permissions = get_current_user_permissions()
if permission not in user_permissions:
raise PermissionError(f"Missing permission: {permission}")
return func(*args, **kwargs)
return wrapper
return decorator
def get_current_user_permissions():
# In a real app, extract from the validated JWT
return ["upload:files", "read:own_files", "delete:own_files"]
class FileService:
@require_permission("upload:files")
def upload_file(self, filename, content):
print(f"Uploading: {filename}")
return {"status": "uploaded", "filename": filename}
@require_permission("delete:any_file")
def delete_any_file(self, file_id):
print(f"Deleting file: {file_id}")
return {"status": "deleted"}
@require_permission("read:any_file")
def list_all_files(self):
print("Listing all files (admin)")
return ["file1", "file2"]
service = FileService()
service.upload_file("doc.pdf", b"...")
# service.delete_any_file("file_123") # Would raise PermissionError
Common Mistakes
Not including permissions in tokens: Permissions must be added to access tokens. Configure the token issuance to include the
permissionsclaim.Hardcoding roles in code: Roles and permissions should be data-driven, not hardcoded. Changes should not require deployments.
Using roles instead of permissions: Roles group permissions. Check permissions, not roles, in your authorization logic for flexibility.
Forgetting to validate permissions on the server: Client-side permission checks are cosmetic. Always enforce authorization on the backend.
Overly granular permissions: Too many permissions create complexity. Start with broad permissions and refine as needed.
Practice Questions
What is the difference between a role and a permission? A role is a named collection of permissions. Permissions are individual actions (e.g., upload:files).
How are permissions delivered to the application? Permissions are embedded in the access token as the
permissionsclaim.How do you assign a role to a user? Via the Auth0 Dashboard, Management API, or a post-login Action.
Where should you enforce permissions? On the server or backend, never only on the client side.
Challenge: Design an RBAC model for a document management application with roles for admin, editor, and viewer, each with appropriate permissions, and implement authorization checks.
FAQ
Mini Project
Create a complete RBAC system with admin, user, and viewer roles, appropriate permissions for each role, a post-login Action that assigns a default role, and permission checks in the API.
def rbac_project():
print("RBAC Implementation Plan:")
print()
roles_permissions = {
"admin": ["upload:files", "read:any_file", "delete:any_file", "manage:users", "read:analytics"],
"user": ["upload:files", "read:own_files", "update:own_files", "delete:own_files"],
"viewer": ["read:own_files"],
}
print("Role-Permission Mapping:")
for role, permissions in roles_permissions.items():
print(f" {role:10s} | {', '.join(permissions)}")
print()
print("Implementation steps:")
print(" 1. Create roles in Auth0 Dashboard")
print(" 2. Create permissions for each role")
print(" 3. Assign default role via post-login Action")
print(" 4. Extract permissions from JWT in API")
print(" 5. Implement @require_permission decorator")
rbac_project()
What's Next
Next: Rules and Actions for custom login logic.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro