Loading TOC...
Security Guide (PDF)

Security Guide — Chapter 7

Protecting XQuery and JavaScript Functions With Privileges

Execute privileges provide authorization control for executing XQuery and JavaScript functions. MarkLogic provides three ways to protect XQuery functions:

  • Built-in execute privileges, created by MarkLogic, control access to protected functions such as xdmp:document-load.
  • Custom execute privileges, which you create using the Admin Interface or the security function in the security.xqy module, control access to functions you write.
  • Amps temporarily amplify a user's authority by granting the authority to execute a single, specific function. You can only amp a function in a library module that is stored in the MarkLogic modules database.

This chapter describes the following:

Built-In MarkLogic Execute Privileges

Every installation of MarkLogic Server includes a set of pre-defined execute privileges. You can view this list either in the Admin Interface or in Appendix B: Pre-defined Execute Privileges of the Administrator's Guide.

Protecting Your XQuery and JavaScript Code with Execute Privileges

To protect the execution of an individual XQuery or JavaScript function that you have written, you can use an execute privilege. When a function is protected with an execute privilege, a user must have that specific privilege to run the protected XQuery or JavaScript function.

Execute privileges operate at the function level. To protect an entire XQuery or JavaScript document that is stored in a modules database, you can use execute permissions. For details, see Document Permissions.

This section describes the following:

Using Execute Privileges

The basic steps for using execute privileges are:

  • Create the privilege.
  • Assign the privilege to a role.
  • Write code to test for the privilege.

You create privileges and assign them to roles using the Admin Interface. You use the xdmp:security-assert built-in function in your XQuery code to test for a privilege and you can use the xdmp.securityAssert built-in function in your JavaScript code to test for a privilege. This function tests to determine if the user running the code has the specified privilege. If the user possesses the privilege, then the code continues to execute. If the user does not possess the privilege, then the server throws an exception, which the application can catch and handle.

For example, to create an execute privilege to control the access to an XQuery function called display-salary, use the following steps:

  1. Use the Admin Interface to create an execute privilege named allow-display-salary.
  2. Assign any URI (for example, http://my/privs/allow-display-salary) to the execute privilege.
  3. Assign a role to the privilege. You may want to create a specific role for this privilege depending on your security requirements.
  4. Finally, in your display-salary XQuery function, include an xdmp:security-assert call to test for the allow-display-salary execute privilege as follows:
    xquery version "1.0-ml";
    declare function display-salary (
         $employee-id as xs:unsignedLong) 
    as xs:decimal
    {
    xdmp:security-assert("http://my/privs/allow-display-salary", "execute"), 
    ...
    } ;

Execute Privileges and App Servers

You can also control access to specific HTTP, WebDAV, ODBC, or XDBC servers using an execute privilege. Using the Admin Interface, you can specify that a privilege is required for server access. Any users that access the server must then possess the specified privilege. If a user tries to access an application on the server and does not possess the specified privilege, an exception is thrown. For an example of using this technique to control server access, see Example: Using the Security Database in Different Servers.

Creating and Updating Collections

To create or update a document and add it to a collection, the unprotected-collections privilege is required. You also need a role corresponding to an insert or update permission on the document. For a protected collection (a protected collection is created using the Admin Interface), you either need permissions to update that collection or the any-collection execute privilege. If the collection is an unprotected collection, then you need the unprotected-collections execute privilege. For details on adding collections while creating a document, see the documentation for xdmp:document-load, xdmp:document-insert, and xdmp:document-add-collections in the MarkLogic XQuery and XSLT Function Reference.

Temporarily Increasing Privileges with Amps

Amps provide users with additional authorization to execute a specific function. Assigning the user this authorization permanently could compromise the security of the system. When executing an amped function, the user is part of an amped role, which temporarily grants the user additional privileges and permissions of that role. Amps enable you to limit the effect of the additional roles (privileges and permissions) to a specific function.

For example, a user may need a count of all the documents in the database in order to create a report. If the user does not have read permissions on all the documents in the database, queries run by the user do not see all the documents in the database. If you want anyone to be able to know how many documents are in the database, regardless of whether they have permissions to see those documents, you can create a function named document-count() and use an amp on the function to elevate the user to a role with read permission for all documents. When the user executes the amped function, she temporarily has the necessary read permissions that enable the function to complete accurately. The administrator has in effect decided that, in the context of that document-count() function, it is safe to let anyone execute it.

Amps are security objects and you use the Admin Interface or Management API to create them. Amps are specific to a single function in a library module, which you specify by URI and local name when creating the amp. You can only amp a function that resides in a library module that is stored in a trusted directory on the filesystem, such as in the Modules directory (<install_dir>/Modules), or in the modules database configured for the server in which the function is executed. The recommended best practice is to put your library module code into the modules database. You cannot amp functions in XQuery modules or JavaScript modules stored in other locations. For example, you cannot amp a function in a module installed under the filesystem root of an HTTP server, and you cannot amp functions that reside in a main module. Functions must reside in the Modules database or in the Modules directory because these locations are trusted. Allowing amped functions from under a server root or from functions submitted by a client could compromise security. For details on creating amps, see the Security Administration chapter of the Administrator's Guide.

For an example that uses an amp, see Access Control Based on Client IP Address. For details on amps in JavaScript modules, see Amps and the module.amp Function in the JavaScript Reference Guide.

« Previous chapter
Next chapter »