MarkLogic Server uses a role-based security model. Each security entity is associated with a role. This chapter describes the role-based security model and includes the following sections:
As described in Role-Based Security Model (Authorization), roles are the central point of authorization in MarkLogic Server. This section describes how the other security entities relate to roles, and includes the following sections:
Execute privileges control access to XQuery or JavaScript code. URI privileges control access to creating documents in a given URI range. You associate roles with privileges by assigning the privileges to the roles.
Execute privileges allow developers to control authorization for the execution of an XQuery or JavaScript function. If an XQuery or JavaScript function is protected by an execute privilege, the function must include logic to check if the user executing the code has the necessary execute privilege. That privilege is assigned to a user through a role that includes the specific execute privilege. There are many execute privileges pre-defined in the security database to control execution of built-in XQuery and JavaScript functions.
For more details on execute privileges, see Protecting XQuery and JavaScript Functions With Privileges.
URI privileges control authorization for creation of a document with a given URI prefix. To create a document with a prefix that has a URI privilege associated with it, a user must be part of a role that has the needed URI privilege.
For more details on how URI privileges interact with document creation, see Protecting Documents.
Permissions are security characteristics of documents that associate a role with a capability. The capabilities are the following:
Users gain the authority to perform these capabilities on a document if they are assigned a role to which a permission is associated.
For more details on how permissions interact with documents, see Document Permissions.
Roles are one of the places where you can specify default permissions. If permissions are not explicitly specified when a document is created, the default permissions of the user creating the document are applied. The system determines the default permissions for a user based on the user's roles. The total set of default permissions is derived from the user's roles and all inherited roles.
For more details on how default permissions interact with document creation, see Default Permissions.
Users are authenticated against the security database configured for the database being accessed. Roles are the mechanism by which authorization information is derived. You assign roles to a user. The roles provide the user with a set of privileges and permissions that grant the authority to perform actions against code and documents. At any given time, a user possesses a set of privileges and default permissions that is the sum of the privileges and default permissions inherited from all of the roles currently assigned to that user.
Use the Admin Interface to display the set of privileges and default permissions for a given user; do not try and calculate it yourself as it can easily get fairly complex when a system has many roles. To display a user's security settings, use Admin Interface > Security > User > Describe. You need to select a specific user to see the Describe tab.
For more details on users, see Authenticating Users.
Privileges, document permissions, and users all interact with roles to define your security policies. The following diagram shows an example of how these entities interact.
Notice how all of the arrows point into the roles; that is because the roles are the center of all security administration in MarkLogic Server. In this diagram, User1
is part of Role2
, and Role2
inherits Role3
. Therefore, even though User1
has only been assigned Role2
, User1
possesses all of the privileges and permissions from both Role2
and Role3
. Following the arrows pointing into Role2
and Role3
, you can see that the user possesses Priv1
and Priv2
based on the privileges assigned to these roles and insert
and read
capabilities based on the permissions applied to Document1
.
Because User1
possesses Priv1
(based on role inheritance), User1
is able to execute code protected with a xdmp:security-assert("Priv1", "execute")
call; users who do not have the Priv1
privilege can not execute such code.
MarkLogic Server has a special role named admin
. The admin
role has full authority to do everything in MarkLogic Server, regardless of the permissions or privileges set. In general, the admin
role is only for administrative activities and should not be used to load data and run applications. Use extreme caution when assigning users the admin
role, because it gives them the authority to perform any activity in MarkLogic, included adding or deleting users, adding or deleting documents, changing passwords, and so on.
There is an admin-ui-user
role that does not have the full authority of the admin
role. Users with the admin-ui-user
role may view the Admin UI, but do not have access to data or the ability to make administrative changes. For more about the admin-ui-user
role, see The admin-ui-user role in the Administrator's Guide.
MarkLogic Server also has a built-in role named security
. Users who are part of the security
role have execute privileges to perform security-related tasks on the system using the functions in the security.xqy
Library Module. Use extreme caution when assigning users the security
role, because it gives the user the ability to utilize or assign the admin
role.
The security
role does not have access to the Admin Interface. To access the Admin Interface, a user must have the admin
role or the admin-ui-user
role. The security
role provides the privileges to execute functions in the security.xqy
module, which has functions to perform actions such as creating users, creating roles, and so on. For details on managing security objects programmatically, see Creating and Configuring Roles and Users and User Maintenance Operations in the Scripting Administrative Tasks Guide.
Consider a simple scenario with two roles: engineering
and sales
. The engineering
role is responsible for making widgets and has privileges needed to perform activities related to making widgets. The sales
role is responsible for selling widgets and has privileges to perform activities related to selling widgets.
To begin, create two roles in MarkLogic Server named engineering
and sales
respectively.
The engineering
role needs to be able to make widgets. You can create an execute privilege with the name make-widget
, and action URI http://widget.com/make-widget
to represent that privilege. The sales
role needs to sell widgets,so you create an execute privilege with the name sell-widget
and action URI http://widget.com/sell-widget
to represent that privilege.
Names for execute privileges are used only as display identifiers in the Admin Interface. The action URIs are used within XQuery or JavaScript code to identify the privilege.
Ron is an engineer in your company so you create a user for Ron and assign the engineering
role to the newly created user. Emily is an account representative so you create a user for Emily and assign her the sales
role.
In your XQuery code, use the xdmp:security-assert function to ensure that only engineers make widgets and only account representatives sell widgets (if you are using JavaScript, you can similarly call xdmp.securityAssert in your JavaScript function to protect the code). For example:
xquery version "1.0-ml" define function make-widget(...) as ... { xdmp:security-assert("http://widget.com/make-widget", "execute"), make widget...}
If Ron is logged into the application and executes the make-widget()
function, xdmp:security-assert("http://widget.com/make-widget", "execute")
succeeds since Ron is of the engineering role which has the execute privilege to make widgets.
If Emily attempts to execute the make-widget
function, the xdmp:security-assert function call throws an exception. You can catch the exception and handle it with a try/catch
in the code. If the exception is not caught, the transaction that called this function is rolled back.
Some functions are common to several protected actions. You can protect such a function with a single xdmp:security-assert
call by providing the appropriate action URIs in a list. For example, if a user needs to execute the count-widgets
function when making or selling widgets, you might protect the function as follows:
xquery version "1.0-ml" define function count-widgets(...) as ... { xdmp:security-assert( ("http://widget.com/make-widget", "http://widget.com/sell-widget"), "execute"), count-widget... }
If there is a function that requires more than one privilege before it can be performed, place the xdmp:security-assert
calls sequentially. For example, if you need to be a manager in the sales department to give discounts when selling the widgets, you can protect the function as follows:
xquery version "1.0-ml" define function discount-widget(...) as ... { xdmp:security-assert( "http://widget.com/sell-widget", "execute"), xdmp:security-assert( "http://widget.com/change-price", "execute"), discount widget... }
where http://widget.com/change-price
is an action URI for a change-price
execute privilege assigned to the manager
role. A user needs to have the sales
role and the manager
role, which provides the user with the sell-widget
and change-price
execute privileges, to be able to execute this function.