Configure granular access control for Directus users using roles, permissions, and access policies.
Permission System Overview
Directus uses a flexible RBAC (Role-Based Access Control) system with:
- Roles - Define sets of permissions
- Permissions - Control access to collections and fields
- Access Policies - Define what actions users can perform
- Field Permissions - Control read/write access per field
Creating Roles
Via Admin App
Navigate to Roles
- Go to Settings → Access Control → Roles
- Click Create Item (+)
Configure Role
- Name - Role identifier (e.g., "Editor")
- Description - Optional description
- Icon - Optional icon
- Admin Access - Enable for admin panel access
- App Access - Enable for Directus App access
Save Role
Via API
import { createRole } from '@directus/sdk';
const role = await directus.request(
createRole({
name: 'Content Editor',
description: 'Users who can edit content',
icon: 'edit',
admin_access: false,
app_access: true,
})
);
Predefined Permission Sets
Admin Role
// Full access to everything
{
name: 'Administrator',
admin_access: true,
app_access: true,
// No collection permissions needed - admin_access grants all
}
Content Editor Role
// Can edit content collections
{
name: 'Content Editor',
admin_access: false,
app_access: true,
permissions: [
{
collection: 'articles',
action: 'create',
permissions: {},
validation: {},
fields: ['*'],
},
{
collection: 'articles',
action: 'read',
permissions: {},
validation: {},
fields: ['*'],
},
{
collection: 'articles',
action: 'update',
permissions: {},
validation: {},
fields: ['*'],
},
],
}
Public Role
// Limited read-only access
{
name: 'Public',
admin_access: false,
app_access: false,
permissions: [
{
collection: 'articles',
action: 'read',
permissions: {
status: { _eq: 'published' },
},
fields: ['id', 'title', 'content', 'published_date'],
},
],
}
Collection Permissions
Setting Permissions
import { createPermission } from '@directus/sdk';
// Allow role to read articles
await directus.request(
createPermission({
role: 'role-uuid',
collection: 'articles',
action: 'read',
fields: ['*'],
permissions: {}, // No filter restrictions
})
);
// Allow role to create articles (own items only)
await directus.request(
createPermission({
role: 'role-uuid',
collection: 'articles',
action: 'create',
fields: ['*'],
permissions: {},
presets: {
user_created: '$CURRENT_USER',
},
})
);
// Allow role to update own articles only
await directus.request(
createPermission({
role: 'role-uuid',
collection: 'articles',
action: 'update',
fields: ['*'],
permissions: {
user_created: { _eq: '$CURRENT_USER' },
},
})
);
Permission Actions
- create - Create new items
- read - View items
- update - Edit existing items
- delete - Delete items
- share - Share items with others
Field-Level Permissions
Restrict Field Access
// Read access to specific fields only
await directus.request(
createPermission({
role: 'role-uuid',
collection: 'articles',
action: 'read',
fields: ['id', 'title', 'content'], // Only these fields
permissions: {},
})
);
// Cannot edit certain fields
await directus.request(
createPermission({
role: 'role-uuid',
collection: 'articles',
action: 'update',
fields: ['title', 'content'], // Can't edit status, published_date, etc.
permissions: {
user_created: { _eq: '$CURRENT_USER' },
},
})
);
Item Permissions (Filtering)
Filter by Status
// Can only read published articles
await directus.request(
createPermission({
role: 'role-uuid',
collection: 'articles',
action: 'read',
fields: ['*'],
permissions: {
status: { _eq: 'published' },
},
})
);
Filter by User
// Can only edit own items
await directus.request(
createPermission({
role: 'role-uuid',
collection: 'articles',
action: 'update',
fields: ['*'],
permissions: {
user_created: { _eq: '$CURRENT_USER' },
},
})
);
Complex Filters
// Can read published articles or own drafts
await directus.request(
createPermission({
role: 'role-uuid',
collection: 'articles',
action: 'read',
fields: ['*'],
permissions: {
_or: [
{ status: { _eq: 'published' } },
{
_and: [
{ status: { _eq: 'draft' } },
{ user_created: { _eq: '$CURRENT_USER' } },
],
},
],
},
})
);
Presets and Validation
Set Default Values
// Auto-set user_created on create
await directus.request(
createPermission({
role: 'role-uuid',
collection: 'articles',
action: 'create',
fields: ['*'],
presets: {
user_created: '$CURRENT_USER',
status: 'draft',
},
})
);
Validation Rules
// Validate before save
await directus.request(
createPermission({
role: 'role-uuid',
collection: 'articles',
action: 'create',
fields: ['*'],
validation: {
title: {
_nnull: true, // Title required
},
content: {
_nnull: true, // Content required
},
},
})
);
Special Variables
Directus provides special variables for dynamic permissions:
$CURRENT_USER- Current user's ID$CURRENT_ROLE- Current user's role ID$NOW- Current timestamp$NOW(-1 day)- Relative time
Best Practices
1. Principle of Least Privilege
Give users minimum permissions needed:
// Good - specific permissions
{
action: 'read',
fields: ['id', 'title', 'content'], // Only needed fields
permissions: { status: { _eq: 'published' } }, // Only published
}
// Bad - too permissive
{
action: 'read',
fields: ['*'], // Everything
permissions: {}, // No restrictions
}
2. Use Roles for Common Access Patterns
Create roles for common user types:
- Admin - Full access
- Editor - Create and edit content
- Author - Create own content only
- Viewer - Read-only access
3. Document Custom Permissions
// Add descriptions to roles
{
name: 'Content Moderator',
description: 'Can review and approve user-submitted content',
// permissions...
}
Troubleshooting
User Cannot Access Collection
Checks:
- Role has permission for the action
- Permission includes required fields
- Item matches permission filter
- User's role is active
Permission Changes Not Taking Effect
- Clear cache
- Re-login user
- Check permission order (more specific first)
Next Steps
- Adding/Removing Users - User management
- Directus Permissions - Official docs
- Access Control API - API reference