Setting up field and document level securityedit

You can control access to data within an index by adding field and document level security permissions to a role. Field level security permissions restrict access to particular fields within a document. Document level security permissions restrict access to particular documents within an index.

Note

Document and field level security is currently meant to operate with read-only privileged accounts. Users with document and field level security enabled for an index should not perform write operations.

A role can define both field and document level permissions on a per-index basis. A role that doesn’t specify field level permissions grants access to ALL fields. Similarly, a role that doesn’t specify document level permissions grants access to ALL documents in the index.

Important

When assigning users multiple roles, be careful that you don’t inadvertently grant wider access than intended. Each user has a single set of field level and document level permissions per index. See Multiple roles with document and field level security.

Multiple roles with document and field level securityedit

A user can have many roles and each role can define different permissions on the same index. It is important to understand the behavior of document and field level security in this scenario.

Document level security takes into account each role held by the user and combines each document level security query for a given index with an "OR". This means that only one of the role queries must match for a document to be returned. For example, if a role grants access to an index without document level security and another grants access with document level security, document level security is not applied; the user with both roles has access to all of the documents in the index.

Field level security takes into account each role the user has and combines all of the fields listed into a single set for each index. For example, if a role grants access to an index without field level security and another grants access with field level security, field level security is not be applied for that index; the user with both roles has access to all of the fields in the index.

For example, let’s say role_a grants access to only the address field of the documents in index1; it doesn’t specify any document restrictions. Conversely, role_b limits access to a subset of the documents in index1; it doesn’t specify any field restrictions. If you assign a user both roles, role_a gives the user access to all documents and role_b gives the user access to all fields.

If you need to restrict access to both documents and fields, consider splitting documents by index instead.

Templating a role queryedit

When you create a role, you can specify a query that defines the document level security permissions. You can optionally use Mustache templates in the role query to insert the username of the current authenticated user into the role. Like other places in Elasticsearch that support templating or scripting, you can specify inline, stored, or file-based templates and define custom parameters. You access the details for the current authenticated user through the _user parameter.

For example, the following role query uses a template to insert the username of the current authenticated user:

POST /_xpack/security/role/example1
{
  "indices" : [
    {
      "names" : [ "my_index" ],
      "privileges" : [ "read" ],
      "query" : {
        "template" : {
          "source" : {
            "term" : { "acl.username" : "{{_user.username}}" }
          }
        }
      }
    }
  ]
}

You can access the following information through the _user variable:

Property Description

_user.username

The username of the current authenticated user.

_user.full_name

If specified, the full name of the current authenticated user.

_user.email

If specified, the email of the current authenticated user.

_user.roles

If associated, a list of the role names of the current authenticated user.

_user.metadata

If specified, a hash holding custom metadata of the current authenticated user.

You can also access custom user metadata. For example, if you maintain a group_id in your user metadata, you can apply document level security based on the group.id field in your documents:

POST /_xpack/security/role/example2
{
  "indices" : [
    {
      "names" : [ "my_index" ],
      "privileges" : [ "read" ],
      "query" : {
        "template" : {
          "source" : {
            "term" : { "group.id" : "{{_user.metadata.group_id}}" }
          }
        }
      }
    }
  ]
}

Pre-processing documents to add security detailsedit

To guarantee that a user reads only their own documents, it makes sense to set up document level security. In this scenario, each document must have the username or role name associated with it, so that this information can be used by the role query for document level security. This is a situation where the set_security_user ingest processor can help.

Note

Document level security doesn’t apply to write APIs. You must use unique ids for each user that uses the same index, otherwise they might overwrite other users' documents. The ingest processor just adds properties for the current authenticated user to the documents that are being indexed.

The set_security_user processor attaches user-related details (such as username, roles, email, full_name and metadata ) from the current authenticated user to the current document by pre-processing the ingest. When you index data with an ingest pipeline, user details are automatically attached to the document. For example:

PUT shared-logs/log/1?pipeline=my_pipeline_id
{
  ...
}

For more information about setting up a pipeline and other processors, see ingest node.

Table 1. Set Security User Options

Name Required Default Description

field

yes

-

The field to store the user information into.

properties

no

[username, roles, email, full_name, metadata]

Controls what user related properties are added to the field.


The following example adds all user details for the current authenticated user to the user field for all documents that are processed by this pipeline:

{
  "processors" : [
    {
      "set_security_user": {
        "field": "user"
      }
    }
  ]
}