Security in Directus is combining:
- who the user is (auth),
- what they can do (permissions),
- which rows/items they can see (policies/filters).
This skill avoids “leaving everything open” for convenience and improves predictability between UI and CMS.
Authn (who you are)
- Use the login flow that your project adopted (email/password, SSO, existing tokens).
- Ensure the client works with user tokens and handles expiration/refresh correctly.
- Never use admin credentials in the front end.
RBAC (what they can do)
When configuring Roles:
- Separate by access level:
public,authenticated,editor,admin(adjust to your roles). - For each Collection, define permissions for:
- read (list/detail)
- create
- update
- delete
- Avoid “global create/update” for collections that represent critical data.
Policies (what is visible)
When the app requires access by ownership/tenant:
- Use policies to restrict reading and writing by
user/role/tenant_id/scope. - Ensure consistency: if the UI does not show it, the backend must also block it.
- For relations (deep reads), check whether the policies also cover related queries.
Best practices to avoid leakage
- Do not rely only on client-side filters.
- Apply authz on the Collection and, when necessary, on custom actions/endpoints (extensions).
- Create manual security tests:
- user A does not see B's items
- user A cannot update forbidden fields
- guest does not obtain details via
fields/deep
Integration with the app
- Map Directus error statuses to UX:
401/403→ prompt/login/redirect404→ resource does not exist or is unauthorized (do not leak existence)- validation → per-field messages
- Keep a “Data Access” layer in the app that does not assume permissions.
Anti-patterns
- Role
adminin the mobile app - Allowing
readglobally for collections with sensitive data - Fragile policies based on a field without an index or without scope validation
deepwithout checking what the user can actually read
Completion criteria
- Roles and permissions justified by product flows
- Policies implemented for ownership/tenant when required
- The app demonstrates consistent behavior for 401/403/404
- There are no leakage paths via endpoints/fields/deep