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 (
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
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 (
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:
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 withboth
update capabilities can call node update functions succesfully.
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.
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
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.
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
insert permissions for the
engineering role, and
update permissions for the
insertpermissions for the
readpermissions for the
... xdmp:document-insert("/widget.com/engineering/features/2004-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"))) ...
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.
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.
You can also use a hybrid of the two methods described above. Assume that
insert capabilities for the
engineering role are specified as default permissions forthe
engineering role as shown in the first screenshot. However,
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
update capabilities on the document, and the
... xdmp:document-insert("/widget.com/engineering/features/2004-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"))) ...
The xdmp:default-permissions function returns Ron's default permissions (from the role level in this example) of
insert capabilities for the
engineering role. The
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
read permission on the document. (He wisely withholds
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/2004-q1.xml", xdmp:permission("sales", "read")) ...
update capability is needed to add permissions to a document. 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.
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.