Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/directus/directus/llms.txt

Use this file to discover all available pages before exploring further.

What are Permissions?

Permissions define access control rules that determine which users can perform specific actions on collections and items. The permission system in Directus operates through policies that are assigned to roles, with each permission rule specifying allowed actions, fields, and conditional filters.
Directus uses a policy-based permission system where permissions are grouped into policies, which are then assigned to roles. Users inherit permissions from their roles.

Permission Structure

A permission defines a single access rule:
// From ~/workspace/source/packages/types/src/permissions.ts:6-16
type Permission = {
  id?: number;
  policy: string | null;           // Policy this permission belongs to
  collection: string;               // Target collection
  action: PermissionsAction;        // Action type (create, read, update, delete, share)
  permissions: Filter | null;       // Filter rules for conditional access
  validation: Filter | null;        // Validation rules for data integrity
  presets: Record<string, any> | null;  // Auto-applied field values
  fields: string[] | null;          // Allowed fields (null = all)
}

Permission Actions

From @directus/constants, supported actions are:
  • create - Create new items
  • read - Read/view items
  • update - Modify existing items
  • delete - Remove items
  • share - Share items (app-specific)

Fields Access

The fields array controls field-level access:
{
  "fields": ["*"]  // All fields
}

{
  "fields": ["id", "title", "content", "status"]  // Specific fields only
}

{
  "fields": null  // No fields accessible (effectively no access)
}

How Permissions Work

Permission Evaluation

When a user attempts an action, Directus:
  1. Retrieves the user’s role(s)
  2. Fetches all policies assigned to those roles
  3. Collects permissions from all policies
  4. Evaluates permissions for the requested action and collection
  5. Applies filters and field restrictions
  6. Returns accessible data
From the source code (~/workspace/source/api/src/services/permissions.ts:88-97):
async getItemPermissions(collection: string, primaryKey?: string): Promise<ItemPermissions> {
  if (!this.accountability?.user) throw new ForbiddenError();
  
  if (this.accountability?.admin) {
    return {
      update: { access: true },
      delete: { access: true },
      share: { access: true },
    };
  }
  // ... permission evaluation logic
}

Admin Users

Users with admin: true in their accountability bypass all permission checks and have unrestricted access.

Conditional Permissions

The permissions field uses filter syntax to conditionally grant access:

Example: User’s Own Items Only

{
  "collection": "articles",
  "action": "read",
  "permissions": {
    "user_created": {
      "_eq": "$CURRENT_USER"
    }
  }
}

Example: Published Items Only

{
  "collection": "articles",
  "action": "read",
  "permissions": {
    "status": {
      "_eq": "published"
    }
  }
}

Example: Multiple Conditions

{
  "collection": "articles",
  "action": "update",
  "permissions": {
    "_and": [
      {
        "user_created": {
          "_eq": "$CURRENT_USER"
        }
      },
      {
        "status": {
          "_in": ["draft", "in_review"]
        }
      }
    ]
  }
}

Dynamic Variables

Permissions support dynamic variables:
  • $CURRENT_USER - Current user’s ID
  • $CURRENT_ROLE - Current user’s role ID
  • $NOW - Current timestamp
  • $CURRENT_POLICIES - Current user’s policy IDs

Validation Rules

The validation field enforces data integrity during create/update:
{
  "collection": "articles",
  "action": "create",
  "validation": {
    "status": {
      "_in": ["draft", "in_review"]
    }
  }
}
This ensures new articles can only be created with specific status values.

Presets

Presets automatically apply field values:
{
  "collection": "articles",
  "action": "create",
  "presets": {
    "author": "$CURRENT_USER",
    "status": "draft",
    "department": "$CURRENT_USER.department"
  }
}
Presets are applied automatically and cannot be overridden by the user.

Creating Permissions

POST /permissions
Content-Type: application/json

{
  "policy": "editor-policy",
  "collection": "articles",
  "action": "read",
  "fields": ["*"],
  "permissions": {
    "status": {
      "_in": ["published", "draft"]
    }
  }
}
From the source code (~/workspace/source/api/src/services/permissions.ts:40-46), creating a permission:
  1. Validates the permission structure
  2. Saves to directus_permissions collection
  3. Clears system cache to apply changes immediately

