Version: SG FLX
Enterprise

Document-level security basics

Document-level security (DLS) restricts a user’s access to certain documents within an index. To enable document-level security you configure an Elasticsearch query that defines which documents are accessible and which not. Only documents matching this query will be visible for the role that the DLS is defined for.

The query supports the full range of the Elasticsearch query DSL, and you can also use user attributes to make the query dynamic. This is a powerful feature to implement access permissions to documents based on user attributes stored in Active Directory / LDAP or a JSON web token.

Note: Search Guard FLX 1.0 comes with two implementations of DLS/FLS:

  • A legacy implementation, which is compatible with nodes which are running still older versions of Search Guard
  • A new implementation, which provides better efficiency and functionality. However, this implementation can only be used if you have completely updated your cluster to Search Guard FLX.

As the new implementation is not backwards-compatible, it needs to be manually activated in the configuration. To do so, create or edit sg_authz_dlsfls.yml and add:

use_impl: flx

Note: LogsDB mode, introduced by Elasticsearch in version 8.15, is not supported with the legacy DLS/FLS implementation.

This documentation describes the new implementation.

Example

Let’s imagine we have an index called humanresources. This index contains documents with type employees, and these documents have a field called department. We want to define a query that allows access to all employee documents, except those where the department is set to “Management”.

The respective query to filter these documents in regular query DSL would look like:

{
  "query": {
    "bool": {
      "must_not": { "match": { "department": "Management" }}
    }
  }
}

You can use this query to define the DLS in sg_roles.yml:

hr_employee:
  index_permissions:
    - index_patterns:
      - 'humanresources'
      allowed_actions:
        - ...
      dls: '{ "bool": { "must_not": { "match": { "department": "Management" }}}}'

If a user has the role hr_employee, Search Guard now filters all documents where the department field is set to “Management” from any search result before passing it back to the user.

The format of the query is the same as if it was used in a search request. The specified query expects the same format as if it was defined in the search request and supports ELasticsearch’s full Query DSL.

This means that you can make the DSL query as complex as you want, but since it has to be executed for each query, this, of course, comes with a small performance penalty.

Multiple roles and document-level security

A user can be member of more than one role, and each role can potentially define a different DLS query and different privileges for the same index. Search Guard uses well-defined semantics for these cases, which are described in this section. Keep these semantics in mind when defining your DLS roles.

If Search Guard encounters users which have more than one role with a DLS query for the same index, all DLS queries are collected and combined with the logical OR operator.

What this means is illustrated by the following example:

  • role_a grants only access to documents a1, a2 and a3
  • role_b grants only access to documents b1, b2 and b3

A user who is member both of role_a and role_b gets thus access to a1, a2, a3, b1, b2 and b3

Keep in mind that roles without explicit DLS query definitions implicitly grant access to all documents of an index. Thus, if a user is in such a role, they will always be able to access all documents, even though they might be also member of roles which only grant access to a subset of documents.

For illustration:

  • role_all does not have an explicit DLS query and thus grants access to all documents of an index
  • role_b grants only access to documents b1, b2 and b3

A user who is member both of role_all and role_b gets thus access to all documents. The DLS query of role_b does not have any effect.

Document Level Security for data streams and aliases

The alias and data stream features are only supported in SG FLX version 3.0 and above

DLS rules can be configured in sg_roles.yml. It is possible to configure roles both on the data stream level, the alias level and on the backing index level.

On the data stream level this would look like this:

dls_test_role:
  cluster_permissions:
  - "SGS_CLUSTER_COMPOSITE_OPS"
  data_stream_permissions:
  - data_stream_patterns:
    - "ds_a*"
    allowed_actions:
    - "SGS_READ"  
    dls: '{"term" : {"dls_attr" : "1"}}'

However, as DLS can be also configured on the index level, it is also possible to use this configuration, which will also apply to data streams:

dls_test_role:
  cluster_permissions:
  - "SGS_CLUSTER_COMPOSITE_OPS"
  index_permissions:
  - index_patterns:
    - "test_index*"
    allowed_actions:
    - "SGS_READ"  
    dls: '{"term" : {"dls_attr" : "1"}}'

It is also possible to define aliases which have data streams as members. You can also define DLS rules for these aliases which then affect all members:

dls_test_role_for_all_indices:
  cluster_permissions:
  - "SGS_CLUSTER_COMPOSITE_OPS"
  alias_permissions:
  - alias_patterns:
    - "datastream_alias"
    allowed_actions:
    - "SGS_READ"  
    dls: '{"term" : {"dls_attr" : "1"}}'

It is also possible to use DLS rules for data streams, aliases and indices at the same time. Search Guard will then compute the union of allowed documents from the rules (i.e., an OR conjunction will be used for these rules).

DLS and write-access

DLS only applies for operations that read from an index. It does not apply to index or update operations. Thus, you should take care that you do not grant any write privileges in roles which apply DLS restrictions.

Performance considerations

A DLS query can be as simple or complex as necessary, and you can use the full range of Elasticsearch’s query DSL. Regarding the performance overhead, think of the DLS query as an additional query executed on top of your original one.

Combining DLS and FLS

If you use both DLS and FLS, all fields that you are basing the DLS query on must be visible, i.e. not filtered by FLS. Otherwise, your DLS query will not work properly.



Not what you were looking for? Try the search.