Configuring Security

Kuzzle provides a full set of functionalities to configure fine-grained permissions to your data.


Initial Setup

When Kuzzle is first installed there is no administrator account and anonymous users (i.e. unauthenticated users) have administrative privileges.

To secure your Kuzzle installation you will need to create an administrator account by either using the Kuzzle Admin Console or using the CLI tool.

Once the administrator account is created, you can remove anonymous access rights and properly secure your installation. You can then use the Kuzzle Admin Console or Kuzzle API to create new users and assign them permissions.


Whitelist strategy

In Kuzzle, permissions follow the Whitelist strategy, which means that an action must be explicitly allowed by at least one role of the user profile.

This means that:

  • If a role allows it, the action is authorized, even if another role denies it.
  • If no role explicitly allows it, the action is denied, even if no role explicitly denies it.

User Permissions

User-level permissions control what API actions can be executed and, optionally, restrict those to targeted data indexes and collections.

Users, Profiles and Roles

Kuzzle's security layer links users to one or more profiles.
You can think of a profile as a group of users that share the same permissions.

The profiles themselves are made up of different groups of permissions, these groups are called roles.

A profile is linked to a set of roles, and each role defines a set of permissions. For example, in the diagram below, the editor profile is has all permissions, the contributor has a subset of the permissions, and the default profile has only default permissions:

Users, Profiles and Roles

All roles and profiles can be edited in the Kuzzle Admin Console.


Defining Roles

A role can be defined using a hierarchical JSON object where permissions are outlined by controller and action.

The role definition is represented as a JSON object where each key at the root of the object identifies a controller by name.

{
  "controllers": {
    "<controller name|*>": {
      "actions": {
        "<action name|*>": true, // accepted values: [true|false|object]
        "<action name|*>": false,
        // ...
      }
    }
  }
}

The controllers and actions properties can be set to a specific value or to the wildcard value "*".

When controller is declared within a Plugin, its name must be prefixed with the name of the Plugin, like < plugin-name/controller-name >.

The action permission value can be set to either:

  • a boolean. If true, the role allows the given action.
  • Deprecated since 1.4.0

    an object describing a dynamic right definition. For more information check out the advanced roles documentation.

As an example, below is the role definition that Kuzzle uses to request authorization from the anonymous user once the administrator account is created and anonymous access is blocked.

{
  "controllers": {
    "auth": {
      "actions": {
        "login": true,
        "checkToken": true,
        "getCurrentUser": true
      }
    }
  }
}

In the above role definition, anonymous users can perform the login, checkToken and getCurrentUser actions of the auth controller.

For a list of available controllers and actions from Kuzzle's API by sending a GET request as follows:

curl -X GET 'http://localhost:7512/?pretty'

Defining Profiles

A profile definition is a JSON object that contains an array of policies, each composed of a roleId and an array of restrictions:

{
  "policies": [
    {
      // Applied to all indexes and collections
      "roleId": "<role identifier>"
    },
    {
      // Restricted to a list of indexes or to a list of collections
      "roleId": "<another role identifier>",
      "restrictedTo": [
        {
          // All collections of this index are allowed
          "index": "<another index name>"
        },
        {
          // Only the specified list of collections are allowed
          "index": "<an authorized index name>",
          "collections": [
            "<authorized collection 1>",
            "<authorized collection 2>",
            "<...>"
          ]
        }
      ]  
    }
  ]
};

When applying a role to a profile, the role can be applied to all indexes and collections or it can be applied to a specific index or collection.

For example, if we have a "publisher" role which allows any action on the document controller:

{
  "controllers": {
    "document": {
      "actions": {
        "*": true
      }
    }
  }
}

Then we can declare three different profiles using this same role, each with varying levels of access based on the index and collection:

  • Applies the publisher role to all indexes and collections
{
  "policies": [
    {"roleId": "publisherRole"}
  ]
}
  • Applies the publisher role only to the index "index1" and all its collections
{
  "policies": [
    {
      "roleId": "publisherRole",
      "restrictedTo": [{"index": "index1"}]
    }
  ]
}
`
  • Applies the publisher role only to the collections "foo" and "bar" in the index "index1", and then to the index "index2" and all its collections
{
  "policies": [
    {
      "roleId": "publisherRole",
      "restrictedTo": [
        {"index": "index1", "collections": ["foo", "bar"]},
        {"index": "index2"}
      ]
    }
  ]
}

Writing complex permission rules

So far, we've seen how to set permissions to API routes, using user roles and profiles.

But this is rarely enough to secure an application, as it's commonplace to reject queries or data depending of business rules.
For instance, suppose you have a chat application and you want the users to only be able to edit & delete their own messages: this type of rules cannot be expressed as a simple boolean.

There are multiple ways of adding a business logic layer on top of the standard Kuzzle security one:

  • With a Pipe Plugin, you can listen to one or multiple API events, and decide whether you accept a query or document according to your business rules
  • If all you need is to make sure that submitted documents follow a strict set of formatting rules, you can add document validators
  • Deprecated since 1.4.0

    Using Permission Closures, you can add functions directly into role definitions