---
description: Deprecated rules API.
---

import { Callout } from 'nextra-theme-docs';

# Access control

<Callout type="error">
  The rules API is deprecated and will be removed in a future release. Please
  use the new [permissions API](/schemas/permissions) instead.
</Callout>

Access control in Triplit occurs at the entity level. Although this is an improvement over membership/room based apis, access control does not extends to individual properties.

Typically a user's id is used to determine access. The user's id is accessible by providing a custom token to Triplit, as explained in the [Auth guide](/auth).

Access control checks run exclusively on the server, and are not enforced on the client. This means that a user can still read and write to a document they do not have access to, but the server will reject the request.

## Access control rules

Permissions for a collection are defined in the `rules` property of a schema. Both `read` and `write` rules are defined with a unique identifier, an optional `description`, and a `filter`. The `filter` is a [filter clause](/client/query/where) that is appended any query for that collection.

```typescript
import { Schema as S } from '@triplit/client';
const schema = {
  todos: {
    schema: S.Schema({
      id: S.Id(),
      author_id: S.String(),
      text: S.String(),
    }),
    rules: {
      read: {
        'author-is-user': {
          description: 'Users can only post todos they authored',
          filter: [['author_id', '=', '$session.SESSION_USER_ID']],
        },
      },
      write: {
        'author-is-user': {
          description: 'Users can only edit their own todos',
          filter: [['author_id', '=', '$session.SESSION_USER_ID']],
        },
      },
    },
  },
};
```

`$session.SESSION_USER_ID` is a special variable injected by Triplit. It is the user id of the user that is authenticated with the current session.
