MarkLogic Server includes element level security (ELS), an addition to the security model that allows you to specify security rules on specific elements within documents. Using ELS, parts of a document may be concealed from users who do not have the appropriate roles to view them. ELS can conceal the XML element (along with properties and attributes) or JSON property so that it does not appear in any searches, query plans, or indexes - unless accessed by a user with appropriate permissions.
ELS protects XML elements or JSON properties in a document using a protected path, where the path to an element or property within the document is protected so that only roles belonging to a specific query roleset can view the contents of that element or property. You specify that an element is part of a protected path by adding the path to the Security database. You also then add the appropriate role to a query roleset, which is also added to the Security database.
ELS uses query rolesets to determine which elements will appear in query results. If a query roleset does not exist with the associated role that has permissions on the path, the role cannot view the contents of that path.
- A user with admin privileges can access documents with protected elements by using fn:doc to retrieve documents (instead of using a query). However, to see protected elements as part of query results, even a user with admin privileges will need to have the appropriate role(s).
- ELS applies to both XML elements and JSON properties; so unless spelled out explicitly, 'element' refers to both XML elements and JSON properties throughout this article.
You can read more about how to configure Element Level Security here, and can see how this all works at this Element Level Security Example.
One of the commonly used document level capabilities is 'update'. Be aware, however, that document level update is too powerful to be used with ELS permissions as someone with document level update privileges could update not only a node, but also delete the whole document. Consequently, a new document-level capability - 'node-update' - has been introduced. 'node-update' offers finer control when combined with ELS through xdmp:node-replace and xdmp:node-delete functions as they can be used to update/delete only the specified nodes of a document (and not the document itself in its entirety).
Document-level vs Element-level security
Unlike at the document-level:
- 'update' and 'node-update' capabilities are equivalent at the element-level. However, at the document-level, if a user only has a 'node-update' privilege to a document, you cannot delete the document. In contrast, 'update' privileges allows that user to delete the document
- 'Read', 'insert' and 'update' are checked separately at the element level i.e.:
- read operations - only permissions with 'read' capability are checked
- node update operations - only permissions with 'node-update' (update) capability are checked
- node insert operations - only permissions with 'insert' capability are checked
Note: read, insert, update and node-update can all be used at the element-level i.e., they can be part of the protected path definition.
- update: A node can be updated by any user that has an 'update' capability at the document-level
- node-update: A node can be updated by any user with a 'node-update' capability as long as they have sufficient privileges at the element-level
- If a node is protected but no 'update/node-update' capabilities are explicitly granted to any user, that node can be updated by any user as long as they have 'update/node-update' capabilities at the document-level
- If any user is explicitly granted 'update/node-update' capabilities to that node at the element level, only that specific user is allowed to update/delete that node. Other users who are expected to have that capability must be explicitly granted that permission at the element level
How does node-replace/node-delete work?
When a node-replace/node-delete is called on a specific node:
- The user trying to update that node must have at least a 'node-update' (or 'update') capability to all the nodes up until (and including) the root node
- None of the descendant nodes of the node being replaced/deleted can be protected by a different roles. If they are protected:
- 'node-delete' isn’t allowed as deleting this node would also delete the descendant node which is supposed to be protected
- 'node-replace' can be used to update the value (text node) of the node but replacing the node itself isn’t allowed
Note: If a caller has the 'update' capability at the document level, there is no need to do element-level permission checks since such a caller can delete or overwrite the whole document anyway.
- 'node-update' was introduced to offer finer control with ELS, in contrast to the document level 'update'
- 'update' and 'node-update' permissions behave the same at element-level, but differently at the document-level
- At document-level, 'update' is more powerful as it gives the user the permission to delete the entire document
- All permissions talk to each other at document-level. In contrast, permissions are checked independently at the element-level
- At the document level, an update permission allows you to read, insert to and update the document
- At the element level, however, read, insert and update (node-update) are checked separately
- For read operations, only permissions with the read capability are checked
- For node update operations, only permissions with the node-update capability are checked
- For node insert operations, only permissions with the insert capability are checked (this is true even when compartments are used).
- Can I use ELS without document level security (DLS)?
- ELS cannot be used without DLS
- Consider DLS the outer layer of defense, whereas ELS is the inner layer - you cannot get to the inner layer without passing through the outer layer
- When to use DLS vs ELS?
- ELS offers finer control on the nodes of a document and whether to use it or not depends on your use-case. We recommend not using ELS unless it is absolutely necessary as its usage comes with serious performance implications
- In contrast, DLS offers better performance and works better at scale - but is not an ideal choice when you need finer control as it doesn’t allow node-level operations
- How does ELS performance scale with respect to different operations?
- Ingestion - depends on the number of protected paths
- During ingestion, the server inspects every node for ELS to do a hash lookup against the names of the last steps from all protected paths
- For every protected path that matches the hash, the server does a full test of the node against the path - the higher the number of protected paths, the higher the performance penalty
- While the hash lookup is very fast, the full test it comparatively much slower - and the corresponding performance penalty increases when there are a large number of nodes that match the last steps of the protected paths
- Consequently, we strongly recommend avoiding the use of wildcards at the leaf-level in protected paths
- For example: /foo/bar/* has a huge performance penalty compared to /foo/*/bar
- Updates - as with ingestion, ELS performance depends on the number of protected paths
- Query/Search - in contrast to ELS ingestion or update, ELS query performance depends on the number of query rolesets
- Because ELS query performance depends on the number of query rolesets, the concept of Protected PathSet was introduced in 9.0-4
- A Protected PathSet allows OR relationships between permissions on multiple protected paths that cover the same element
- Because query performance depends on the number of relevant query rolesets, it is highly recommended to use helper functions to obtain the query rolesets of nodes configured with element-level security