--- title: "Local API — Access Control" aliases: [local-api-access-control, payload-overrideAccess] tags: [payloadcms, local-api, access-control, security, server-side] sources: [raw/local-api__access-control.md] created: 2026-05-15 updated: 2026-05-15 --- ## Overview Local API operations **skip access control by default**. This is by design — server-side scripts and admin tasks often run without a user context. You must explicitly opt in to access control enforcement when it matters. ## Default Behaviour: Access Control Skipped ```ts // Access control is NOT checked — runs as a privileged operation const doc = await payload.create({ collection: 'users', data: { email: 'test@test.com', password: 'test' }, }) ``` Useful for: - Seed scripts and migrations - Admin-only server jobs (cron tasks, background workers) - Internal service-to-service operations ## Enforcing Access Control Pass `overrideAccess: false` **and** the authenticated `user` object to make the operation respect collection-level access rules. ```ts const doc = await payload.create({ collection: 'users', overrideAccess: false, // enforce collection access control user, // authenticated user to check against data: { email: 'test@test.com', password: 'test' }, }) ``` - If `user` lacks permission → Payload throws a `Forbidden` error - Works on all CRUD operations: `create`, `find`, `findByID`, `update`, `delete` ## When to Use Each Mode | Scenario | `overrideAccess` | Pass `user`? | |----------|-----------------|--------------| | Server scripts, cron jobs, seeds | `true` (default) | No | | Server actions executing on behalf of a logged-in user | `false` | Yes — `req.user` | | Webhooks / third-party integrations with trusted tokens | `true` (default) | No | | Custom API endpoints that mirror REST behaviour | `false` | Yes | ## Key Takeaways - Local API **bypasses access control by default** — safe for trusted server code, dangerous if exposed to untrusted input. - To enforce permissions: set `overrideAccess: false` AND pass the `user` object. - Both conditions are required — `overrideAccess: false` without a `user` will treat the request as unauthenticated (all collection-access functions receive `undefined` as user). - In [[wiki/payloadcms/hooks-collections|Collection Hooks]] that run after user-triggered events, access control is already enforced by the REST/GraphQL layer; using the Local API inside hooks with `overrideAccess: true` lets you escalate privileges intentionally. - See [[wiki/payloadcms/access-control|Access Control Overview]] for collection/field-level access function signatures. ## Sources - `raw/local-api__access-control.md` - https://payloadcms.com/docs/local-api/access-control