Security Guide (PDF)

Security Guide — Chapter 3

« Previous chapter
Next chapter »

Protecting Documents

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:

Creating Documents

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

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.

Built-In URI Execute Privileges

The following built-in execute privileges control the creation of URIs:

  • any-uri
  • unprotected-uri

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.

Document Permissions

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:

Capabilities Associated Through Permissions

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:

Read

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.

Update

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.

Node-Update

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.

Insert

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.

Execute

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.

Setting Document Permissions

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:

  • Explicitly set permissions on a document at load time (as a parameter to xdmp:document-load or xdmp:document-insert, for example).
  • Explicitly set and remove permissions on a document using the following functions:
    • xdmp:document-add-permissions
    • xdmp:document-set-permissions
    • xdmp:document-remove-permissions
  • Implicitly set permissions when the document is created based on the default permissions of the user who creates the documents. Permissions are applied to a document at document creation time based on the default permissions of the user who creates the document.

For examples of setting permissions on documents, see Example--Using Permissions.

Securing Collection Membership

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.

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.

Example--Using Permissions

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:

Setting Permissions Explicitly

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 role
  • update, 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).

Default Permission Settings

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.

« Previous chapter
Next chapter »
Powered by MarkLogic Server | Terms of Use | Privacy Policy