Skip to content
KeystoneJS LogoKeystoneJS
👋🏻 Keystone 5 has officially moved to maintenance only. For the latest release of Keystone please visit the Keystone website.

Access control

Access control enforces who can do what with your GraphQL API.

Introduction

What a user can and cannot do in Keystone depends on two things: authentication and access control.

This guide focuses on the GraphQL API access control, which refers to the specific actions an authenticated or anonymous user can take.

Authentication, on the other hand, refers to a user identifying themselves in the Admin UI. You can learn about it in the Authentication guide.

GraphQL access control

Access control is about limiting CRUD (Create, Read, Update, Delete) actions that can be performed based on the current user (authenticated or anonymous).

In Keystone, both Lists and Fields take an access option, which lets you define rules of access control with fine precision - see Access control API docs for more details.

Example

Let's assume we want set the following access controls for a User list:

  1. Only admins can read deactivated user accounts.
  2. Only authenticated users can read/update their own email, not any other user's. Admins can read/update anyone's email.
  3. Only admins can see if a password is set. No-one can read their own or other user's passwords.
    • NOTE: It is never possible in Keystone to read a password via the Admin UI or the API)
  4. Only authenticated users can update their own password. Admins can update anyone's password.

Here's how we would set that up:

JS
const { Text, Select, Checkbox, Password } = require('@keystonejs/fields');

const keystone = new Keystone({...})

// Setup the authentication strategy
const authStrategy = keystone.createAuthStrategy({...})

keystone.createList('User', {
  access: {
    // 1. Only admins can read deactivated user accounts
    read: ({ authentication: { item } }) => {
      if (item.isAdmin) {
        return {}; // Don't filter any items for admins
      }
      // Approximately; users.filter(user => user.state !== 'deactivated');
      return {
        state_not: 'deactivated',
      };
    },
  },
  fields: {
    name: { type: Text },
    address: { type: Text },
    state: {
      type: Select,
      options: ['active', 'deactivated'],
      defaultValue: 'active',
    },
    isAdmin: { type: Checkbox, defaultValue: false },
    email: {
      type: Text,
      // 2. Only authenticated users can read/update their own email, not any other user's.
      // Admins can read/update anyone's email.
      access: ({ existingItem, authentication: { item } }) => {
        return item.isAdmin || existingItem.id === item.id;
      },
    },
    password: {
      type: Password,
      access: {
        // 3. Only admins can see if a password is set. No-one can read their own or other user's passwords.
        read: ({ authentication }) => authentication.item.isAdmin,
        // 4. Only authenticated users can update their own password. Admins can update anyone's password.
        update: ({ existingItem, authentication: { item } }) => {
          return item.isAdmin || existingItem.id === item.id;
        },
      },
    },
  },
});

Note: The code above depends on having a correct authentication setup

When logged in to the Admin UI as "Jess", will result in a list view like:

nameemailpasswordstate
Ticianaactive
Jessjess@thinkmill.com.auactive
Laurenactive

Note that Jess can only read his own email, and cannot read any passwords.


Read more in the access control API docs.

On this page

  • Introduction
  • GraphQL access control
  • Example
Edit on GitHub