The MarkLogic Server includes an extension to the security model called compartment security. Compartment security allows you to specify more complex security rules on documents.
An Advanced Security License is required when using compartment security. Licensing lists other security options requiring this license option. Contact your MarkLogic sales representative for details on purchasing the Advance Security License option.
This chapter describes compartment security and includes the following sections:
A compartment is a name associated with a role. You specify that a role is part of a compartment by adding the compartment name to each role in the compartment. When a role is compartmented, the compartment name is used as an additional check when determining a user's authority to access or create documents in a database. Compartments have no effect on execute privileges. Without compartment security, permissions are checked using OR semantics.
For example, if a document has read
permission for role1
and read
permission for role2
, a user who possesses either role1
or role2
can read that document. If those roles have different compartments associated with them (for example, compartment1
and compartment2
, respectively), then the permissions are checked using AND semantics for each compartment, as well as OR semantics for each non-compartmented role. To access the document if role1
and role2
are in different compartments, a user must possess both role1
and role2
to access the document, as well as a non-compartmented role that has a corresponding permission on the document.
If any permission on a document has a compartment, then the user must have that compartment in order to access any of the capabilities, even if the capability is not the one with the compartment.
Access to a document requires a permission in each compartment for which there is a permission on the document, regardless of the capability of the permission. So if there is a read
permission for a role in compartment1
, there must also be an update
permission for some role in compartment1
(but not necessarily the same role). If you try to add read
, insert
, node-update
, or execute
permissions that reference a compartmented role to a document for which there is no update
permission with the corresponding compartment, the XDMP-MUSTHAVEUPDATE
exception is thrown.
You can only add a compartment for a new role. To add a compartment, use the Admin Interface > Security > Roles > Create and enter a name for the compartment in the compartment field when you define each role in the compartment.
You cannot modify an existing role to use a compartment. To add a compartment to a role, you must delete the role and re-create it with a compartment. If you do re-create a role, any permissions you have on documents reference the old role (because they use the role ID, not the role name). So if you want those document permissions to use the new role, you need to update those documents with new permissions that reference the new role.
This section describes a scenario that uses compartment security. The scenario is not meant to demonstrate the correct way to set up compartment security, as your situation is likely to be unique. However, it demonstrates how compartment security works and may give you ideas for how to implement your own security model.
Description:For a MarkLogic application used by a government department, documents are classified with a security classification that dictates who may access the document. The department also restricts access to some documents based on the citizenship of the user. Additionally, some documents can only be accessed by employees with certain job functions.
To set up the compartment security for this scenario, you create the necessary roles, users, and documents with the example permissions. You will need access to both MarkLogic Admin Interface and Query Console.
To run through the example, perform the steps in each of the following sections:
Using the Admin Interface > Security > Roles > Create, create the roles and compartments as follows:
US
and Canada
and assign each of these roles the country
compartment name. These roles form the country
compartment.Executive
and Employee
and assign each of these roles the job-function
compartment name. These roles form the job-function
compartment.top-secret
and unclassified
and assign each of these roles the classification
compartment name. These roles form the classification
compartment.can-read
with no compartment.Using the Admin Interface > Security > Users > Create, create users and give them the roles indicated in the following table.
User | Roles |
---|---|
Don |
Executive, US, top-secret, can-read |
Ellen |
Employee, US, unclassified, can-read |
Frank |
Executive, Canada, top-secret, can-read |
Gary |
can-read |
Hannah |
unclassified, can-read |
Using the MarkLogic Query Console, add a document for each combination of permissions in the following table:
Document | Permissions [Role and Capability] | Users with Access |
---|---|---|
doc1.xml |
Don |
|
doc2.xml |
Don and Ellen |
|
doc3.xml |
All users | |
doc4.xml |
Frank, Don, Ellen |
|
doc5.xml |
Ellen, Hannah |
doc1.xml
, containing one <a>
element and a set of five permissions.xquery version "1.0-ml"; declare namespace html = "http://www.w3.org/1999/xhtml"; xdmp:document-insert( "/doc1.xml", <a>This is document 1.</a>, (xdmp:permission("can-read", "read"), xdmp:permission("can-read", "update"), xdmp:permission("US", "read"), xdmp:permission("US", "update"), xdmp:permission("Executive", "read"), xdmp:permission("Executive", "update"), xdmp:permission("top-secret", "read"), xdmp:permission("top-secret", "update")))
The doc1.xml
document can only be read by Don
because the permissions designate all three compartments and Don
is the only user with a role in all three of the necessary compartmented roles Executive
, US
, and top-secret
, plus the basic can-read
role.
doc2.xml
, doc3.xml
, doc4.xml
, and doc5.xml
and modify the permissions for each document as suggested in the table in Create the Documents and Add Permissions.Using Query Console, you can execute a series of queries to verify that the users can access each document as specified in the table in Create the Documents and Add Permissions.
For simplicity, this sample query uses xdmp:eval and xdmp:user to execute a query in the context of each different user. Modify the document URI and the user name to verify the permissions until you understand how the compartment security logic works. If you added the roles, users, and documents as described in this scenario, the query results should match the table in Create the Documents and Add Permissions.
xquery version "1.0-ml"; declare namespace html = "http://www.w3.org/1999/xhtml"; xdmp:eval('fn:doc("/doc1.xml")', (), <options xmlns="xdmp:eval"> <user-id>{xdmp:user("Don")}</user-id> </options>)