Privileges and Delegation to Restrict Administrative Access
Privileges enable you to grant administrative access to specific endpoints and objects, without needing to grant full administrative access to the server. For example, you might want to allow users with a help desk or support role to update the information of another user, without allowing them to delete user accounts or change the IDM system configuration.
You can use privileges to delegate specific administrative capabilities to non-administrative users, without exposing the Admin UI to those users. If a user has been granted a privilege that allows them to see a list of users and user information, for example, they can access this list directly through the End User UI.
Note
A delegated administrator does not have access to the same methods over REST as a regular administrator. IDM does not allow delegated administrator requests such as POST or DELETE. To add or remove relationships, use PATCH. For examples, see "Managed Roles".
The privilege mechanism requires dynamic role calculation, which is disabled by default. To enable it, set the enableDynamicRoles
property to true
in your conf/authentication.json
file, or select Configure > Authentication > Session > Enable Dynamic Roles in the Admin UI. For more information about dynamic role calculation, see "Dynamic Role Calculation".
For more information on managing privileges over REST, see "Privileges".
Determine Access Privileges
IDM determines what access a user has as follows:
IDM checks the
onRequest
script specified inrouter.json
. By default, this script callsrouter-authz.js
.If access requirements are not satisfied, IDM then checks for any privileges associated with the user's roles.
onResponse
and onFailure
scripts are supported when using privileges. onFailure
scripts are called only if both the onRequest
script and the privilege filter fail. onRequest
, onResponse
, and onFailure
scripts are not required for the privilege mechanism.
Create Privileges
Privileges are assigned to internal roles. A privilege specifies the following information:
The service path to which users with that internal role have access.
The methods and actions allowed on that service path.
The specific attributes of the objects at that service path, to which access is allowed.
You can use a query filter within a privilege so that the privilege applies to only a subset of managed objects.
The privileges
property is an array, and can contain multiple privileges. Each privilege can contain:
- accessFlags
A list of attributes within a managed object that you wish to give access to. Each attribute has two fields:
attribute
—the name of the property you are granting access to.readOnly
(boolean)—determines what level of access is allowed.
Attributes marked as
"readOnly": true
can be viewed but not edited. Attributes marked as"readOnly": false
can be both viewed and edited. Attributes that are not listed in theaccessFlags
array cannot be viewed or edited.Note
Privileges are not automatically aware of changes to the managed object schema. If new properties are added, removed, or made mandatory, you must update any existing privileges to account for these changes. When a new property is added, it has a default permission level of
NONE
in existing privileges, including when the privilege is set to access all attributes.IDM applies policy validation when creating or updating a privilege, to ensure that all required properties are writable when the
CREATE
permission is assigned. This validation does not run when schema changes are made, however, so you must verify that any existing privileges adhere to defined policies.
- actions
A list of the specific actions allowed if the
ACTION
permission has been specified. Allowed actions must be explicitly listed.- description (optional)
A description of the privilege.
- filter (optional)
This property lets you apply a static or dynamic query filter to the privilege, which can be used to limit the scope of what the privilege allows the user to access.
Static Filter ExampleTo allow a delegated administrator to access information only about users for the
stateProvince
Washington, include a static filter such as:filter : "stateProvince eq \"Washington\""
Dynamic Filter ExampleDynamic filters insert values from the authenticated resource. To allow a delegated administrator to access information only about users in their own
stateProvince
, include a dynamic filter by wrapping the parameter in curly braces:filter : "stateProvince eq \"{{stateProvince}}\""
Users with query filter privileges cannot edit the properties specified in the filter in ways that would cause the privilege to lose access to the object. For example, if a user with either of the preceding example privileges attempted to edit another user's
stateProvince
field to anything not matching the query filter, the request would return a403 Forbidden
error.Note
Fields must be searchable by IDM to be used in a privilege filter. Make sure that the field you are filtering on has
"searchable" : true
set inrepo.jdbc.json
. This is not necessary if you are using a DS or a PostgreSQL repository.Privilege filters are another layer of filter in addition to any other query filters you create. This means any output must satisfy all filters to be included.
- name
The name of the privilege being created.
- path
The path to the service you want to allow members of this privilege to access. For example,
managed/user
.- permissions
A list of permissions this privilege allows for the given path. The following permissions are available:
VIEW
—allows reading and querying the path, such as viewing and querying managed users.CREATE
—allows creation at the path, such as creating new managed users.UPDATE
—allows updating or patching existing information, such as editing managed user details.DELETE
—allows deletion, such as deleting users frommanaged/user
.ACTION
—allows users to perform actions at the given path, such as custom scripted actions.Note
Actions that require additional filtering on the results of the action are not currently supported.
The easiest way to modify privileges is using the Admin UI.
From the navigation bar, click Manage > Role.
From the Roles page, click the Internal tab, and then click an existing role (or create a new role).
From the Role Name page, click the Privileges tab.
IDM displays the current privileges for the role.
To add privileges, click Add Privileges.
In the Add a privilege window, enter information, as necessary, and click Add.
The following example creates a new support
role with privileges that let members view, create, and update information about users, but not delete users:
curl \ --header "X-OpenIDM-UserName: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --cacert ca-cert.pem \ --request PUT \ --data '{ "name": "support", "description": "Support Role", "privileges": [ { "name": "support", "description": "Support access to user information.", "path": "managed/user", "permissions": [ "VIEW", "UPDATE", "CREATE" ], "actions": [], "filter": null, "accessFlags": [ { "attribute" : "userName", "readOnly" : false }, { "attribute" : "mail", "readOnly" : false }, { "attribute" : "givenName", "readOnly" : false }, { "attribute" : "sn", "readOnly" : false }, { "attribute" : "accountStatus", "readOnly" : true } ] } ] }' \ "https://localhost:8443/openidm/internal/role/support"
{ "_id": "support", "_rev": "00000000bfbac2ed", "name": "support", "description": "Support Role", "temporalConstraints": [], "condition": null, "privileges": [ { "name": "support", "description": "Support access to user information.", "path": "managed/user", "permissions": [ "VIEW", "UPDATE", "CREATE" ], "actions": [], "filter": null, "accessFlags": [ { "attribute": "userName", "readOnly": false }, { "attribute": "mail", "readOnly": false }, { "attribute": "givenName", "readOnly": false }, { "attribute": "sn", "readOnly": false }, { "attribute": "accountStatus", "readOnly": true } ] } ] }
Policies Related to Privileges
When creating privileges, IDM runs policies found in policy.json
and policy.js
, including the five policies used for validating privileges:
valid-accessFlags-object
Verifies that
accessFlag
objects are correctly formatted. Only two fields are permitted in anaccessFlag
object:readOnly
, which must be a boolean; andattribute
, which must be a string.valid-array-items
Verifies that each item in an array contains the properties specified in
policy.json
, and that each of those properties satisfies any specific policies applied to it. By default, this is used to verify that each privilege containsname
,path
,accessFlags
,actions
, andpermissions
properties, and that thefilter
property is valid if included.valid-permissions
Verifies that the permissions set on the privilege are all valid and can be achieved with the
accessFlags
that have been set. It checks:CREATE
permissions must have write access to all properties required to create a new object.CREATE
andUPDATE
permissions must have write access to at least one property.ACTION
permissions must include a list of allowed actions, with at least one action included.If any attributes have write access, then the privilege must also have either
CREATE
orUPDATE
permission.All permissions listed must be valid types of permission:
VIEW
,CREATE
,UPDATE
,ACTION
, orDELETE
. Also, no permissions are repeated.
valid-privilege-path
Verifies that the
path
specified in the privilege is a valid object with a schema for IDM to reference. Only objects with a schema (such asmanaged/user
) can have privileges applied.valid-query-filter
Verifies that the query filter used to filter privileges is a valid query.
For more information about policies and creating custom policies, see Use Policies to Validate Data.
Use Privileges to Create a Delegated Administrator
You can use the IDM REST API to create an internal/role
with privileges that have object, array, and relationship type attribute access. You can then use that role as a delegated administrator to perform operations on those attributes.
Use the following example to create a delegated administrator:
Note
If you want to experiment with delegated administrators in Postman, download and import this Postman collection.
To ensure a role object exists when roles are requested, you must create a managed role.
curl \ --header "Content-Type: application/json" \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "If-None-Match: *" \ --request PUT \ --data '{ "name": "testManagedRole", "description": "a managed role for test" }' \ "http://localhost:8080/openidm/managed/role/testManagedRole"
{ "_id": "testManagedRole", "_rev": "00000000e0945865", "name": "testManagedRole", "description": "a managed role for test" }
curl \ --header "Content-Type: application/json" \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "If-None-Match: *" \ --request PUT \ --data '{ "userName": "psmith", "sn": "Smith", "givenName": "Patricia", "mail": "psmith@example.com", "telephoneNumber": "082082082", "password": "Passw0rd" }' \ "http://localhost:8080/openidm/managed/user/psmith"
{ "_id": "psmith", "_rev": "000000008fefe160", "userName": "psmith", "sn": "Smith", "givenName": "Patricia", "mail": "psmith@example.com", "telephoneNumber": "082082082", "accountStatus": "active", "effectiveRoles": [], "effectiveAssignments": [] }
In this step, you'll create two users with the following attributes:
preferences
manager
roles
curl \ --header "Content-Type: application/json" \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "If-None-Match: *" \ --request PUT \ --data '{ "userName": "scarter", "sn": "Carter", "givenName": "Steven", "mail": "scarter@example.com", "telephoneNumber": "082082082", "password": "Passw0rd", "preferences": { "updates": true, "marketing": false }, "manager": {"_ref" : "managed/user/psmith"}, "roles": [{"_ref" : "managed/role/testManagedRole"}] }' \ "http://localhost:8080/openidm/managed/user/scarter"
{ "_id": "scarter", "_rev": "00000000a8d501f8", "userName": "scarter", "sn": "Carter", "givenName": "Steven", "mail": "scarter@example.com", "telephoneNumber": "082082082", "preferences": { "updates": true, "marketing": false }, "accountStatus": "active", "effectiveRoles": [ { "_ref": "managed/role/testManagedRole" } ], "effectiveAssignments": [] }
curl \ --header "Content-Type: application/json" \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "If-None-Match: *" \ --request PUT \ --data '{ "userName": "jdoe", "sn": "Doe", "givenName": "John", "mail": "jdoe@example.com", "telephoneNumber": "082082082", "password": "Passw0rd", "preferences": { "updates": true, "marketing": false }, "manager": {"_ref" : "managed/user/psmith"}, "roles": [{"_ref" : "managed/role/testManagedRole"}] }' \ "http://localhost:8080/openidm/managed/user/jdoe"
{ "_id": "jdoe", "_rev": "00000000b174fbd4", "userName": "jdoe", "sn": "Doe", "givenName": "John", "mail": "jdoe@example.com", "telephoneNumber": "082082082", "preferences": { "updates": true, "marketing": false }, "accountStatus": "active", "effectiveRoles": [ { "_ref": "managed/role/testManagedRole" } ], "effectiveAssignments": [] }
You will delegate an internal/role with privileges to this user in the next step:
curl \ --header "Content-Type: application/json" \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "If-None-Match: *" \ --request PUT \ --data '{ "userName": "bjensen", "sn": "Jensen", "givenName": "Barbara", "mail": "bjensen@example.com", "telephoneNumber": "082082082", "password": "Passw0rd" }' \ "http://localhost:8080/openidm/managed/user/bjensen"
{ "_id": "bjensen", "_rev": "0000000022fae330", "userName": "bjensen", "sn": "Jensen", "givenName": "Barbara", "mail": "bjensen@example.com", "telephoneNumber": "082082082", "accountStatus": "active", "effectiveRoles": [], "effectiveAssignments": [] }
This role will have the following privileges:
A
managed/user
privilege with accessFlags attributes that are of types: "String", "boolean", and "number"; but also for:An object type that is not a relationship (
preferences
).An object type that is a relationship (
manager
).Array types that are relationships (
roles
,authzRoles
,reports
).
A
managed/role
privilege for viewing details of the "roles" property of a managed user.An
internal/role
privilege for viewing the details of the "authzRoles" property of a managed user.
Note
You can populate the privilege filter
field to apply a finer level of permissions for what a delegated administrator can see or do with certain objects. The filter
field is omitted in this example to allow all.
For properties that are not relationships, such as preferences
, you can't specify finer-grained permissions. For example, you can't set permissions on preferences/marketing
.
curl \ --header "Content-Type: application/json" \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "If-None-Match: *" \ --request PUT \ --data '{ "name": "internal_role_with_object_array_and_relationship_privileges", "description": "an internal role that has privileges for object & array types and relationships", "privileges": [ { "name": "managed_user_privilege", "path": "managed/user", "permissions": [ "VIEW", "CREATE", "UPDATE", "DELETE" ], "actions": [], "accessFlags": [ { "attribute": "userName", "readOnly": false }, { "attribute": "password", "readOnly": false }, { "attribute": "givenName", "readOnly": false }, { "attribute": "sn", "readOnly": false }, { "attribute": "mail", "readOnly": false }, { "attribute": "description", "readOnly": false }, { "attribute": "accountStatus", "readOnly": false }, { "attribute": "telephoneNumber", "readOnly": false }, { "attribute": "postalAddress", "readOnly": false }, { "attribute": "city", "readOnly": false }, { "attribute": "postalCode", "readOnly": false }, { "attribute": "country", "readOnly": false }, { "attribute": "stateProvince", "readOnly": false }, { "attribute": "preferences", "readOnly": false }, { "attribute": "roles", "readOnly": false }, { "attribute": "manager", "readOnly": false }, { "attribute": "authzRoles", "readOnly": false }, { "attribute": "reports", "readOnly": false } ] }, { "name": "managed_role_privilege", "path": "managed/role", "permissions": [ "VIEW" ], "actions": [], "accessFlags": [ { "attribute": "name", "readOnly": true }, { "attribute": "description", "readOnly": true } ] }, { "name": "internal_role_privilege", "path": "internal/role", "permissions": [ "VIEW" ], "actions": [], "accessFlags": [ { "attribute": "name", "readOnly": true }, { "attribute": "description", "readOnly": true }, { "attribute": "authzMembers", "readOnly": true } ] } ] }' \ "http://localhost:8080/openidm/internal/role/testInternalRole"
{ "_id": "testInternalRole", "_rev": "0000000079775d19", "name": "internal_role_with_object_array_and_relationship_privileges", "description": "an internal role that has privileges for object & array types and relationships", "temporalConstraints": null, "condition": null, "privileges": [ { "name": "managed_user_privilege", "path": "managed/user", "permissions": [ "VIEW", "CREATE", "UPDATE", "DELETE" ], "actions": [], "accessFlags": [ { "attribute": "userName", "readOnly": false }, { "attribute": "password", "readOnly": false }, { "attribute": "givenName", "readOnly": false }, { "attribute": "sn", "readOnly": false }, { "attribute": "mail", "readOnly": false }, { "attribute": "description", "readOnly": false }, { "attribute": "accountStatus", "readOnly": false }, { "attribute": "telephoneNumber", "readOnly": false }, { "attribute": "postalAddress", "readOnly": false }, { "attribute": "city", "readOnly": false }, { "attribute": "postalCode", "readOnly": false }, { "attribute": "country", "readOnly": false }, { "attribute": "stateProvince", "readOnly": false }, { "attribute": "preferences", "readOnly": false }, { "attribute": "roles", "readOnly": false }, { "attribute": "manager", "readOnly": false }, { "attribute": "authzRoles", "readOnly": false }, { "attribute": "reports", "readOnly": false } ] }, { "name": "managed_role_privilege", "path": "managed/role", "permissions": [ "VIEW" ], "actions": [], "accessFlags": [ { "attribute": "name", "readOnly": true }, { "attribute": "description", "readOnly": true } ] }, { "name": "internal_role_privilege", "path": "internal/role", "permissions": [ "VIEW" ], "actions": [], "accessFlags": [ { "attribute": "name", "readOnly": true }, { "attribute": "description", "readOnly": true }, { "attribute": "authzMembers", "readOnly": true } ] } ] }
In this step, assign the internal/role from step 5 to the user created in step 4 by creating a relationship:
curl \ --header "X-OpenIDM-Username: openidm-admin" \ --header "X-OpenIDM-Password: openidm-admin" \ --header "Content-Type: application/json" \ --request POST \ --data '{ "_ref": "managed/user/bjensen", "_refProperties": {} }' \ "http://localhost:8080/openidm/internal/role/testInternalRole/authzMembers?_action=create"
{ "_id": "732d3ab1-4319-41de-801b-80f4f4c97ef2", "_rev": "00000000e6dd99e0", "_ref": "managed/user/bjensen", "_refResourceCollection": "managed/user", "_refResourceId": "bjensen", "_refProperties": { "_id": "732d3ab1-4319-41de-801b-80f4f4c97ef2", "_rev": "00000000e6dd99e0" } }
You can now perform operations as a delegated administrator, such as:
The query results display all users' properties that are allowed by the privileges:
curl \ --header "X-OpenIDM-Username: bjensen" \ --header "X-OpenIDM-Password: Passw0rd" \ --request GET \ "http://localhost:8080/openidm/managed/user?_queryFilter=true&_pageSize=100&_fields=*,*_ref/*"
{ "result": [ { "_id": "psmith", "_rev": "000000008fefe160", "userName": "psmith", "sn": "Smith", "givenName": "Patricia", "mail": "psmith@example.com", "telephoneNumber": "082082082", "accountStatus": "active", "reports": [ { "_ref": "managed/user/scarter", "_refResourceCollection": "managed/user", "_refResourceId": "scarter", "_refProperties": { "_id": "c4e296ba-b0bb-44b8-a3e5-8d7c1656cef2", "_rev": "00000000e6f694a4" }, "userName": "scarter", "sn": "Carter", "givenName": "Steven", "mail": "scarter@example.com", "telephoneNumber": "082082082", "preferences": { "updates": true, "marketing": false }, "accountStatus": "active", "_rev": "00000000a8d501f8", "_id": "scarter" }, { "_ref": "managed/user/jdoe", "_refResourceCollection": "managed/user", "_refResourceId": "jdoe", "_refProperties": { "_id": "1e3dd17d-a540-4652-984a-60bd60e546d5", "_rev": "0000000066ee928d" }, "userName": "jdoe", "sn": "Doe", "givenName": "John", "mail": "jdoe@example.com", "telephoneNumber": "082082082", "preferences": { "updates": true, "marketing": false }, "accountStatus": "active", "_rev": "00000000b174fbd4", "_id": "jdoe" } ], "manager": null, "roles": [], "authzRoles": [], "_notifications": [], "_meta": { "_ref": "internal/usermeta/0c15f08b-cf2e-4408-b302-4f46a40bf943", "_refResourceCollection": "internal/usermeta", "_refResourceId": "0c15f08b-cf2e-4408-b302-4f46a40bf943", "_refProperties": { "_id": "da3e2429-ae6f-4ea6-b5db-d3112f7c9d6a", "_rev": "00000000fd019b55" }, "_rev": "000000003d8f5ca1", "_id": "0c15f08b-cf2e-4408-b302-4f46a40bf943" } }, { "_id": "scarter", "_rev": "00000000a8d501f8", "userName": "scarter", "sn": "Carter", "givenName": "Steven", "mail": "scarter@example.com", "telephoneNumber": "082082082", "preferences": { "updates": true, "marketing": false }, "accountStatus": "active", "reports": [], "manager": { "_ref": "managed/user/psmith", "_refResourceCollection": "managed/user", "_refResourceId": "psmith", "_refProperties": { "_id": "c4e296ba-b0bb-44b8-a3e5-8d7c1656cef2", "_rev": "00000000e6f694a4" }, "userName": "psmith", "sn": "Smith", "givenName": "Patricia", "mail": "psmith@example.com", "telephoneNumber": "082082082", "accountStatus": "active", "_rev": "000000008fefe160", "_id": "psmith" }, "roles": [ { "_ref": "managed/role/testManagedRole", "_refResourceCollection": "managed/role", "_refResourceId": "testManagedRole", "_refProperties": { "_id": "352d7864-3143-4c56-ae11-8f75c96e980a", "_rev": "00000000b9ef9689" }, "name": "testManagedRole", "description": "a managed role for test", "_rev": "00000000e0945865", "_id": "testManagedRole" } ], "authzRoles": [], "_notifications": [], "_meta": { "_ref": "internal/usermeta/6677aad2-def9-4507-9ea0-edd95da8da43", "_refResourceCollection": "internal/usermeta", "_refResourceId": "6677aad2-def9-4507-9ea0-edd95da8da43", "_refProperties": { "_id": "cc32ab82-084a-455c-bf97-3f2f2a71f848", "_rev": "00000000f4819bb6" }, "_rev": "0000000090ae5c88", "_id": "6677aad2-def9-4507-9ea0-edd95da8da43" } }, { "_id": "jdoe", "_rev": "00000000b174fbd4", "userName": "jdoe", "sn": "Doe", "givenName": "John", "mail": "jdoe@example.com", "telephoneNumber": "082082082", "preferences": { "updates": true, "marketing": false }, "accountStatus": "active", "reports": [], "manager": { "_ref": "managed/user/psmith", "_refResourceCollection": "managed/user", "_refResourceId": "psmith", "_refProperties": { "_id": "1e3dd17d-a540-4652-984a-60bd60e546d5", "_rev": "0000000066ee928d" }, "userName": "psmith", "sn": "Smith", "givenName": "Patricia", "mail": "psmith@example.com", "telephoneNumber": "082082082", "accountStatus": "active", "_rev": "000000008fefe160", "_id": "psmith" }, "roles": [ { "_ref": "managed/role/testManagedRole", "_refResourceCollection": "managed/role", "_refResourceId": "testManagedRole", "_refProperties": { "_id": "a3f6be90-3009-4e87-af46-257306617bd9", "_rev": "00000000b8f69498" }, "name": "testManagedRole", "description": "a managed role for test", "_rev": "00000000e0945865", "_id": "testManagedRole" } ], "authzRoles": [], "_notifications": [], "_meta": { "_ref": "internal/usermeta/5b844d7e-c200-4b67-9fad-fa346740c79d", "_refResourceCollection": "internal/usermeta", "_refResourceId": "5b844d7e-c200-4b67-9fad-fa346740c79d", "_refProperties": { "_id": "42aa7cf0-6726-461b-92f9-1a22dab0b3c3", "_rev": "000000003aa1993e" }, "_rev": "000000003e4f5bba", "_id": "5b844d7e-c200-4b67-9fad-fa346740c79d" } }, { "_id": "bjensen", "_rev": "0000000022fae330", "userName": "bjensen", "sn": "Jensen", "givenName": "Barbara", "mail": "bjensen@example.com", "telephoneNumber": "082082082", "accountStatus": "active", "reports": [], "manager": null, "roles": [], "authzRoles": [ { "_ref": "internal/role/testInternalRole", "_refResourceCollection": "internal/role", "_refResourceId": "testInternalRole", "_refProperties": { "_id": "732d3ab1-4319-41de-801b-80f4f4c97ef2", "_rev": "00000000e6dd99e0" }, "_id": "testInternalRole", "name": "internal_role_with_object_array_and_relationship_privileges", "description": "an internal role that has privileges for object & array types and relationships", "_rev": "0000000079775d19" } ], "_notifications": [], "_meta": { "_ref": "internal/usermeta/0fbeb220-5e95-42b4-9bdd-0464e23194d4", "_refResourceCollection": "internal/usermeta", "_refResourceId": "0fbeb220-5e95-42b4-9bdd-0464e23194d4", "_refProperties": { "_id": "cbdb3794-1629-424d-8d7a-9e9b0c93287f", "_rev": "000000002b5199f1" }, "_rev": "000000002fbc5b92", "_id": "0fbeb220-5e95-42b4-9bdd-0464e23194d4" } } ], "resultCount": 4, "pagedResultsCookie": null, "totalPagedResultsPolicy": "NONE", "totalPagedResults": -1, "remainingPagedResults": -1 }
curl \ --header "X-OpenIDM-Username: bjensen" \ --header "X-OpenIDM-Password: Passw0rd" \ --request GET \ "http://localhost:8080/openidm/managed/user/jdoe?_fields=preferences"
{ "_id": "jdoe", "_rev": "00000000b174fbd4", "preferences": { "updates": true, "marketing": false } }
curl \ --header "X-OpenIDM-Username: bjensen" \ --header "X-OpenIDM-Password: Passw0rd" \ --request GET \ "http://localhost:8080/openidm/managed/user/scarter/roles?_queryFilter=true&_fields=*"
{ "result": [ { "_id": "352d7864-3143-4c56-ae11-8f75c96e980a", "_rev": "00000000b9ef9689", "_refResourceCollection": "managed/role", "_refResourceId": "testManagedRole", "_refResourceRev": "00000000e0945865", "name": "testManagedRole", "description": "a managed role for test", "_ref": "managed/role/testManagedRole", "_refProperties": { "_id": "352d7864-3143-4c56-ae11-8f75c96e980a", "_rev": "00000000b9ef9689" } } ], "resultCount": 1, "pagedResultsCookie": null, "totalPagedResultsPolicy": "NONE", "totalPagedResults": -1, "remainingPagedResults": -1 }
curl \ --header "X-OpenIDM-Username: bjensen" \ --header "X-OpenIDM-Password: Passw0rd" \ --request GET \ "http://localhost:8080/openidm/managed/user/scarter/manager?_fields=*"
{ "_id": "c4e296ba-b0bb-44b8-a3e5-8d7c1656cef2", "_rev": "00000000e6f694a4", "_refResourceCollection": "managed/user", "_refResourceId": "psmith", "_refResourceRev": "000000008fefe160", "userName": "psmith", "sn": "Smith", "givenName": "Patricia", "mail": "psmith@example.com", "telephoneNumber": "082082082", "accountStatus": "active", "_ref": "managed/user/psmith", "_refProperties": { "_id": "c4e296ba-b0bb-44b8-a3e5-8d7c1656cef2", "_rev": "00000000e6f694a4" } }
curl \ --header "X-OpenIDM-Username: bjensen" \ --header "X-OpenIDM-Password: Passw0rd" \ --header "Content-Type: application/json" \ --request PATCH \ --data '[ { "operation" : "replace", "field" : "reports", "value" : [{"_ref" : "managed/user/scarter"}] } ]' \ "http://localhost:8080/openidm/managed/user/psmith"
{ "_id": "psmith", "_rev": "000000008fefe160", "userName": "psmith", "sn": "Smith", "givenName": "Patricia", "mail": "psmith@example.com", "telephoneNumber": "082082082", "accountStatus": "active" }
curl \ --header "X-OpenIDM-Username: bjensen" \ --header "X-OpenIDM-Password: Passw0rd" \ --header "Content-Type: application/json" \ --request PATCH \ --data '[ { "operation": "add", "field": "manager", "value": {"_ref" : "managed/user/psmith"} } ]' \ http://localhost:8080/openidm/managed/user/jdoe
{ "_id": "jdoe", "_rev": "00000000b174fbd4", "userName": "jdoe", "sn": "Doe", "givenName": "John", "mail": "jdoe@example.com", "telephoneNumber": "082082082", "preferences": { "updates": true, "marketing": false }, "accountStatus": "active" }
curl \ --header "X-OpenIDM-Username: bjensen" \ --header "X-OpenIDM-Password: Passw0rd" \ --header "Content-Type: application/json" \ --request PATCH \ --data '[ { "operation": "remove", "field": "manager" } ]' \ http://localhost:8080/openidm/managed/user/jdoe
{ "_id": "jdoe", "_rev": "00000000b174fbd4", "userName": "jdoe", "sn": "Doe", "givenName": "John", "mail": "jdoe@example.com", "telephoneNumber": "082082082", "preferences": { "updates": true, "marketing": false }, "accountStatus": "active" }
curl \ --header "X-OpenIDM-Username: bjensen" \ --header "X-OpenIDM-Password: Passw0rd" \ --header "Content-Type: application/json" \ --request PATCH \ --data '[ { "operation": "replace", "field": "manager", "value": {"_ref" : "managed/user/jdoe"} } ]' \ "http://localhost:8080/openidm/managed/user/scarter"
{ "_id": "scarter", "_rev": "00000000a8d501f8", "userName": "scarter", "sn": "Carter", "givenName": "Steven", "mail": "scarter@example.com", "telephoneNumber": "082082082", "preferences": { "updates": true, "marketing": false }, "accountStatus": "active" }
curl \ --header "X-OpenIDM-Username: bjensen" \ --header "X-OpenIDM-Password: Passw0rd" \ --header "Content-Type: application/json" \ --request DELETE \ "http://localhost:8080/openidm/managed/user/psmith"
{ "_id": "psmith", "_rev": "000000008fefe160", "userName": "psmith", "sn": "Smith", "givenName": "Patricia", "mail": "psmith@example.com", "telephoneNumber": "082082082", "accountStatus": "active" }
Using POST:
curl \ --header "Content-Type: application/json" \ --header "X-OpenIDM-Username: bjensen" \ --header "X-OpenIDM-Password: Passw0rd" \ --request POST \ --data '{ "userName": "psmith", "sn": "Smith", "givenName": "Patricia", "mail": "psmith@example.com", "telephoneNumber": "082082082", "password": "Passw0rd" }' \ "http://localhost:8080/openidm/managed/user"
{ "_id": "e5f6a856-9f3c-49fd-904c-c5f87004b682", "_rev": "000000004bbde938", "userName": "psmith", "sn": "Smith", "givenName": "Patricia", "mail": "psmith@example.com", "telephoneNumber": "082082082", "accountStatus": "active" }
Using PUT:
curl \ --header "Content-Type: application/json" \ --header "X-OpenIDM-Username: bjensen" \ --header "X-OpenIDM-Password: Passw0rd" \ --header "If-None-Match: *" \ --request PUT \ --data '{ "userName": "psmith", "sn": "Smith", "givenName": "Patricia", "mail": "psmith@example.com", "telephoneNumber": "082082082", "password": "Passw0rd" }' \ "http://localhost:8080/openidm/managed/user/psmith"
{ "_id": "psmith", "_rev": "00000000658fe17a", "userName": "psmith", "sn": "Smith", "givenName": "Patricia", "mail": "psmith@example.com", "telephoneNumber": "082082082", "accountStatus": "active" }
Note
For more examples, including working with filters, see the Postman collection.
Note
All patches are done with a PATCH request. Delegated administrator operations do not currently support using POST actions for patch requests (POST _action=patch
will not work).
Get Privileges on a Resource
To determine which privileges a user has on a service, you can query the privilege endpoint for a given resource path or object, based on the user you are currently logged in as. For example, if bjensen is a member of the support role mentioned in the previous example, checking their privileges for the managed/user
resource would look like this:
curl \ --header "X-OpenIDM-UserName: bjensen" \ --header "X-OpenIDM-Password: Passw0rd" \ --header "Accept-API-Version: resource=1.0" \ --cacert ca-cert.pem \ --request GET \ "https://localhost:8443/openidm/privilege/managed/user"
{ "VIEW": { "allowed": true, "properties": [ "userName", "givenName", "sn", "mail", "accountStatus" ] }, "CREATE": { "allowed": true, "properties": [ "userName", "givenName", "sn", "mail" ] }, "UPDATE": { "allowed": true, "properties": [ "userName", "givenName", "sn", "mail" ] }, "DELETE": { "allowed": false }, "ACTION": { "allowed": false, "actions": [] } }
In the above example, accountStatus
is listed as a property for VIEW
, but not for CREATE
or UPDATE
, because the privilege sets this property to be read only. Since both CREATE
and UPDATE
need the ability to write to a property, setting readOnly
to false applies to both permissions. If you need more granular control, split these permissions into two privileges.
In addition to checking privileges for a resource, it is also possible to check privileges for specific objects within a resource, such as managed/user/scarter
.