The MarkLogic Server security model has a set of tools you can use to control access to documents. These authorization tools control creating, inserting into, updating, and reading documents in a database. This chapter describes those tools and includes the following sections:
To create a document in a MarkLogic Server database, a user must possess the needed privileges to create a document with a given URI. The ability to create documents based on the URI is controlled with URI privileges and with two built-in execute privileges (any-uri
and unprotected-uri
). To possess a privilege, the user must be part of a role (either directly or indirectly, through role inheritance) to which the privilege is assigned. This section describes these different privileges.
URI privileges control the ability to create a new document with a given URI prefix. Using a URI privilege for a given URI protects that URI from new document creation; only users possessing the URI privilege can create a new document with the prefix.
For example, the screenshot below shows a URI privilege with /widget.com/sales/
as the protected URI. Any URI with /widget.com/sales/
as the prefix is protected. Users must be part of the sales
role to create documents with URIs beginning with this prefix. In this example, you need this URI privilege (or a privilege with at least as much authority) to create a document with the URI /widget.com/sales/my_process.xml
.
The following built-in execute privileges control the creation of URIs:
The any-uri
privilege provides the authority to create a document with any URI in the database, even if the URI is protected with a URI privilege. The unprotected-uri
privilege provides the authority to create a document at any URI in the database except for URIs that are protected with a URI privilege.
Permissions set on a document define access to capabilities (read
, insert
, update
, node-update
, and execute
) for that document. Each permission consists of a capability and a role. This section describes how to set permissions on a document. It includes the following subsections:
Document permissions pair a role with a capability to perform some action on a document. You can add multiple permissions to a document. If a user is part of a role (either directly or through inheriting the role) specified as part of a document permission, then the user has that capability for the given document. Each permission associates a role with one of the following capabilities:
The read
capability provides the authority to see the content in the document. Being able to see the content does not allow you to modify the document.
The update
capability provides the authority to modify content in the document or delete the document. However, update
does not provide the authority to read the document. Reading the document requires the read
capability. Users with update
capability, but not read
capability, can call the xdmp:document-delete and xdmp:document-insert functions successfully. However, node update functions, such as xdmp:node-replace, xdmp:node-delete, and xdmp:node-insert-after, cannot be called successfully. Node update functions require a node from the document as a parameter. If a user cannot read the document, he cannot access the node in the document and supply it as a parameter.
There is a way to get around the issue with node update functions. The update
capability provides the authority to change the permissions on a document. Therefore, you can use the xdmp:document-add-permissions function to add a new permission to the document with read
capability for a given role. A user with both read
and update
capabilities can call node update functions successfully.
The node-update
capability provides a subset of the update
capability, enabling permission to update nodes within a document. The node-update
capability offers finer control of updates when combined with element level security. The node-update
capability covers xdmp:node-replace and xdmp:node-delete and can also be used in built-ins on properties, including xdmp:document-add-properties, xdmp:document-set-property, xdmp:document-set-properties and xdmp:document-remove-properties. Note that if a role has the update
capability, it automatically includes the node-update
capability as well.
The insert
capability provides a subset of the update
capability. The insert
capability provides the authority to add new content to the document. The insert
capability by itself does not allow a user to change existing content or remove an existing document (for example, calls to xdmp:document-insert and xdmp:document-delete on an existing document fail). Furthermore, you need read
capability on the document to perform actions that use any of the node insert functions (xdmp:node-insert-before, xdmp:node-insert-after, xdmp:node-insert-child), as explained above in the description for update
. Therefore, a permission with an insert
capability must be paired with a permission with a read
capability to be useful.
The execute
capability provides the authority to execute application code contained in that document, if the document is stored in a database which is configured as a modules database. Users without permissions for the execute
capability on a stored module, are not able to execute that module.
When you create documents in a database, you must think about setting permissions on the document. If a document has no permission set on it, no one, other than users with the admin
role, can read, update, insert, or delete it. Additionally, non-admin users must add update permissions on documents when creating them; attempts to create a document without at least one update permission result in an XDMP-MUSTHAVEUPDATE
exception.
You set document permissions in the following ways:
For examples of setting permissions on documents, see Example--Using Permissions.
You can also secure membership in collections by assigning permissions to collections. To assign permissions to collections, you must use the Admin Interface or the security.xqy
Library Module functions. You cannot assign permissions to collections implicitly with default permissions.
For more information about permissions on collections, see Collections and Security in the Search Developer's Guide.
When a document is created, it is initialized with a set of permissions. If permissions are not explicitly set (by using xdmp:document-load or xdmp:document-insert, for example), then the permissions are set to the default permissions. The default permissions are determined based on the roles assigned (both explicitly and inherited from roles assigned to other roles) to the user who creates the document and on any default permissions assigned directly to the user.
If users are creating documents in a database, it is important to configure default permissions for the roles assigned to that user. Without default permissions, it is easy to create documents that no users (except those with the admin
role) can read, update, or delete.
It is important to consider document permissions when you load content into a database, whether you load data using the built-in functions (for example, xdmp:document-load or xdmp:document-insert), WebDAV (for example, dragging and dropping files into a WebDAV folder), the REST API, the Java API, or a custom program. In each case, setting permissions is necessary, whether explicitly or by taking advantage of default permissions. This example shows several ways of setting permissions on documents.
Suppose that Ron, of the engineering
role, is given the task to create a document to describe new features that will be added to the next version of the widget. Once the document is created, other users with the engineering
role contribute to the document and add the features they are working on. Ian, of the engineering-manager
role, decides that users of the engineering
role should only be allowed to read and add to the document. This enables Ian to control the process of removing or changing features in the document. To implement this security model, the document should be created with read
and insert
permissions for the engineering
role, and read
and update
permissions for the engineering-manager
role.
There are two ways to apply permissions to documents at creation time:
Assume that the following code snippet is executed as user Ron
of the engineering
role. The code inserts a document with the following permissions:
read
and insert
permissions for the engineering
roleupdate
, node-update
, and read
permissions for the engineering-manager
role... xdmp:document-insert("/widget.com/engineering/features/2017-q1.xml", <new-features> <feature> <name>blue whistle</name> <assigned-to>Ron</assigned-to> ... </feature> ... </new-features>, (xdmp:permission("engineering", "read"), xdmp:permission("engineering", "insert"), xdmp:permission("engineering-manager", "read"), xdmp:permission("engineering-manager", "update"), xdmp:permission("engineering-manager", "node-update")) ...
If you specify permissions to the function call explicitly, as shown above, those permissions override any default permission settings associated with the user (through user settings and role inheritance).
If there is a set of permission requirements that meets the needs of most application scenarios, MarkLogic recommends creating the appropriate default permission settings at the role or user level. This avoids having to explicitly create and set document permissions each time you call xdmp:document-load or xdmp:document-insert.
Default permission settings that apply to a user, either through a role or through the user definition, are important if you are loading documents using a WebDAV client. When you drag and drop files into a WebDAV folder, the permissions are automatically set based on the default permissions of the user logged into the WebDAV client. For more information about WebDAV servers, see WebDAV Servers in the Administrator's Guide.
The following screenshot shows a portion of the Admin Interface for the engineering
role. It shows read
and insert
capabilities being added to the engineering
role's default permissions.
A user's set of default permissions is additive; it is the aggregate of the default permissions for all of the user's role(s) as well as for the user himself. Below is another screenshot of a portion of a User configuration screen for Ron. It shows read and update capabilities being added to the engineering-manager
role as Ron's default permissions at the user level.
Ron has the engineering
role and does not have the engineering-manager
role. A user does not need to have a certain role in order to specify that role in its default permission set.
You can also use a hybrid of the two methods described above. Assume that read
and insert
capabilities for the engineering
role are specified as default permissions for the engineering
role as shown in the first screenshot. However, update
and read
capabilities are not specified for the engineering-manager
at the user or engineering
role level.
Further assume that the following code snippet is executed by Ron. It achieves the desired objective of giving the engineering-manager
role read
, update
, and node-update
capabilities on the document, and the engineering
role read
and insert
capabilities.
... xdmp:document-insert("/widget.com/engineering/features/2017-q1.xml", <new-features> <feature> <name>blue whistle</name> <assigned-to>Ron</assigned-to> ... </feature> ... </new-features>, (xdmp:default-permissions(), xdmp:permission("engineering-manager", "read") xdmp:permission("engineering-manager", "update")) xdmp:permission("engineering-manager", "node-update")) ...
The xdmp:default-permissions function returns Ron's default permissions (from the role level in this example) of read
and insert
capabilities for the engineering
role. The read
, update
, and node-update
capabilities for the engineering-manager
role are then added explicitly as function parameters.
The xdmp:document-insert function performs an update (rather than a create) function if a document with the specified document URI already exists. Consequently, if Ron calls the xdmp:document-insert function the second time with the same document URI, the call fails since Ron does not have update capability on the document.
Suppose that Ian, of the engineering-manager
role, decides to give users of the sales
role read
permission on the document. (He wisely withholds update
or insert
capability or there will surely be an explosion of features!) The code snippet below shows how to add permissions to a document after it has been created.
... xdmp:document-add-permissions( "/widget.com/engineering/features/2017-q1.xml", xdmp:permission("sales", "read")) ...
The update
capability is needed to add permissions to a document, and the node-update
capability is needed to update a portion of a document (or node). Therefore, the code snippet only succeed if it is executed by Ian, or another user of the engineering-manager
role. This prevents Ron from giving Emily, his buddy in sales, insert
capability on the document.
But what if the Emily is now the person in sales assigned to the project? Ian has the node-update
capability, so he can call xdmp:node-replace and xdmp:node-delete to modify nodes in a document. Ian changes the assigned-to element in the document using xdmp:node-update
.
... xdmp:node-update("/widget.com/engineering/features/2017-q1.xml", <new-features> <feature> <name>blue whistle</name> <assigned-to>Emily</assigned-to> ... </feature> ... </new-features>,
Changing default permissions for a role or a user does not affect the permissions associated with existing documents. To change permissions on existing documents, you need to use the permission update functions. See the documentation for the MarkLogic Built-In Functions in MarkLogic XQuery and XSLT Function Reference for more details.