Setting Up Roles and Permissions in Directus
Directus uses a role-based access model. Each user is assigned to a role, and the role receives a set of permissions on collections: read, create, update, delete. Permissions can be full or conditional (only own records, only specific fields).
Roles
In Settings → Roles & Permissions → create a role:
- Administrator — full access (built-in)
- Public — unauthenticated requests (built-in)
- Editor — content management
- Author — only own materials
- API Client — read-only for external frontend
Programmatic Role Management
// Via Directus SDK
import { createDirectus, rest, authentication, createRole, createPermission } from '@directus/sdk'
const directus = createDirectus(DIRECTUS_URL).with(rest()).with(authentication())
await directus.login(ADMIN_EMAIL, ADMIN_PASSWORD)
// Create role
const editorRole = await directus.request(createRole({
name: 'Editor',
admin_access: false,
app_access: true, // access to admin panel
}))
// Assign permissions
await directus.request(createPermission({
role: editorRole.id,
collection: 'articles',
action: 'read',
// null = all records
}))
await directus.request(createPermission({
role: editorRole.id,
collection: 'articles',
action: 'create',
}))
await directus.request(createPermission({
role: editorRole.id,
collection: 'articles',
action: 'update',
// Only own articles
permissions: { user_created: { _eq: '$CURRENT_USER' } },
fields: ['*'], // all fields
}))
Field-level Permissions
// Only specific fields are accessible for reading
await directus.request(createPermission({
role: authorRoleId,
collection: 'articles',
action: 'read',
fields: ['id', 'title', 'slug', 'content', 'status'],
// Hidden fields: internal_notes, revenue_impact
}))
Item-level Permissions with Filter
// Editor sees only published articles plus own drafts
await directus.request(createPermission({
role: editorRoleId,
collection: 'articles',
action: 'read',
permissions: {
_or: [
{ status: { _eq: 'published' } },
{ user_created: { _eq: '$CURRENT_USER' } },
],
},
}))
Public Role (for Public API)
// Public read of published articles
await directus.request(createPermission({
role: null, // null = Public role
collection: 'articles',
action: 'read',
permissions: { status: { _eq: 'published' } },
fields: ['id', 'title', 'slug', 'content', 'publishedAt', 'thumbnail'],
}))
Static Token for Server Requests
# Admin → Users → select user → Token field
# Create user with "API Client" role (read-only)
# Set static token
// Using static token
const response = await fetch(`${DIRECTUS_URL}/items/articles?filter[status][_eq]=published`, {
headers: { Authorization: `Bearer ${STATIC_TOKEN}` },
})
Timeline
Setting up a roles system for editorial team (3–5 roles) — 0.5–1 day.