App Minimal Permissions

From the source code (~/workspace/source/api/src/services/permissions.ts:34-38), Directus automatically adds minimal permissions for the app to function:
override async readByQuery(query: Query, opts?: QueryOptions): Promise<Partial<Item>[]> {
  const result = (await super.readByQuery(query, opts)) as Permission[];
  
  return withAppMinimalPermissions(this.accountability, result, query.filter);
}
This ensures authenticated users can always access necessary system collections.

Policies and Roles

Permissions are organized through policies:
User → Role → Policies → Permissions
  1. User has a Role
  2. Role has multiple Policies (via directus_access)
  3. Policies contain Permissions
This three-tier system allows:
  • Reusable permission sets (policies)
  • Multiple policies per role
  • Flexible permission combinations

Example Structure

// Policy
{
  "id": "editor-policy",
  "name": "Editor Policy",
  "icon": "edit"
}

// Access (links role to policy)
{
  "id": 1,
  "role": "editor-role",
  "policy": "editor-policy"
}

// Permissions within policy
[
  {
    "policy": "editor-policy",
    "collection": "articles",
    "action": "read",
    "fields": ["*"]
  },
  {
    "policy": "editor-policy",
    "collection": "articles",
    "action": "create",
    "fields": ["*"],
    "presets": { "status": "draft" }
  }
]

Public Role

The public role grants access to unauthenticated requests:
{
  "policy": "public-policy",
  "collection": "articles",
  "action": "read",
  "permissions": {
    "status": {
      "_eq": "published"
    }
  },
  "fields": ["id", "title", "content", "published_date"]
}
This allows public read access to published articles without authentication.

System Permissions

System collections (directus_*) have special permission requirements. Modifying system permissions incorrectly can break platform functionality.
Key system collections:
  • directus_users - Requires special handling for password fields
  • directus_roles - Should only be accessible to admins
  • directus_permissions - Manages access control itself
  • directus_files - Controls asset access

Permission Patterns

Read-Only Access

{
  "collection": "articles",
  "action": "read",
  "fields": ["*"],
  "permissions": {}
}

Full CRUD for Own Items

[
  {
    "action": "create",
    "fields": ["*"],
    "presets": { "user_created": "$CURRENT_USER" }
  },
  {
    "action": "read",
    "permissions": { "user_created": { "_eq": "$CURRENT_USER" } }
  },
  {
    "action": "update",
    "permissions": { "user_created": { "_eq": "$CURRENT_USER" } }
  },
  {
    "action": "delete",
    "permissions": { "user_created": { "_eq": "$CURRENT_USER" } }
  }
]

Department-Based Access

{
  "action": "read",
  "permissions": {
    "department": {
      "_eq": "$CURRENT_USER.department"
    }
  }
}

Time-Based Access

{
  "action": "read",
  "permissions": {
    "publish_date": {
      "_lte": "$NOW"
    },
    "expire_date": {
      "_gte": "$NOW"
    }
  }
}

Common Use Cases

Content Workflow

Define permissions for draft, review, and published states with role-based approval processes.

Multi-Tenant Systems

Isolate data by organization or client using conditional permissions on tenant ID fields.

Public API

Expose read-only access to published content for public consumption without authentication.

Team Collaboration

Grant department or team-based access to shared resources while maintaining data isolation.

Best Practices

Principle of Least Privilege: Grant only the minimum permissions necessary for each role.
Use Policies Wisely: Create reusable policies for common permission sets to simplify management.
Test Permissions: Always test permissions as different roles to ensure correct access control.
Leverage Presets: Use presets to enforce data ownership and automatic field population.
Document Custom Filters: Complex permission filters should be documented for future maintenance.
Cache Clearing: After permission changes, clear the cache to ensure updates take effect immediately.
  • Users & Roles - Users and roles that permissions are assigned to
  • Collections - Target collections for permission rules
  • Items - Data subject to permission filtering