# Collection Access Control

Source: https://payloadcms.com/docs/beta/access-control/collections

Collection Access Control is [Access Control](/docs/v4/access-control/overview.md) used to restrict access to Documents within a [Collection](/docs/v4/getting-started/concepts.md#collections), as well as what they can and cannot see within the [Admin Panel](/docs/v4/admin/overview.md) as it relates to that Collection.

To add Access Control to a Collection, use the `access` property in your [Collection Config](/docs/v4/configuration/collections.md):

```ts
import type { CollectionConfig } from 'payload'

export const CollectionWithAccessControl: CollectionConfig = {
  // ...
  access: {
    // highlight-line
    // ...
  },
}
```

## Config Options

Access Control is specific to the operation of the request.

To add Access Control to a Collection, use the `access` property in your [Collection Config](/docs/v4/configuration/collections.md):

```ts
import type { CollectionConfig } from 'payload';

export const CollectionWithAccessControl: CollectionConfig = {
  // ...
  // highlight-start
  access: {
    create: () => {...},
    read: () => {...},
    update: () => {...},
    delete: () => {...},
    validate: () => {...},

    // Auth-enabled Collections only
    admin: () => {...},
    unlock: () => {...},

    // Version-enabled Collections only
    readVersions: () => {...},
  },
  // highlight-end
}
```

The following options are available:

| Function       | Allows/Denies Access                                                                                              |
| -------------- | ----------------------------------------------------------------------------------------------------------------- |
| **`create`**   | Used in the `create` operation. [More details](#create).                                                          |
| **`read`**     | Used in the `find` and `findByID` operations. [More details](#read).                                              |
| **`update`**   | Used in the `update` operation. [More details](#update).                                                          |
| **`delete`**   | Used in the `delete` operation. [More details](#delete).                                                          |
| **`validate`** | Optionally overrides `update` access for [on-demand validation](/docs/v4/validation/overview.md#access-control-and-hooks). |

If a Collection supports [`Authentication`](/docs/v4/authentication/overview.md), the following additional options are available:

| Function     | Allows/Denies Access                                                                     |
| ------------ | ---------------------------------------------------------------------------------------- |
| **`admin`**  | Used to restrict access to the [Admin Panel](/docs/v4/admin/overview.md). [More details](#admin). |
| **`unlock`** | Used to restrict which users can access the `unlock` operation. [More details](#unlock). |

If a Collection supports [Versions](/docs/v4/versions/overview.md), the following additional options are available:

| Function           | Allows/Denies Access                                                                                                                                   |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **`readVersions`** | Used to control who can read versions, and who can't. Will automatically restrict the Admin UI version viewing access. [More details](#read-versions). |

### Create

Returns a boolean which allows/denies access to the `create` request.

To add create Access Control to a Collection, use the `create` property in the [Collection Config](/docs/v4/configuration/collections.md):

```ts
import type { CollectionConfig } from 'payload'

export const CollectionWithCreateAccess: CollectionConfig = {
  // ...
  access: {
    // highlight-start
    create: ({ req: { user }, data }) => {
      return Boolean(user)
    },
    // highlight-end
  },
}
```

The following arguments are provided to the `create` function:

| Option     | Description                                                                                                                   |
| ---------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **`req`**  | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object containing the currently authenticated `user`. |
| **`data`** | The data passed to create the document with.                                                                                  |
| **`slug`** | The slug of the Collection being accessed.                                                                                    |

### Read

Returns a boolean which allows/denies access to the `read` request.

To add read Access Control to a Collection, use the `read` property in the [Collection Config](/docs/v4/configuration/collections.md):

```ts
import type { CollectionConfig } from 'payload'

export const CollectionWithReadAccess: CollectionConfig = {
  // ...
  access: {
    // highlight-start
    read: ({ req: { user } }) => {
      return Boolean(user)
    },
    // highlight-end
  },
}
```

> **Tip:** Return a [Query](/docs/v4/queries/overview.md) to limit the Documents to only
> those that match the constraint. This can be helpful to restrict users' access
> to specific Documents. [More details](/docs/v4/queries/overview.md).

As your application becomes more complex, you may want to define your function in a separate file and import them into your Collection Config:

```ts
import type { Access } from 'payload'
import type { Page } from '@/payload-types'

export const canReadPage: Access<Page> = ({ req: { user } }) => {
  // Allow authenticated users
  if (user) {
    return true
  }

  // By returning a Query, guest users can read public Documents
  // Note: this assumes you have a `isPublic` checkbox field on your Collection
  return {
    isPublic: {
      equals: true,
    },
  }
}
```

The following arguments are provided to the `read` function:

| Option     | Description                                                                                                                   |
| ---------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **`req`**  | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object containing the currently authenticated `user`. |
| **`id`**   | `id` of document requested, if within `findByID`.                                                                             |
| **`slug`** | The slug of the Collection being accessed.                                                                                    |

### Update

Returns a boolean which allows/denies access to the `update` request.

To add update Access Control to a Collection, use the `update` property in the [Collection Config](/docs/v4/configuration/collections.md):

```ts
import type { CollectionConfig } from 'payload'

export const CollectionWithUpdateAccess: CollectionConfig = {
  // ...
  access: {
    // highlight-start
    update: ({ req: { user } }) => {
      return Boolean(user)
    },
    // highlight-end
  },
}
```

> **Tip:** Return a [Query](/docs/v4/queries/overview.md) to limit the Documents to only
> those that match the constraint. This can be helpful to restrict users' access
> to specific Documents. [More details](/docs/v4/queries/overview.md).

As your application becomes more complex, you may want to define your function in a separate file and import them into your Collection Config:

```ts
import type { Access } from 'payload'
import type { User } from '@/payload-types'

export const canUpdateUser: Access<User> = ({ req: { user }, id }) => {
  // Allow users with a role of 'admin'
  if (user.roles && user.roles.some((role) => role === 'admin')) {
    return true
  }

  // allow any other users to update only oneself
  return user.id === id
}
```

The following arguments are provided to the `update` function:

| Option     | Description                                                                                                                   |
| ---------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **`req`**  | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object containing the currently authenticated `user`. |
| **`id`**   | `id` of document requested to update.                                                                                         |
| **`data`** | The data passed to update the document with.                                                                                  |
| **`slug`** | The slug of the Collection being accessed.                                                                                    |

> **Tip:** For Collections with [Drafts](/docs/v4/versions/drafts.md) enabled, you can
> use `update` access to [control who can
> publish](/docs/v4/versions/drafts.md#controlling-who-can-publish) by returning a query
> constraint on the `_status` field.

### Delete

Similarly to the Update function, returns a boolean or a [query constraint](/docs/v4/queries/overview.md) to limit which documents can be deleted by which users.

To add delete Access Control to a Collection, use the `delete` property in the [Collection Config](/docs/v4/configuration/collections.md):

```ts
import type { CollectionConfig } from 'payload'

export const CollectionWithDeleteAccess: CollectionConfig = {
  // ...
  access: {
    // highlight-start
    delete: ({ req: { user } }) => {
      return Boolean(user)
    },
    // highlight-end
  },
}
```

As your application becomes more complex, you may want to define your function in a separate file and import them into your Collection Config:

```ts
import type { Access } from 'payload'
import type { Customer } from '@/payload-types'

export const canDeleteCustomer: Access<Customer> = async ({ req, id }) => {
  if (!id) {
    // allow the admin UI to show controls to delete since it is indeterminate without the `id`
    return true
  }

  // Query another Collection using the `id`
  const result = await req.payload.find({
    collection: 'contracts',
    overrideAccess: true,
    limit: 0,
    depth: 0,
    where: {
      customer: { equals: id },
    },
  })

  return result.totalDocs === 0
}
```

The following arguments are provided to the `delete` function:

| Option     | Description                                                                                                                                                                          |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **`req`**  | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object with additional `user` property, which is the currently logged in user.                               |
| **`id`**   | `id` of document requested to delete.                                                                                                                                                |
| **`data`** | The data being set on the document. For [Trash-enabled](/docs/v4/trash/overview.md) collections, check `data.deletedAt` to differentiate between soft delete and permanent delete operations. |
| **`slug`** | The slug of the Collection being accessed.                                                                                                                                           |

> **Tip:** For Collections with [Trash](/docs/v4/trash/overview.md) enabled, you can use
> the `data` argument to allow users to soft delete (trash) documents while
> restricting permanent deletion. See [Trash Access
> Control](/docs/v4/trash/overview.md#access-control) for examples.

### Admin

If the Collection is used to access the [Admin Panel](/docs/v4/admin/overview.md#the-admin-user-collection), the `Admin` Access Control function determines whether or not the currently logged in user can access the admin UI.

To add Admin Access Control to a Collection, use the `admin` property in the [Collection Config](/docs/v4/configuration/collections.md):

```ts
import type { CollectionConfig } from 'payload'

export const CollectionWithAdminAccess: CollectionConfig = {
  // ...
  access: {
    // highlight-start
    admin: ({ req: { user } }) => {
      return Boolean(user)
    },
    // highlight-end
  },
}
```

The following arguments are provided to the `admin` function:

| Option     | Description                                                                                                                   |
| ---------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **`req`**  | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object containing the currently authenticated `user`. |
| **`slug`** | The slug of the Collection being accessed.                                                                                    |

### Unlock

Determines which users can [unlock](/docs/v4/authentication/operations.md#unlock) other users who may be blocked from authenticating successfully due to [failing too many login attempts](/docs/v4/authentication/overview.md#config-options).

To add Unlock Access Control to a Collection, use the `unlock` property in the [Collection Config](/docs/v4/configuration/collections.md):

```ts
import type { CollectionConfig } from 'payload'

export const CollectionWithUnlockAccess: CollectionConfig = {
  // ...
  access: {
    // highlight-start
    unlock: ({ req: { user } }) => {
      return Boolean(user)
    },
    // highlight-end
  },
}
```

The following arguments are provided to the `unlock` function:

| Option     | Description                                                                                                                   |
| ---------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **`req`**  | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object containing the currently authenticated `user`. |
| **`slug`** | The slug of the Collection being accessed.                                                                                    |

### Read Versions

If the Collection has [Versions](/docs/v4/versions/overview.md) enabled, the `readVersions` Access Control function determines whether or not the currently logged in user can access the version history of a Document.

If `readVersions` is not configured, Payload uses the Collection's `read` Access Control. Boolean results are preserved, and query constraints are automatically adjusted to target fields within the stored version document.

For `findVersionByID`, the inherited `read` function receives the parent Document's `id`, not the version record's `id`.

To add Read Versions Access Control to a Collection, use the `readVersions` property in the [Collection Config](/docs/v4/configuration/collections.md):

```ts
import type { CollectionConfig } from 'payload'

export const CollectionWithVersionsAccess: CollectionConfig = {
  // ...
  access: {
    // highlight-start
    readVersions: ({ req: { user } }) => {
      return Boolean(user)
    },
    // highlight-end
  },
}
```

> **Note:** When you explicitly configure `readVersions`, returning a
> [Query](/docs/v4/queries/overview.md) will apply the constraint to the [`versions`
> collection](/docs/v4/versions/overview.md#database-impact), not the original
> Collection.

The following arguments are provided to the `readVersions` function:

| Option     | Description                                                                                                                   |
| ---------- | ----------------------------------------------------------------------------------------------------------------------------- |
| **`req`**  | The [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) object containing the currently authenticated `user`. |
| **`slug`** | The slug of the Collection being accessed.                                                                                    |
