[[setting-up-field-and-document-level-security]] === Setting Up Field and Document Level Security 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. Field and document level permissions are specified separately, but a role can define both field and document level permissions. Field and document level security permissions can be configured on a per-index basis. ==== Field Level Security To enable field level security, you specify the fields that each role can access in the `roles.yml` file. You list the allowed fields with the `fields` option. Fields are associated with a particular index or index pattern and operate in conjunction with the privileges specified for the indices. [source,yaml] -------------------------------------------------- : indices: : privileges: fields: - - - -------------------------------------------------- To allow access to the `_all` meta field, you must explicitly list it as an allowed field. Access to the following meta fields is always allowed: _id, _type, _parent, _routing, _timestamp, _ttl, _size and _index. If you specify an empty list of fields, only these meta fields are accessible. NOTE: Omitting the fields entry entirely disables field-level security. For example, the following `customer_care` role grants read access to six fields in any index: [source,yaml] -------------------------------------------------- customer_care: indices: '*': privileges: read fields: - issue_id - description - customer_handle - customer_email - customer_address - customer_phone -------------------------------------------------- Also wildcard field expressions can be added to the `fields` options in the `roles.yml` file. For example the following example has the same effect as the previous example: [source,yaml] -------------------------------------------------- customer_care: indices: '*': privileges: read fields: - issue_id - description - 'customer_*' -------------------------------------------------- If documents are more complex and contain json objects then the fields with dot notion should be used. Assume the following document: [source,json] -------------------------------------------------- { "customer": { "handle": "Jim", "email": "jim@mycompany.com", "phone": "555-555-5555" } } -------------------------------------------------- If only access to the `handle` field is allowed then the following role should be setup: [source,yaml] -------------------------------------------------- my_role: indices: '*': privileges: read fields: - customer.handle -------------------------------------------------- If access to the entire `customer` object is allowed then the wildcard dot notation can be used to make this easier: [source,yaml] -------------------------------------------------- my_role: indices: '*': privileges: read fields: - customer.* -------------------------------------------------- ===== Limitations When field level security is enabled for an index: * The get, multi get, termsvector and multi termsvector APIs aren't executed in real time. The realtime option for these APIs is forcefully set to false. * The query cache and the request cache are disabled for search requests. * The update API is blocked. An update request needs to be executed via a role that doesn't have field level security enabled. [[document-level-security]] ==== Document Level Security Enabling document level security restricts which documents can be accessed from any document based API. To enable document level security, you use a query to specify the documents that each role can access in the `roles.yml` file. You specify the document query with the `query` option. The document query is associated with a particular index or index pattern and operates in conjunction with the privileges specified for the indices. [source,yaml] -------------------------------------------------- : indices: : privileges: query: -------------------------------------------------- NOTE: Omitting the `query` entry entirely disables document-level security. The `query` should follow the same format as if a query was defined in the request body of a search request, but here the format is YAML. Any query from the query-dsl can be defined in the `query` entry. For example, the following `customer_care` role grants read access to all indices, but restricts access to documents whose `department_id` equals `12`. [source,yaml] -------------------------------------------------- customer_care: indices: '*': privileges: read query: term: department_id: 12 -------------------------------------------------- Alternatively the query can also be defined in JSON as a string. This makes it easier to define queries that already have been defined in the JSON body of search request body elsewhere. [source,yaml] -------------------------------------------------- customer_care: indices: '*': privileges: read query: '{"term" : {"department_id" : "12"}}'' --------------------------------------------------