Object modeling
Advanced Identity Cloud provides a default schema for typical managed object types, such as users and roles. This section provides information on how to change and add to the managed object schema, establish relationships between objects, and use policies to validate objects. You will also learn how to access IDM objects using queries.
Managed objects
These topics describe how to work with managed object types:
The IDM object model includes other object types besides managed objects.
For more information, refer to Data models and objects reference.
Define managed object schema
Managed objects and their properties are defined in the default IDM managed object schema.
The default schema includes these types of managed objects:
The default schema also includes application type managed objects. However, you should not alter these in any way as they are reserved for modification by Ping Identity to support workforce use cases. You should not add custom attributes to them, repurpose their default attributes, or reconcile data into them. |
Each managed object type contains properties for storing information about objects of that type. For example, the user object type has properties for storing usernames, passwords, email addresses, and so forth.
You can extend the default IDM managed object schema to meet your needs:
-
Add new managed object types. For more information, refer to Create and modify object types.
-
Specify default values for object properties. For more information, refer to Default Values.
-
Derive object property values from other object property values, known as virtual properties. For more information, refer to Calculate properties based off other properties.
-
Define custom relationships between managed objects. For more information, refer to Manage custom relationship properties.
To store custom data for users, you can add custom attributes (non-searchable) or adapt one of the general purpose extension attributes (searchable). Refer to Customize user identities.
Ping Identity recommends that you do not delete the default managed objects in your tenant. In many cases it can break your tenant. The IDM admin UI depends on the presence of the default managed object types and the
default properties nested within them. If you remove any of these schema elements,
and you use the IDM admin UI to configure IDM, you must modify the IDM admin UI
code accordingly. For example, if you remove the |
To interact with a managed object schema via REST, refer to Schema.
Create and modify object types
If the managed object types provided in the default configuration are not sufficient for your deployment, you can create new ones. To do this through the Advanced Identity Cloud admin UI:
-
From the Advanced Identity Cloud admin UI, select Native Consoles > Identity Management.
-
Select Configure > Managed Objects > New Managed Object.
-
On the New Managed Object page, enter a name and readable title for the object, make optional changes, as necessary, and click Save. The readable title specifies what the object will be called in the UI.
-
On the Properties tab, specify the schema for the object type (the properties that make up the object).
-
On the Scripts tab, specify any scripts that will be applied on events associated with that object type. For example, scripts that will be run when an object of that type is created, updated, or deleted.
You can also create a new managed object type by editing your managed object schema. For more information, refer to Schema.
Example: Phone
object created using the IDM admin UI
{
"name": "Phone",
"schema": {
"$schema": "http://forgerock.org/json-schema#",
"type": "object",
"properties": {
"brand": {
"description": "The supplier of the mobile phone",
"title": "Brand",
"viewable": true,
"searchable": true,
"userEditable": false,
"policies": [],
"returnByDefault": false,
"pattern": "",
"isVirtual": false,
"type": [
"string",
"null"
]
},
"assetNumber": {
"description": "The asset tag number of the mobile device",
"title": "Asset Number",
"viewable": true,
"searchable": true,
"userEditable": false,
"policies": [],
"returnByDefault": false,
"pattern": "",
"isVirtual": false,
"type": "string"
},
"model": {
"description": "The model number of the mobile device, such as 6 plus, Galaxy S4",
"title": "Model",
"viewable": true,
"searchable": false,
"userEditable": false,
"policies": [],
"returnByDefault": false,
"pattern": "",
"isVirtual": false,
"type": "string"
}
},
"required": [],
"order": [
"brand",
"assetNumber",
"model"
]
}
}
Every managed object type has a name
and a schema
that describes the properties associated with that object. The name
can only include the characters a-z
, A-Z
, 0-9
, and _
(underscore). You can add any arbitrary properties to the schema.
Avoid using the dash character in property names (like Also, managed object properties that contain an underscore ( |
Typical property definition fields
title
-
The name of the property, in human-readable language, used to display the property in the UI.
description
-
A brief description of the property.
viewable
-
Specifies whether this property is viewable in the object’s profile in the UI. Boolean,
true
orfalse
(true
by default). searchable
-
Specifies whether this property can be searched in the UI. A searchable property is visible within the Managed Object data grid in the End User UI.
Boolean,
true
orfalse
(false
by default).Do not modify the searchable setting on properties in the default manged object schema in IDM, unless otherwise noted in documentation. userEditable
-
Specifies whether users can edit the property value in the UI. This property applies in the context of the End User UI, where users are able to edit certain properties of their own accounts. Boolean,
true
orfalse
(false
by default). pattern
-
Any specific pattern to which the value of the property must adhere. For example, a property whose value is a date might require a specific date format.
policies
-
Any policy validation that must be applied to the property.
required
-
Specifies whether the property must be supplied when an object of this type is created. Boolean,
true
orfalse
.To set an attribute as
required
:-
In the left menu, go to Native Consoles > Identity Management.
-
Click Configure > Managed Objects and select the managed object, in this case, click
Alpha_user
. A list of the properties in the managed object displays. The Required column displays which properties Advanced Identity Cloud currently requires. -
Click on the desired property.
-
In the Details tab, enable the Required field.
-
Click Save.
The required
policy is assessed only during object creation, not when an object is updated. You can effectively bypass the policy by updating the object and supplying an empty value for that property. To prevent this inconsistency, set bothrequired
andnotEmpty
totrue
for required properties. This configuration indicates that the property must exist, and must have a value.
-
type
-
The data type for the property value; can be
string
,array
,boolean
,integer
,number
,object
,Resource Collection
, ornull
.If any user might not have a value for a specific property (such as a
telephoneNumber
), you must includenull
as one of the property types. You can set a null property type in the IDM admin UI (Configure > Managed Objects > User, select the property, and under the Details tab, Advanced Options, setNullable
totrue
).You can also set a null property type in your managed object configuration by setting
"type" : '[ "string","null" ]'
for that property (wherestring
can be any other valid property type. This information is validated by the policy service.If you’re configuring a data
type
ofarray
through the IDM admin UI, you’re limited to two values. isVirtual
-
Specifies whether the property takes a static value, or whether its value is calculated "on the fly" as the result of a script. Boolean,
true
orfalse
. returnByDefault
-
For non-core attributes (virtual attributes and relationship fields), specifies whether the property is returned in the results of a query on an object of this type if it is not explicitly requested. Virtual attributes and relationship fields are not returned by default. Boolean,
true
orfalse
. When the property is in an array within a relationship, always set tofalse
.
default
-
Specifies a default value if the object is created without passing a value. Default values are available for the following data types, and arrays of those types:
-
boolean
-
number
-
object
-
string
IDM assumes all default values are valid for the schema. -
Default values
You can specify default values in the IDM managed object schema. If you omit a value when creating an object, the default value is automatically applied to the object. You can have default values for the following data types, and arrays of those types:
-
boolean
-
number
-
object
-
string
For example, the default IDM managed object schema includes a default value that makes accountStatus:active
, which effectively replaces the onCreate
script that was previously used to achieve the same result. The following excerpt from the IDM managed object schema displays the default value for accountStatus
:
"accountStatus" : {
"title" : "Status",
"description" : "Status",
"viewable" : true,
"type" : "string",
"searchable" : true,
"userEditable" : false,
"usageDescription" : "",
"isPersonal" : false,
"policies" : [
{
"policyId": "regexpMatches",
"params": {
"regexp": "^(active|inactive)$"
}
}
],
"default" : "active"
}
IDM assumes all default values are valid for the schema. |
Calculate properties based off other properties
Properties can be derived from other properties within an object. This lets computed and composite values be created in the object. These derived properties are called virtual properties, and their value can be calculated in two ways:
-
Using a script called by the
onRetrieve
script hook. This script calculates the current value of the virtual property based on the related properties.For example, you may want to dynamically update a property that you use for a country code (for phone number purposes). When a user’s record is retrieved, the country code is dynamically calculated based off of the
country
property of the user’s record. -
Using a query to identify the relationship fields to traverse to reach the managed objects whose state is included in the virtual property, and the fields in these managed objects to include in the value of the virtual property.
These properties are called relationship-derived virtual properties.
The default Advanced Identity Cloud schema defines several user properties as relationships. For information on how to define custom relationships, refer to Manage custom relationship properties.
Learn more about extending attributes of the user object in Customize user identities.
Derive virtual properties using onRetrieve
scripts
The onRetrieve
script hook lets you run a script when the object is retrieved. In the case of virtual properties, this script gets the data from related properties and uses it to calculate a value for the virtual property. Learn more in Extend functionality through scripts.
Only run |
Relationship-derived virtual properties
Virtual properties can be calculated by IDM based on relationships and relationship notifications. This means that, rather than calculating the current state when retrieved, the managed object that contains the virtual property is notified of changes in a related object, and the virtual property is recalculated when this notification is received. To configure virtual properties to use relationship notifications, there are two areas that need to be configured:
-
The related managed objects must be configured to use relationship notifications. This lets IDM know where to send notifications of changes in related objects.
-
To calculate the value of a virtual property, you must configure which relationships to check, and in which order, a notification of a change in a related object is received. You configure this using the
queryConfig
property.
The queryConfig
property tells IDM the sequence of relationship fields it should traverse in order to calculate (or recalculate) a virtual property, and which fields it should return from that related object. This is done using the following fields:
-
referencedRelationshipFields
is an array listing a sequence of relationship fields connecting the current object with the related objects you want to calculate the value of the virtual property from. The first field in the array is a relationship field belonging to the same managed object as the virtual property. The second field is a relationship in the managed object referenced by the first field, and so on.Example
For example, the
referencedRelationshipFields
foreffectiveAssignments
is["roles","assignments"]
. The first field refers to theroles
relationship field inmanaged/realm-name_user
, which references themanaged/realm-name_role
object. It then refers to theassignments
relationship inmanaged/realm-name_role
, which references themanaged/realm-name_assignment
object. Changes to either related object (managed/realm-name_role
ormanaged/realm-name_assignment
) will cause the virtual property value to be recalculated, due to thenotify
,notifySelf
, andnotifyRelationships
configurations on managed user, role, and assignment. These configurations ensure that any changes in the relationships between a user and their roles, or their roles, and their assignments, as well as any relevant changes to the roles or assignments themselves, such as the modification of temporal constraints on roles, or attributes on assignments, will be propagated to connected users, so theireffectiveRoles
andeffectiveAssignments
can be recalculated and potentially synced.-
referencedObjectFields
is an array of object fields that should be returned as part of the virtual property. If this property is not included, the returned properties will be a reference for the related object. To return the entire related object, use*
. -
flattenProperties
is a boolean that specifies whether relationship-derived virtual properties should be returned as plain fields rather than as JSON objects with an_id
and a_rev
. This property isfalse
by default.With
flattenProperties
set tofalse
, andreferencedObjectFields
set toname
, the response to a query on a user’seffectiveAssignments
might look something like this:"effectiveAssignments": [ { "name": "MyFirstAssignment", "_id": "02b166cc-d7ed-46b7-813f-5ed103145e76", "_rev": "2" }, { "name": "MySecondAssignment", "_id": "7162ddd4-591a-413e-a30b-3a5864bee5ec", "_rev": "0" } ]
jsonWith
flattenProperties
set totrue
, andreferencedObjectFields
set toname
, the response to the same query looks like this:"effectiveAssignments": [ "MyFirstAssignment", "MySecondAssignment" ]
jsonSetting
flattenProperties
totrue
also lets singleton relationship-derived virtual properties be initialized tonull
.
-
Using queryConfig
, the virtual property is recalculated when it receives a notice that changes occurred in the related objects. This can be significantly more efficient than recalculating whenever an object is retrieved, while still ensuring the state of the virtual property is correct.
When you change which fields to return using |
Extend functionality through scripts
Before implementing a script, it’s highly recommended that you validate the script over REST. Use scripts in a test environment before deploying them to a production environment. |
A number of script hooks let you manipulate managed objects using scripts. Scripts can be triggered during various stages of the lifecycle of the managed object, and are defined in the managed object schema.
You can trigger scripts when a managed object is:
-
Created (onCreate)
-
Deleted (onDelete)
-
Read (onRead)
-
Retrieved (onRetrieve)
-
Stored in the repository (onStore)
-
Synchronized (onSync)
-
Updated (onUpdate)
-
Validated (onValidate)
Post-action scripts let you manipulate objects after they are:
-
Created (postCreate)
-
Updated (postUpdate)
-
Deleted (postDelete)
For in-depth explanations of the various scripts, refer to managed object configuration properties.
Enable self-service by tracking user metadata
Some self-service features, such as progressive profile completion, privacy and consent, and acceptance of terms and conditions, rely on user metadata that tracks information related to a managed object state.
For example, this data might include when the object was created or the date of the most recent change. This metadata is not stored within the object itself but in a separate resource location.
In Advanced Identity Cloud, metadata is only tracked for managed/alpha_user
and managed/bravo_user
managed objects.
If you are not using the self-service features that require metadata, you can remove the |
The metadata configuration includes the following properties:
property
-
The property dynamically added to the managed object schema for this object.
resourceCollection
-
The resource location where the metadata is stored.
Metadata is stored under
ou=usermeta,ou=internal,dc=openidm,dc=forgerock,dc=com
by default.You must include the
ou
specified in the precedingdnTemplate
attribute. trackedProperties
-
The properties tracked as metadata for this object. In the following example, the
createDate
(when the object was created) and thelastChanged
date (when the object was last modified) are tracked.
You cannot search on metadata, and it is not returned by the results of a query, unless it is specifically requested. To return all metadata for an object, include _fields=,_meta/*
in your request. The following example returns a user entry without requesting the metadata:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user/bjensen" { "_id": "bjensen", "_rev": "000000000444dd1a", "mail": "bjensen@example.com", "givenName": "Barbara", "sn": "Jensen", "description": "Created By CSV", "userName": "bjensen", "telephoneNumber": "1234567", "accountStatus": "active", "effectiveRoles": [], "effectiveAssignments": [] }
The following example returns the same user entry, with metadata:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user/bjensen?_fields=,_meta/*" { "_id": "bjensen", "_rev": "000000000444dd1a", "mail": "bjensen@example.com", "givenName": "Barbara", "sn": "Jensen", "description": "Created By CSV", "userName": "bjensen", "telephoneNumber": "1234567", "accountStatus": "active", "effectiveRoles": [], "effectiveAssignments": [] "_meta": { "_ref": "internal/usermeta/284273ff-5e50-4fa4-9d30-4a3cf4a5f642", "_refResourceCollection": "internal/usermeta", "_refResourceId": "284273ff-5e50-4fa4-9d30-4a3cf4a5f642", "_refProperties": { "_id": "30076e2e-8db5-4b4d-ab91-5351d2da4620", "_rev": "000000001ad09f00" }, "createDate": "2018-04-12T19:53:19.004Z", "lastChanged": { "date": "2018-04-12T19:53:19.004Z" }, "loginCount": 0, "_rev": "0000000094605ed9", "_id": "284273ff-5e50-4fa4-9d30-4a3cf4a5f642" } }
Apart from the |
The request also returns a _meta
property that includes relationship information. IDM uses the relationship model to store the metadata. When the meta
stanza is added to the user object definition, the attribute specified by the property
("property" : "_meta",
in this case) is added to the schema as a uni-directional relationship to the resource collection specified by resourceCollection
.
In this example, the user object’s _meta
field is stored as an internal/usermeta
object. The _meta/_ref
property shows the full resource path to the internal object where the metadata for this user is stored.
Manage identities
In Advanced Identity Cloud user identities are sometimes referred to as managed users or user managed objects. There are alpha users and bravo users.
To retrieve, add, change, and delete managed users, use one of the following methods:
-
In the Advanced Identity Cloud admin UI, any of the options in Identities > Manage > realm-name_user.
-
The REST interface at the context path
/openidm/managed/realm-name_user
.
Managed users examples
The following examples show how to retrieve, add, change, and delete users over the REST interface. For more information on all the managed user endpoints and actions, refer to the Managed users endpoint.
Retrieve IDs of all managed users in a realm
The size of the returned set can be large when there are many users in your tenant. |
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_queryFilter=true&_fields=_id" { "result": [ { "_id": "1dff18dc-ac57-4388-8127-dff309f80002", "_rev": "ceea2483-7f92-411e-9194-dcca0d61198e-48377" }, { "_id": "7750881d-1622-451e-9ee5-71f7aaafcadf", "_rev": "ecf2cd07-f187-482e-9fa0-1127c267bce2-65781" }, ... ], ... }
Query managed users for a specific user
You can return a subset of users based on a query. If the conditions are met, then the users are returned.
The _queryFilter
requires double quotes, or the URL-encoded equivalent (%22
), around the search term. This example uses the URL-encoded equivalent:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_queryFilter=userName+eq+%22scarter%22" { "result": [ { "_id": "7750881d-1622-451e-9ee5-71f7aaafcadf", "_rev": "ecf2cd07-f187-482e-9fa0-1127c267bce2-65781", "userName": "scarter", "givenName": "Sam", "sn": "Carter", "telephoneNumber": "12345678", "active": "true", "mail": "scarter@example.com", "accountStatus": "active", "effectiveAssignments": [], "effectiveRoles": [] } ], ... }
This example uses single quotes around the URL to avoid conflicts with the double quotes around the search term:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ 'https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_queryFilter=userName+eq+"scarter"' { "result": [ { "_id": "7750881d-1622-451e-9ee5-71f7aaafcadf", "_rev": "ecf2cd07-f187-482e-9fa0-1127c267bce2-65781", "userName": "scarter", "givenName": "Sam", "sn": "Carter", "telephoneNumber": "12345678", "active": "true", "mail": "scarter@example.com", "accountStatus": "active", "effectiveAssignments": [], "effectiveRoles": [] } ], ... }
Retrieve a managed user by their ID
In the following example, 7750881d-1622-451e-9ee5-71f7aaafcadf
is the UUID of the user.
If you do not know the UUID of the user, you can retrieve the user by performing a search query, as described in Query managed users for a specific user. |
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user/7750881d-1622-451e-9ee5-71f7aaafcadf" { "_id": "7750881d-1622-451e-9ee5-71f7aaafcadf", "_rev": "ecf2cd07-f187-482e-9fa0-1127c267bce2-65781", "userName": "scarter", "givenName": "Sam", "sn": "Carter", "telephoneNumber": "12345678", "active": "true", "mail": "scarter@example.com", "accountStatus": "active", "effectiveAssignments": [], "effectiveRoles": [] }
Add a user with a specific user ID
To add a user, you must provide the minimum required attributes.
To locate the minimum required attributes:
-
From the Advanced Identity Cloud admin UI, click Native Consoles > Identity Management.
-
Click Configure > Managed Objects > managed/realm-name_user.
-
In the Required column, note the properties that have required marked.
-
To create a user, these are the minimum attributes you must present.
-
If you create an object using PUT, the ID you assign must be a UUID, for example, 4cf65bb9-baa4-4488-aa73-216adf0787a1 .
|
curl \ --header "Content-Type: application/json" \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "If-None-Match: *" \ --request PUT \ --data '{ "userName": "bjackson", "sn": "Jackson", "givenName": "Barbara", "mail": "bjackson@example.com", "telephoneNumber": "082082082", "password": "Passw0rd" }' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user/4cf65bb9-baa4-4488-aa73-216adf0787a1" { "_id": "4cf65bb9-baa4-4488-aa73-216adf0787a1", "_rev": "ceea2483-7f92-411e-9194-dcca0d61198e-51099", "userName": "bjackson", "sn": "Jackson", "givenName": "Barbara", "mail": "bjackson@example.com", "telephoneNumber": "082082082", "accountStatus": "active", "effectiveAssignments": [], "effectiveRoles": [] }
Add a user with a system-generated ID
To add a user, you must provide the minimum required attributes.
To locate the minimum required attributes:
-
From the Advanced Identity Cloud admin UI, click Native Consoles > Identity Management.
-
Click Configure > Managed Objects > managed/realm-name_user.
-
In the Required column, note the properties that have required marked.
-
To create a user, these are the minimum attributes you must present.
-
In this instance, Advanced Identity Cloud will create a UUID for you.
curl \ --header "Content-Type: application/json" \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request POST \ --data '{ "userName": "pjensen", "sn": "Jensen", "givenName": "Pam", "mail": "pjensen@example.com", "telephoneNumber": "082082082", "password": "Passw0rd" }' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_action=create" { "_id": "4121ae44-7bf4-4dcb-b853-cfc8b5b8582c", "_rev": "ceea2483-7f92-411e-9194-dcca0d61198e-51129", "userName": "pjensen", "sn": "Jensen", "givenName": "Pam", "mail": "pjensen@example.com", "telephoneNumber": "082082082", "accountStatus": "active", "effectiveAssignments": [], "effectiveRoles": [] }
Update a user
This example checks whether user bjackson
exists, then replaces the telephone number attribute with the new data provided in the request body:
curl \ --header "Content-Type: application/json" \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request POST \ --data '[ { "operation": "replace", "field": "/telephoneNumber", "value": "0763483726" } ]' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_action=patch&_queryFilter=userName+eq+'bjackson'" { "userName": "bjackson", "sn": "Jackson", "givenName": "Barbara", "mail": "bjackson@example.com", "telephoneNumber": "0763483726", "accountStatus": "active", "effectiveAssignments": [], "effectiveRoles": [], "_rev": "ceea2483-7f92-411e-9194-dcca0d61198e-51153", "_id": "4cf65bb9-baa4-4488-aa73-216adf0787a1" }
Delete a user
To delete a user, all you need is the UUID.
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request DELETE \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user/4cf65bb9-baa4-4488-aa73-216adf0787a1" { "_id": "4cf65bb9-baa4-4488-aa73-216adf0787a1", "_rev": "ceea2483-7f92-411e-9194-dcca0d61198e-51153", "userName": "bjackson", "sn": "Jackson", "givenName": "Barbara", "mail": "bjackson@example.com", "telephoneNumber": "0763483726", "accountStatus": "active", "effectiveAssignments": [], "effectiveRoles": [] }
Relationships between objects
Relationships are references between managed objects. Roles and Organizations are implemented using relationships.
The default Advanced Identity Cloud schema defines several user properties as relationships. For information on how to define custom relationships, refer to Manage custom relationship properties. |
Create a relationship between two objects
In the default IDM schema, several user properties are defined as
relationships, for example, the manager
relationship.
Relationships let you
reference one managed object from another using the _ref*
relationship
properties. Three properties make up a relationship reference:
-
_refResourceCollection
specifies the container of the referenced object, for example,managed/realm-name_user
. -
_refResourceId
specifies the ID of the referenced object. This is generally a system-generated UUID, such as9dce06d4-2fc1-4830-a92b-bd35c2f6bcbb
. -
_ref
is a derived path that is a combination of_refResourceCollection
and a URL-encoded_refResourceId
.
For example, imagine that you are creating a new user, psmith
, and that psmith
's manager is bjensen
.
You would add psmith
's user entry, and reference bjensen
's entry with the _ref
property.
First, retrieve bjensen
's UUID, displayed in the _id
property value.
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_queryFilter=userName+eq+%22bjensen%22" { "result": [ { "_id": "1dff18dc-ac57-4388-8127-dff309f80002", "_rev": "f4816053-aa01-4a7b-8380-8f3646787fd0-23348", "country": null, ... } ] ... }
Next, add the new user psmith
and specify bjensen
as the manager using the _ref
property. Make sure to use bjensen
's UUID, for example,
1dff18dc-ac57-4388-8127-dff309f80002
.
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request POST \ --data '{ "sn":"Smith", "userName":"psmith", "givenName":"Patricia", "displayName":"Patti Smith", "description" : "psmith - new user", "mail" : "psmith@example.com", "telephoneNumber" : "0831245986", "password" : "Passw0rd", "manager" : {"_ref" : "managed/realm-name_user/1dff18dc-ac57-4388-8127-dff309f80002"} }' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_action=create" { "_id": "51257f1e-6562-4b67-a80b-47b84f693f1b", "_rev": "6aad0f3b-eb20-4ae4-8c72-7e904b1062e5-34787", "country": null, "frUnindexedString1": null, "mail": "psmith@example.com", "memberOfOrgIDs": [], ... }
Note that relationship information is not returned by default. To show the relationship in psmith
's entry,
you must explicitly request their manager entry, as follows:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_queryFilter=userName+eq+%22psmith%22&_fields=manager" { "result": [ { "_id": "51257f1e-6562-4b67-a80b-47b84f693f1b", "_rev": "6aad0f3b-eb20-4ae4-8c72-7e904b1062e5-34787", "manager": { "_ref": "managed/alpha_user/1dff18dc-ac57-4388-8127-dff309f80002", "_refResourceCollection": "managed/alpha_user", "_refResourceId": "1dff18dc-ac57-4388-8127-dff309f80002", "_refProperties": { "_id": "3dd2c42d-598e-4b78-bf59-0aab43113be7", "_rev": "6aad0f3b-eb20-4ae4-8c72-7e904b1062e5-34784" } } } ], ... }
If a relationship changes, you can query the updated relationship state when any referenced managed objects are queried.
So, after creating user psmith
with manager bjensen
, run a query on bjensen
's user entry. The query shows a reference to psmith
's
entry in their reports
property, which is configured as the reversePropertyName
of the manager
property.
The following query shows bjensen
's direct reports including the new user entry, psmith
:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_queryFilter=userName+eq+%22bjensen%22&_fields=reports" { "result": [ { "_id": "1dff18dc-ac57-4388-8127-dff309f80002", "_rev": "f4816053-aa01-4a7b-8380-8f3646787fd0-23348", "reports": [ ... { "_ref": "managed/alpha_user/51257f1e-6562-4b67-a80b-47b84f693f1b", "_refResourceCollection": "managed/alpha_user", "_refResourceId": "51257f1e-6562-4b67-a80b-47b84f693f1b", "_refProperties": { "_id": "3dd2c42d-598e-4b78-bf59-0aab43113be7", "_rev": "6aad0f3b-eb20-4ae4-8c72-7e904b1062e5-34784" } } ] } ], ... }
IDM maintains referential integrity by deleting the relationship reference if the object referred to by that relationship is deleted. In our example, if bjensen 's user entry is deleted, the corresponding reference in psmith 's manager property is removed.
|
Manage custom relationship properties
Custom relationship properties allow you to define custom relationships between managed objects. For example, you could model a parent-child relationship by creating the custom_Parents
and custom_Children
properties and configuring them as one-way one-to-many relationships.
Only use the Advanced Identity Cloud admin UI or the Schema API to manage relationships. Using other methods may cause your data to de-sync. |
Create a custom relationship property
To create a custom relationship property using the Advanced Identity Cloud admin UI:
-
In the Advanced Identity Cloud admin UI, click Native Consoles > Identity Management.
-
From the top navigation menu, click Configure > Managed Objects.
-
Select a managed object type.
-
Click Add a Property. An entry field displays.
-
In the Name field, enter a name for the custom relationship property. The name must begin with the string
custom_
, such ascustom_Example
. -
From the Type drop-down, select Relationship.
-
Click Next. The Add Resources modal displays.
-
From the Resource drop-down, select the resource to map the custom relationship property to.
-
From the Display Properties drop-down, select the properties on the resource to map to the custom relationship property.
-
Click Save. The Relationships Property screen for the new relationship property displays.
Objects are limited to 10 custom relationships. If you need an object to have more, create custom relationships from the related object and map them to the original object. |
Update a custom relationship
You can adjust a custom relationship’s cardinality by configuring each side of the relationship to be have one, many, or none of the other side. For instance, custom_Managers
may have many custom_Employees
, while custom_Employees
have only one custom_Managers
.
To change the cardinality of a custom relationship using the Advanced Identity Cloud admin UI:
-
In the Advanced Identity Cloud admin UI, click Native Consoles > Identity Management.
-
From the top navigation menu, click Configure > Managed Objects.
-
Click the managed object type which has the relationship property to modify.
-
Click the relationship property to modify.
-
In the Relationship Configuration section, click the cardinality relationship name associated with the arrow indicating the direction of the relationship. A popover displays.
-
From the Relationship drop-down on the popover, select the cardinality of the relationship. The Changes Pending notification displays in the lower left of the UI.
-
Click Save.
When you change the configuration of a custom relationship, existing objects which contain that custom relationship are not automatically updated to match the new configuration. Ensure your data is updated to reflect the new relationship configuration. For example, suppose |
Delete a custom relationship property
Existing objects are not automatically updated when you delete a custom relationship property. When you delete a custom relationship property, you must also update the existing objects to no longer reference them. Failing to do this may result in the "orphaned" data unpredictably reappearing if Advanced Identity Cloud reuses the deleted reference attribute for other data.
Before you delete a custom relationship property, find all of the managed objects which are in the custom relationship and either modify or delete the data. The following REST API query returns all managed users with the property custom_Example
:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=2.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/user?_queryFilter=/custom_Example+pr&_pageSize=30"
For more information on using the REST API to manage custom relationship properties, refer to Schema.
Configure relationship change notification
A relationship exists between two managed objects. By default, when a relationship changes for any create, update, or delete operation, the managed objects on either side of the relationship are not notified of that change. This means that the state of each object with respect to that relationship field is not recalculated until the object is read. This default behavior improves performance, especially cases where many objects are affected by a single relationship change.
For roles
, change notification is set to TRUE
by default. This default configuration lets managed users receive notifications when any relationships that link users, roles, and assignments are manipulated. For more information about relationship change notification, refer to Roles and relationship change notification.
Origin and referenced objects
A relationship exists between an origin object and a referenced object. These terms reflect which managed object is specified in the URL (for example managed/realm-name_user/psmith
), and which object is referenced by the relationship (_ref*
) properties. For more information about the relationship properties, refer to Create a relationship between two objects.
In an example in the Create a relationship between two objects section, a POST on managed/realm-name_user/psmith
(UUID is 51257f1e-6562-4b67-a80b-47b84f693f1b
) with "manager":{_ref:"managed/realm-name_user/bjensen"}
(UUID is 1dff18dc-ac57-4388-8127-dff309f80002
) causes managed/realm-name_user/psmith
to be the origin object, and managed/realm-name_user/bjensen
to be the referenced object for that relationship.
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request POST \ --data '{ "sn":"Smith", "userName":"psmith", "givenName":"Patricia", "displayName":"Patti Smith", "description" : "psmith - new user", "mail" : "psmith@example.com", "telephoneNumber" : "0831245986", "password" : "Passw0rd", "manager" : {"_ref" : "managed/realm-name_user/1dff18dc-ac57-4388-8127-dff309f80002"} }' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_action=create" { "_id": "51257f1e-6562-4b67-a80b-47b84f693f1b", "_rev": "6aad0f3b-eb20-4ae4-8c72-7e904b1062e5-34787", "country": null, "frUnindexedString1": null, "mail": "psmith@example.com", "memberOfOrgIDs": [], ... }
This relationship is illustrated as follows:

Note that for the reverse relationship (a POST on managed/realm-name_user/bjensen
with "reports":[{_ref = "managed/realm-name_user/psmith"}]
) managed/realm-name_user/bjensen
would be the origin object, and managed/realm-name_user/psmith
would be the referenced object.
By default, when a relationship changes, neither the origin object nor the referenced object is notified of the change. So, with the POST on managed/realm-name_user/psmith
with "manager":{_ref:"managed/realm-name_user/bjensen"}
, neither psmith
's object nor bjensen
's object is notified.
This means that the objects are not updated to reflect the latest change.
Notification properties
To configure relationship change notifications, set the notify
and notifySelf
properties in your managed object schema.
Auditing is not tied to relationship change notification and is always triggered when a relationship changes; therefore,
relationship changes are audited, regardless of the |
The following properties specify whether objects that reference relationships are notified of a relationship change:
notifySelf
-
Notifies the origin object of the relationship change.
In our example, if the
manager
definition includes"notifySelf":true
and if the relationship is changed through a URL that referencespsmith
, thenpsmith
's object would be notified of the change. Thus, for any CREATE, UPDATE or DELETE request on thepsmith/manager
,psmith
would be notified, but the managed object referenced by this relationship (bjensen
) would not be notified.If the relationship were manipulated through a request to
bjensen/reports
, thenbjensen
would only be notified if thereports
relationship specified"notifySelf":true
. notify
-
Notifies the referenced object of the relationship change. Set this property on the
resourceCollection
of the relationship property.In our example, assume that the
manager
definition has aresourceCollection
with apath
ofmanaged/realm-name_user
and that this object specifies"notify":true
. If the relationship changes through any CREATE, UPDATE, or DELETE operation on the URLpsmith/manager
, then the reference object (managed/realm-name_user/bjensen
) would be notified of the change to the relationship. notifyRelationships
-
This property controls the propagation of notifications out of a managed object when one of its properties changes through an update or patch or when that object receives a notification through one of these fields.
The
notifyRelationships
property takes an array of relationships as a value; for example,"notifyRelationships":["relationship1", "relationship2"]
. The relationships specified here are fields defined on the managed object type, which might itself be a relationship.Notifications are propagated according to the recipient’s
notifyRelationships
configuration. If a managed object type is notified of a change through one if its relationship fields, the notification is done according to the configuration of the recipient object.To illustrate, review the
attributes
property in the defaultmanaged/realm-name_assignment
object:{ "name" : "assignment", "schema" : { ... "properties" : { ... "attributes" : { "description" : "The attributes operated on by this assignment.", "title" : "Assignment Attributes", ... "notifyRelationships" : ["roles"] }, ...
json
This configuration means that if an assignment is updated or patched and the assignment’s attributes
change in some way,
all the roles
connected to that assignment are notified.
Note that the role
managed object has "notifyRelationships":["members"]
defined on its assignments
field as follows:
{
"name" : "role",
"schema" : {
...
"properties" : {
...
"assignments" : {
...
"notifyRelationships" : ["members"]
}
...
}
When a role is notified of the creation of a new relationship to an assignment, the notification is propagated through
the assignments
property. Because "notifyRelationships":["members"]
is set on the assignments
property, the
notification is propagated across the role to all of its members.
Relationship change notifications
By default, roles
, assignments
, and members
use relationship change notification to ensure that relationship changes
are accurately provisioned.
For example, the default user
object includes a roles
property with notifySelf
set to true
:
{
"name" : "user",
...
"schema" : {
...
"properties" : {
...
"roles" : {
"description" : "Provisioning Roles",
...
"items" : {
"type" : "relationship",
...
"reverseRelationship" : true,
"reversePropertyName" : "members",
"notifySelf" : true,
...
}
...
In this case, notifySelf
indicates the origin or user
object. If any changes are made to a relationship referencing a role through a URL that includes a user, the user is notified of the change. For example, if there is a CREATE on managed/realm-name_user/psmith/roles
specifying a set of references to existing roles, user psmith
is notified of the change.
Similarly, the role
object also includes a members
property. That property includes the following schema definition:
{
"name" : "role",
...
"schema" : {
...
"properties" : {
...
"members" : {
...
"items" : {
"type" : "relationship",
...
"properties" : {
...
"resourceCollection" : [
{
"notify" : true,
"path" : "managed/realm-name_user",
"label" : "User",
...
}
]
}
...
Notice the "notify":true
setting on the resourceCollection
. This setting indicates that if the relationship is created, updated, or deleted through a URL that references that role, all objects in that resource collection (in this case, managed/realm-name_user
objects), which are identified as
members
of that role, are notified of the change.
|
Validate relationships between objects
Optionally, you can specify that a relationship between two objects must be validated when the relationship is created. For example, you can indicate that a user cannot reference a role if that role does not exist.
When you create a new relationship type, validation is disabled by default because it involves an expensive query to the relationship that is not always required.
To configure validation of a referenced relationship, set "validate":true
in the managed object schema. The default schema enables validation for the following relationships:
-
For user objects—roles, managers, and reports
-
For role objects—members and assignments
-
For assignment objects—roles
Query relationships bidirectionally
Relationships between two managed objects come in two forms: forward and reverse. Forward relationships mean one side points to the other in a uni-directional flow. Reverse relationships means both sides point to the other in a bidirectional flow.
Most cases use reverse or bidirectional relationships for efficient querying of objects.
For example, a relationship between a user and his manager might indicate a reverse relationship between the manager and her direct report.
You may want to query jdoe
's user entry to discover who his manager is, or query bjensen
's user entry to discover all the users who report to bjensen
.
You define a reverse relationship within a relationship definition. Consider the following sample excerpt of the default managed object configuration:
"reports" : {
"description" : "Direct Reports",
"title" : "Direct Reports",
...
"type" : "array",
"returnByDefault" : false,
"items" : {
"type" : "relationship",
"reverseRelationship" : true,
"reversePropertyName" : "manager",
"validate" : true,
...
}
...
The reports
property is a relationship
type between users and managers, so you can refer to a managed user’s reports by referencing the reports
object.
However, the reports
property is also a reverse relationship ("reverseRelationship":true
), which means you can list all users that reference that report.
You can list all users whose manager
property is set to the currently queried user.
The reverse relationship includes an optional resourceCollection
that lets you query a set of objects, based on specific fields:
"resourceCollection" : [
{
"path" : "managed/realm-name_user",
"label" : "User",
"query" : {
"queryFilter" : "true",
"fields" : [
"userName",
"givenName",
"sn"
]
}
}
]
The path
property of the resourceCollection
points to the set of objects to be queried. If this path is not in the local repository,
the link expansion can incur a significant performance cost. Although the resourceCollection
is optional,
the same performance cost is incurred if the property is absent.
The query
property indicates how you will query this resource collection to configure the relationship. In this case, "queryFilter":true
indicates that you can search on any of the properties listed in the fields
array when you are assigning a manager to a user
or a new report to a manager.
Grant relationships conditionally
Relationships can be granted dynamically, based on a specified condition. In order to conditionally grant a relationship, the schemas for the resources you are creating a relationship between need to be configured to support conditional association. To do this, three fields in the schema are used:
conditionalAssociation
-
Boolean. This property is applied to the
resourceCollection
for the grantor of the relationship. For example, themembers
relationship onmanaged/realm-name_role
specifies that there is a conditional association with themanaged/realm-name_user
resource:"resourceCollection" : [ { "notify" : true, "conditionalAssociation" : true, "path" : "managed/realm-name_user", "label" : "User", "query" : { "queryFilter" : "true", "fields" : [ "userName", "givenName", "sn" ] } } ]
json conditionalAssociationField
-
String. This property specifies the field used to determine whether a conditional relationship is granted. The field is applied to the
resourceCollection
of the grantee of the relationship. For example, theroles
relationship onmanaged/realm-name_user
specifies that the conditional association withmanaged/realm-name_role
is defined by thecondition
field inmanaged/realm-name_role
."resourceCollection" : [ { "path" : "{managed_role}", "label" : "Role", "conditionalAssociationField" : "condition", "query" : { "queryFilter" : "true", "fields" : [ "name" ] } } ]
jsonIf you are using the default schema, the field name is usually the condition
but can be any field that evaluates a condition and is flagged asisConditional
. isConditional
-
Boolean. This property is applied to the field to check whether membership in a relationship is granted. You can only mark one field on a resource as
isConditional
. For example, in the relationship betweenmanaged/realm-name_user
andmanaged/realm-name_role
, conditional membership in the relationship is determined by the query filter specified in themanaged/realm-name_role
condition
field:"condition" : { "description" : "A conditional filter for this role", "title" : "Condition", "viewable" : false, "searchable" : false, "isConditional" : true, "type" : "string" }
json
Conditions support both properties and virtual properties derived from other relationships, if the query property has been configured. Conditions are a powerful tool for dynamically creating relationships between two objects. An example of conditional relationships in use is covered in Grant a Role Based on a Condition.
View relationships over REST
By default, information about relationships is not returned as the result of a GET request on a managed object.
You must explicitly include the relationship property in the request. For example, if you request a user’s manager
entry,
the manager
's _ref
property returns the UUID (managed/alpha_user/1dff18dc-ac57-4388-8127-dff309f80002
) of the manager, bjensen
.
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_queryFilter=userName+eq+%22psmith%22&_fields=manager" { "result": [ { "_id": "4121ae44-7bf4-4dcb-b853-cfc8b5b8581c", "_rev": "e7b5a983-c0dc-405d-9d6a-cf0e186e5abf-66315", "manager": { "_ref": "managed/alpha_user/1dff18dc-ac57-4388-8127-dff309f80002", "_refResourceCollection": "managed/alpha_user", "_refResourceId": "1dff18dc-ac57-4388-8127-dff309f80002", "_refProperties": { "_id": "152ae6f2-d862-46df-8569-9cc2b2e6533a", "_rev": "a41bb123-7755-4ceb-9e49-e0f26b5912a8-15964" } } } ], ... }
To obtain more information about the referenced object (psmith
's manager, in this case), you can include additional fields
from the referenced object in the query, using the syntax object/property
(for a simple string value) or object/*/property
(for an array of values).
The following example returns the email address and contact number for psmith
's manager:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_queryFilter=userName+eq+%22psmith%22&_fields=manager/mail,manager/telephoneNumber" { "result": [ { "_id": "4121ae44-7bf4-4dcb-b853-cfc8b5b8581c", "_rev": "e7b5a983-c0dc-405d-9d6a-cf0e186e5abf-66315", "manager": { "_rev": "b5ae9a0e-cc07-45ba-8a9e-d8c43aa3ff13-4157", "_id": "1dff18dc-ac57-4388-8127-dff309f80002", "mail": "bjensen@example.com", "telephoneNumber": null, "_ref": "managed/alpha_user/1dff18dc-ac57-4388-8127-dff309f80002", "_refResourceCollection": "managed/alpha_user", "_refResourceId": "1dff18dc-ac57-4388-8127-dff309f80002", "_refProperties": { "_id": "152ae6f2-d862-46df-8569-9cc2b2e6533a", "_rev": "a41bb123-7755-4ceb-9e49-e0f26b5912a8-15964" } } } ], ... }
To query all the relationships associated with a managed object, query the reference (*_ref
) property of that object.
The following example shows all the objects referenced by psmith
's entry:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_queryFilter=userName+eq+%22psmith%22&_fields=*_ref" { "result": [ { "_id": "4121ae44-7bf4-4dcb-b853-cfc8b5b8581c", "_rev": "e7b5a983-c0dc-405d-9d6a-cf0e186e5abf-66315", "reports": [], "manager": { "_ref": "managed/alpha_user/1dff18dc-ac57-4388-8127-dff309f80002", "_refResourceCollection": "managed/alpha_user", "_refResourceId": "1dff18dc-ac57-4388-8127-dff309f80002", "_refProperties": { "_id": "152ae6f2-d862-46df-8569-9cc2b2e6533a", "_rev": "a41bb123-7755-4ceb-9e49-e0f26b5912a8-15964" } }, "adminOfOrg": [], "memberOfOrg": [], "ownerOfOrg": [], "roles": [], "_meta": { "_ref": "managed/alpha_usermeta/95718189-7138-4e18-97c4-5fe42e4cabb5", "_refResourceCollection": "managed/alpha_usermeta", "_refResourceId": "95718189-7138-4e18-97c4-5fe42e4cabb5", "_refProperties": { "_id": "57306c2d-8a49-49cc-9088-ef269a16d067", "_rev": "a41bb123-7755-4ceb-9e49-e0f26b5912a8-15967" } }, "authzRoles": [], "_notifications": [] } ], ... }
To expand that query to show all fields within each relationship, add a wildcard (*
) as follows:
curl \
--header "Authorization: Bearer <token>" \
--header "Accept-API-Version: resource=1.0" \
--request GET \
"https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_queryFilter=userName+eq+%22psmith%22&_fields=*_ref/*"
{
"result": [
{
"_id": "4121ae44-7bf4-4dcb-b853-cfc8b5b8581c",
"_rev": "e7b5a983-c0dc-405d-9d6a-cf0e186e5abf-66315",
"reports": [],
"manager": {
"_rev": "b5ae9a0e-cc07-45ba-8a9e-d8c43aa3ff13-4157",
"_id": "1dff18dc-ac57-4388-8127-dff309f80002",
"accountStatus": "active",
"aliasList": null,
"assignedDashboard": null,
"city": null,
"consentedMappings": null,
"country": null,
"description": "Password = Password1!",
"displayName": null,
"effectiveAssignments": null,
"effectiveRoles": null,
"frIndexedDate1": null,
...
"frIndexedInteger1": null,
...
"frIndexedMultivalued1": null,
...
"frIndexedString2": null,
...
"frUnindexedDate1": null,
...
"frUnindexedInteger1": null,
...
"frUnindexedMultivalued1": null,
...
"frUnindexedString1": null,
...
"givenName": "Babs",
"isMemberOf": [
"cn=am-policy-evaluation,ou=groups,o=alpha,o=root,ou=identities"
],
"kbaInfo": null,
"mail": "bjensen@example.com",
"memberOfOrgIDs": null,
"postalAddress": null,
"postalCode": null,
"preferences": null,
"profileImage": null,
"sn": "Jensen",
"stateProvince": null,
"telephoneNumber": null,
"userName": "bjensen",
"_ref": "managed/alpha_user/1dff18dc-ac57-4388-8127-dff309f80002",
"_refResourceCollection": "managed/alpha_user",
"_refResourceId": "1dff18dc-ac57-4388-8127-dff309f80002",
"_refProperties": {
"_id": "152ae6f2-d862-46df-8569-9cc2b2e6533a",
"_rev": "a41bb123-7755-4ceb-9e49-e0f26b5912a8-15964"
}
},
"adminOfOrg": [],
"memberOfOrg": [],
"ownerOfOrg": [],
"roles": [],
"_meta": {
"_rev": "e7b5a983-c0dc-405d-9d6a-cf0e186e5abf-66336",
"_id": "95718189-7138-4e18-97c4-5fe42e4cabb5",
"createDate": "2022-11-02T16:35:20.112988Z",
"lastChanged": {
"date": "2022-11-02T16:35:20.113032Z"
},
"loginCount": 1,
"_ref": "managed/alpha_usermeta/95718189-7138-4e18-97c4-5fe42e4cabb5",
"_refResourceCollection": "managed/alpha_usermeta",
"_refResourceId": "95718189-7138-4e18-97c4-5fe42e4cabb5",
"_refProperties": {
"_id": "57306c2d-8a49-49cc-9088-ef269a16d067",
"_rev": "a41bb123-7755-4ceb-9e49-e0f26b5912a8-15967"
}
},
"authzRoles": [],
"_notifications": []
}
],
...
}
Metadata is implemented using the relationships mechanism. When you request all relationships for a user with |
Roles
Roles define privileges for user and device identities. Roles let you automatically assign and update privileges in numerous identity profiles. For further information about roles and assignments, refer to Roles and assignments.
The role object is a managed object type that uses the relationships mechanism to link the role to the managed object to which it applies.
IDM role types
IDM supports two types of roles:
-
Provisioning roles : used to specify how objects are provisioned to an external system.
Provisioning roles are created as managed roles, at the context path
openidm/managed/realm-name_role/role-name
, and are granted to managed users as values of the user’sroles
property. -
Authorization roles : used to specify the authorization rights of a managed object internally, within IDM.
Authorization roles are created as internal roles, at the context path
openidm/internal/role/role-name
, and are granted to managed users as values of the user’sauthzRoles
property.
Authorization roles can also be granted statically during authentication with the defaultUserRoles
property.
Managed roles
Managed roles are intended to be collections of assignments for easier provisioning.
For information about roles, and how IDM controls authorization to its own endpoints, refer to Authorization and roles. |
Managed roles are defined like any other managed object, and are granted to users through the relationships mechanism. A managed role can be granted manually, as a static value of the user’s roles
attribute, or dynamically, as a result of a condition or script. For example, a user might be granted a role such as asia-sales-role
dynamically, if a user in the sales
organization is located in Asia region.
A user’s roles
attribute takes an array of references as a value, where the references point to the managed roles. For example, if user bjensen has been granted two roles (employee
and supervisor
), the value of bjensen’s roles
attribute would look something like the following:
"roles": [
{
"_ref": "managed/realm-name_role/employee",
"_refResourceCollection": "managed/realm-name_role",
"_refResourceId": "employee",
"_refProperties": {
"_grantType": "",
"_id": "bb399428-21a9-4b01-8b74-46a7ac43e0be",
"_rev": "00000000e43e9ba7"
}
},
{
"_ref": "managed/realm-name_role/supervisor",
"_refResourceCollection": "managed/realm-name_role",
"_refResourceId": "supervisor",
"_refProperties": {
"_grantType": "",
"_id": "9f7d124b-c7b1-4bcf-9ece-db4900e37c31",
"_rev": "00000000e9c19d26"
}
}
]
The _refResourceCollection
container holds each role. The _refResourceId
is the ID of the role. The _ref
property is a resource path that is derived from the _refResourceCollection
and the URL-encoded _refResourceId
. _refProperties
provides more information about the relationship.
Manipulate roles
These sections show how to create, read, update, and delete managed roles, and to grant roles to users. For information about using roles to provision users to external systems, refer to Use assignments to provision users.
Create a role
By default, the role |
Using the Advanced Identity Cloud admin UI
-
From the navigation bar, click Identities > Manage.
-
On the Manage Identities page, click Realm-name - Roles > New Realm-name - Role .
-
On the New Role page, enter a name and description for the new role, and click Next.
-
Optionally, to assign users to the role based on the presence of specific attributes, enable Condition, and define the query. Then click Next.
-
Optionally, to allow the role to be assigned only on a temporary basis, enable An array of temporal constraints for this role, and set the Start time, End time, and Time Zone Offset. Then click Save.
For more information, refer to Grant Roles Dynamically and Use temporal constraints to restrict effective roles.
Using the IDM admin UI
-
On the Quick Start page, click the Manage Roles tile.
-
On the Realm-name - Role List page, click New Realm-name - Role.
-
On the New Realm-name - Role page, enter a name and description, and click Save.
-
Optionally, do any of the following, and click Save:
-
To restrict the role grant to a set time period, enable Temporal Constraint, and set the Timezone Offset, Start Date, and End Date.
-
To define a query filter that dynamically grants the role to members, enable Condition, and define the query.
-
Using REST
To create a role, send a PUT or POST request to the /openidm/managed/realm-name_role
context path. The following example creates a managed role named employee
:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request POST \ --data '{ "name": "employee", "description": "Role granted to workers on the company payroll" }' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_role?_action=create" { "_id": "5790220a-719b-49ad-96a6-6571e63cbaf1", "_rev": "0000000079c6644f", "name": "employee", "description": "Role granted to workers on the company payroll" }
This employee
role has no corresponding assignments. Assignments are what enables the provisioning logic to the external system. Assignments are created and maintained as separate managed objects, and are referred to within role definitions. For more information about assignments, refer to Use assignments to provision users.
Use script hooks to configure role behavior. For more information, refer to event hooks. |
List roles
Using the Advanced Identity Cloud admin UI
-
From the navigation bar, click Identities > Manage.
-
On the Manage Identities page, click Realm-name - Roles > New Realm-name - Role.
Using REST
To list all the managed roles over REST, query the
openidm/managed/realm-name_role
endpoint. The following example shows the employee
role that you created in the previous example:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_role?_queryFilter=true" { "result": [ { "_id": "5790220a-719b-49ad-96a6-6571e63cbaf1", "_rev": "0000000079c6644f", "name": "employee", "description": "Role granted to workers on the company payroll" } ], ... }
Grant roles to a user
You grant roles to users through the relationship mechanism. Relationships are essentially references from one managed object to another; in this case, from a user object to a role object. For more information about relationships, refer to Relationships between objects.
You can grant roles statically or dynamically.
To grant a role statically, you must do one of the following:
-
Update the value of the user’s
roles
property to reference the role. -
Update the value of the role’s
members
property to reference the user.
Dynamic role grants use the result of a condition or script to update a user’s list of roles.
Using the Advanced Identity Cloud admin UI
-
From the navigation bar, click Identities > Manage.
-
On the Manage Identities page, click Realm-name - Roles > New Realm-name - Role.
-
Click the role-name you want to assign to users.
-
On the role-name page, click Role Members > + Add Role Members
-
Enter the name of the user.
-
Optionally enable Assign role only during a selected time period, and specify the time interval.
-
Click Save.
Using the IDM admin UI
-
On the Quick Start page, click the Manage Roles tile.
-
On the Realm-name - Role List page, click Realm-name.
-
On the Realm-name page, click Role Members > Add Role Members.
-
Enter Realm-name in the Role Members field.
-
Optionally, to restrict the role grant to a set time period, enable Temporal Constraint, and set the Timezone Offset, Start Date, and End Date.
-
Click Add.
Using REST
Grant roles statically
Use one of the following methods to grant a role statically to a user over REST:
-
Add the user as a role member.
This preferred method does not incur an unnecessary performance cost when working with a role that contains many members. The following example adds user scarter with UUID 1002e929-5605-4a31-865d-ee0a16df6e3a as a member of the role (
5790220a-719b-49ad-96a6-6571e63cbaf1
):curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request POST \ --data '{ "_ref":"managed/realm-name_user/<scarterUUID>", "_refProperties":{} }' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_role/5790220a-719b-49ad-96a6-6571e63cbaf1/members?_action=create" { "_id": "4c32ae53-abed-45f8-bc84-c367e2b0e194", "_rev": "5b65b2b8-4955-461b-8532-d763426fc058-5396", "_ref": "managed/realm-name_user/1002e929-5605-4a31-865d-ee0a16df6e3a", "_refResourceCollection": "managed/realm-name_user", "_refResourceId": "<scarterUUID>", "_refProperties": { "_id": "4c32ae53-abed-45f8-bc84-c367e2b0e194", "_rev": "5b65b2b8-4955-461b-8532-d763426fc058-5396" } }
-
Update the user’s
roles
property to refer to the role.The following example grants the
employee
role (5790220a-719b-49ad-96a6-6571e63cbaf1
) to userscarter
:curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request PATCH \ --data '[ { "operation": "add", "field": "/roles/-", "value": {"_ref" : "managed/realm-name_role/5790220a-719b-49ad-96a6-6571e63cbaf1"} } ]' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user/<scarterUUID>" { "_id": "<scarterUUID>", "_rev": "000000003be825ce", "mail": "scarter@example.com", "givenName": "Steven", "sn": "Carter", "description": "Created By CSV", "userName": "scarter", "telephoneNumber": "1234567", "accountStatus": "active", "effectiveRoles": [ { "_ref": "managed/realm-name_role/5790220a-719b-49ad-96a6-6571e63cbaf1" } ], "effectiveAssignments": [] }
Note that
scarter’s
effectiveRoles
attribute has been updated with a reference to the new role. For more information about effective roles and effective assignments, refer to Effective roles and effective assignments.When you update a user’s existing roles array, use the
-
special index to add the new value to the set. For more information, refer to Set semantic arrays in Patch. -
Update the role’s
members
property to refer to the user.The following sample command makes scarter a member of the
employee
role:curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request PATCH \ --data '{ "operation": "add", "field": "/members/-", "value": {"_ref" : "managed/realm-name_user/<scarterUUID>"} }' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_role/5790220a-719b-49ad-96a6-6571e63cbaf1" { "_id": "5790220a-719b-49ad-96a6-6571e63cbaf1", "_rev": "0000000079c6644f", "name": "employee", "description": "Role granted to workers on the company payroll" }
The
members
property of a role is not returned by default in the output. To show all members of a role, you must specifically request the relationship properties (*_ref
) in your query. The following example lists the members of theemployee
role (currently only scarter):curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_role/5790220a-719b-49ad-96a6-6571e63cbaf1?_fields=*_ref,name" { "_id": "5790220a-719b-49ad-96a6-6571e63cbaf1", "_rev": "0000000079c6644f", "name": "employee", "assignments": [], "members": [ { "_ref": "managed/realm-name_user/<scarterUUID>", "_refResourceCollection": "managed/realm-name_user", "_refResourceId": "<scarterUUID>", "_refProperties": { "_id": "7ad15a7b-6806-487b-900d-db569927f56d", "_rev": "0000000075e09cbf" } } ] }
-
You can replace an existing role grant with a new one by using the
replace
operation in your patch request.The following command replaces scarter’s entire
roles
entry (that is, overwrites any existing roles) with a single entry, the reference to theemployee
role (ID5790220a-719b-49ad-96a6-6571e63cbaf1
):curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request PATCH \ --data '[ { "operation": "replace", "field": "/roles", "value": [ {"_ref":"managed/realm-name_role/5790220a-719b-49ad-96a6-6571e63cbaf1"} ] } ]' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user/<scarterUUID>" { "_id": "<scarterUUID>", "_rev": "00000000da112702", "mail": "scarter@example.com", "givenName": "Steven", "sn": "Carter", "description": "Created By CSV", "userName": "scarter", "telephoneNumber": "1234567", "accountStatus": "active", "effectiveRoles": [ { "_ref": "managed/realm-name_role/5790220a-719b-49ad-96a6-6571e63cbaf1" } ], "effectiveAssignments": [] }
Grant roles dynamically
Grant a role dynamically by using one of the following methods:
-
Use a condition, expressed as a query filter, in the role definition. If the condition is
true
for a particular member, that member is granted the role. Conditions can be used in both managed and internal roles. -
Use a custom script to define a more complex role-granting strategy.
Grant a conditional role
A role that is granted based on a defined condition is called a conditional role. To create a conditional role, include a query filter in the role definition.
To set up a condition for a role by using the Advanced Identity Cloud admin UI, select Settings node on the role [.var]#Role-nmae page, then define the query filter that will be used to assess the condition.
To set up a condition for a role by using the IDM admin UI, select Condition on the role Details page, then define the query filter that will be used to assess the condition.
To set up a condition for a role over REST, include the query filter as a value of the condition
property in the role definition.
The following example creates a role, fr-employee
, that will be granted to users whose country
property is set to FR
:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request POST \ --data '{ "name": "fr-employee", "description": "Role granted to employees resident in France", "condition": "/country eq \"FR\"" }' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_role?_action=create" { "_id": "eb18a2e2-ee1e-4cca-83fb-5708a41db94f", "_rev": "000000004085704c", "name": "fr-employee", "description": "Role granted to employees resident in France", "condition": "/country eq \"FR\"" }
When a condition is enabled for a role, IDM automatically assesses all managed users. It recalculates the value of the roles
property for users who qualify for that role.
When a condition is removed from a role, that is, when the role becomes an unconditional role, all conditional grants are removed. So, users who were granted the role based on the condition, have that role removed from their roles
property.
When a condition is defined in an existing data set, every user entry (including the mapped entries on remote systems) must be updated with the assignments implied by that conditional role. The time that it takes to create a new conditional role is impacted by the following items:
In a data set with a very large number of users, creating a new conditional role can therefore incur a significant performance cost when you create it. Ideally, you should set up your conditional roles at the beginning of your deployment to avoid performance issues later. |
Query a user’s roles
Using the Advanced Identity Cloud admin UI
-
From the navigation bar, click Identities > Manage.
-
On the Manage Identities page, click Realm name - Users.
-
Click the User name you want to check the roles.
-
On the User name page, click Provisioning Roles.
Using the IDM admin UI
You can verify the dynamic and static roles granted to a user from the user’s entry in the IDM admin UI:
-
On the Quick Start page, select Manage Users, then select User name.
-
Select the Provisioning Roles tab.
-
If you have a large number of managed roles, use the Advanced Filter option on the Role List page to build a custom query.
Using REST
Query user’s roles
property to get the roles granted to the user. The following example shows that scarter
has been granted two roles—an employee
role, and an fr-employee
role:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user/<scarterUUID>/roles?_queryFilter=true&_fields=_ref/*,name" { "result": [ { "_id": "5a023862-654d-4d7f-b9d0-7c151b8dede5", "_rev": "00000000baa999c1", "_refResourceCollection": "managed/realm-name_role", "_refResourceId": "b8783543-869a-4bd4-907e-9c1d89f826ae", "_refResourceRev": "0000000027a959cf", "name": "employee", "_ref": "managed/realm-name_role/b8783543-869a-4bd4-907e-9c1d89f826ae", "_refProperties": { "_id": "5a023862-654d-4d7f-b9d0-7c151b8dede5", "_rev": "00000000baa999c1" } }, { "_id": "b281ffdf-477e-4211-a112-84476435bab2", "_rev": "00000000d612a248", "_refResourceCollection": "managed/realm-name_role", "_refResourceId": "01ee6191-75d8-4d4b-9291-13a46592c57a", "_refResourceRev": "000000000cb0794d", "name": "fr-employee", "_ref": "managed/realm-name_role/01ee6191-75d8-4d4b-9291-13a46592c57a", "_refProperties": { "_grantType": "conditional", "_id": "b281ffdf-477e-4211-a112-84476435bab2", "_rev": "00000000d612a248" } } ], ... }
Note that the fr-employee
role indicates a _grantType
of conditional
. This property indicates how the role was granted to the user. If no _grantType
is listed, the role was granted statically.
Querying a user’s roles in this way does not return any roles that would be in effect as a result of a custom script, or of any temporal constraint applied to the role. To return a complete list of all the roles in effect at a specific time, query the user’s effectiveRoles
property, as follows:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user/<scarterUUID>?_fields=effectiveRoles"
Remove a user’s roles
To remove a statically granted role from a user entry, do one of the following:
-
Update the value of the user’s
roles
property to remove the reference to the role. -
Update the value of the role’s
members
property to remove the reference to that user.
A delegated administrator must use PATCH to add or remove relationships. Roles that have been granted as the result of a condition can only be removed when the condition is changed or removed, or when the role itself is deleted. |
Using the Advanced Identity Cloud admin UI
-
From the navigation bar, click Identities > Manage.
-
On the Manage Identities page, click Realm name - Roles.
-
Click the Role name that you want to delete membership.
-
Select the users you want to remove from this role and click Remove.
-
On the Confirm Removal page, click Remove.
Using the IDM admin UI
Method 1 (If you want to remove multiple roles from a user):
-
On the Quick Start page, select Manage Users, and select the user whose roles you want to remove.
-
Select the Provisioning Roles tab, select the roles that you want to remove, then select Remove Selected Provisioning Roles.
Method 2 (If you want to remove a role from multiple users):
-
On the Quick Start page, select Manage Roles, and select the role whose members you want to remove.
-
Select the Role Members tab, select the members that you want to remove, then select Remove Selected Role Members.
Using REST
Use one of the following methods to remove a role grant from a user:
-
DELETE the role from the user’s
roles
property, including the reference ID (the ID of the relationship between the user and the role) in the delete request.The following example removes the
employee
role from user scarter. The role ID isb8783543-869a-4bd4-907e-9c1d89f826ae
, but the ID required in the DELETE request is the reference ID (5a023862-654d-4d7f-b9d0-7c151b8dede5
):curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request DELETE \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user/<scarterUUID>/roles/5a023862-654d-4d7f-b9d0-7c151b8dede5" { "_id": "5a023862-654d-4d7f-b9d0-7c151b8dede5", "_rev": "00000000baa999c1", "_ref": "managed/realm-name_role/b8783543-869a-4bd4-907e-9c1d89f826ae", "_refResourceCollection": "managed/realm-name_role", "_refResourceId": "b8783543-869a-4bd4-907e-9c1d89f826ae", "_refProperties": { "_id": "5a023862-654d-4d7f-b9d0-7c151b8dede5", "_rev": "00000000baa999c1" } }
-
PATCH the user entry to remove the role from the array of roles, specifying the value of the role object in the JSON payload.
When you remove a role in this way, you must include the entire object in the value, as shown in the following example: curl \ --header "Content-type: application/json" \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request PATCH \ --data '[ { "operation" : "remove", "field" : "/roles", "value" : { "_ref": "managed/realm-name_role/b8783543-869a-4bd4-907e-9c1d89f826ae", "_refResourceCollection": "managed/realm-name_role", "_refResourceId": "b8783543-869a-4bd4-907e-9c1d89f826ae", "_refProperties": { "_id": "5a023862-654d-4d7f-b9d0-7c151b8dede5", "_rev": "00000000baa999c1" } } } ]' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user/<scarterUUID>" { "_id": "<scarterUUID>", "_rev": "000000007b78257d", "mail": "scarter@example.com", "givenName": "Steven", "sn": "Carter", "description": "Created By CSV", "userName": "scarter", "telephoneNumber": "1234567", "accountStatus": "active", "effectiveRoles": [ { "_ref": "managed/realm-name_role/01ee6191-75d8-4d4b-9291-13a46592c57a" } ], "effectiveAssignments": [], "preferences": { "updates": false, "marketing": false }, "country": "France" }
-
DELETE the user from the role’s
members
property, including the reference ID (the ID of the relationship between the user and the role) in the delete request.The following example first queries the members of the
employee
role, to obtain the ID of the relationship, then removes bjensen’s membership from that role:curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_role/b8783543-869a-4bd4-907e-9c1d89f826ae/members?_queryFilter=true" { "result": [ { "_id": "a5a4bf94-6425-4458-aae4-bbd6ad094f72", "_rev": "00000000c25d994a", "_ref": "managed/realm-name_user/bjensen", "_refResourceCollection": "managed/realm-name_user", "_refResourceId": "bjensen", "_refProperties": { "_id": "a5a4bf94-6425-4458-aae4-bbd6ad094f72", "_rev": "00000000c25d994a" } } ], ... }
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request DELETE \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_role/b8783543-869a-4bd4-907e-9c1d89f826ae/members/a5a4bf94-6425-4458-aae4-bbd6ad094f72" { "_id": "a5a4bf94-6425-4458-aae4-bbd6ad094f72", "_rev": "00000000c25d994a", "_ref": "managed/realm-name_user/bjensen", "_refResourceCollection": "managed/realm-name_user", "_refResourceId": "bjensen", "_refProperties": { "_id": "a5a4bf94-6425-4458-aae4-bbd6ad094f72", "_rev": "00000000c25d994a" } }
Delete a role definition
To delete a role over the REST interface, delete that managed object.
You cannot delete a role that is currently granted to users. If you attempt to delete a role that is granted to a user (either over the REST interface, or by using the IDM admin UI), IDM returns an error. |
Using the Advanced Identity Cloud admin UI
-
From the navigation bar, click Identities > Manage.
-
On the Manage Identities page, click Realm name - Roles.
-
Click the Role name you want to delete.
-
Click Delete Realm name - Role.
-
On the Delete Realm name - Role page, click Delete.
Using the IDM admin UI
-
On the Quick Start page, select Manage Roles.
-
Select the roles you want to remove and click Delete Selected.
Using REST
The following example deletes the employee
role created in the previous section:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request DELETE \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_role/b8783543-869a-4bd4-907e-9c1d89f826ae" { "_id": "b8783543-869a-4bd4-907e-9c1d89f826ae", "_rev": "0000000027a959cf", "privileges": [], "name": "employee", "description": "All employees" }
The following example attempts to remove a role that is still granted to a user, and receives an error message: curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request DELETE \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_role/01ee6191-75d8-4d4b-9291-13a46592c57a" { "code": 409, "reason": "Conflict", "message": "Cannot delete a role that is currently granted" } |
Use temporal constraints to restrict effective roles
Temporal constraints restrict the period that a role is effective. You can apply temporal constraints to managed and internal roles, and to role grants (for individual users).
For example, you may want a role, contractors-2020
, to apply to all contract employees for the year 2020. In this case, you would set the temporal constraint on the role. Alternatively, you may want to assign a contractors
role that applies to an individual user only for the period of their contract of employment.
The following examples show how to set temporal constraints on role definitions, and on individual role grants.
Add a temporal constraint to a role
When you create a role, you can include a temporal constraint in the role definition that restricts the validity of the role, regardless of how that role is granted. Temporal constraints are expressed as a time interval in ISO 8601 date and time format. For more information on this format, refer to the ISO 8601 standard.
The following example adds a contractor
role over the REST interface. The role is effective from March 1, 2020 to August 31, 2020:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request POST \ --data '{ "name": "contractor", "description": "Role granted to contract workers for 2020", "temporalConstraints": [ { "duration": "2020-03-01T00:00:00.000Z/2020-08-31T00:00:00.000Z" } ] }' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_role?_action=create" { "_id": "ed761370-b24f-4e21-8e58-a3230942da67", "_rev": "000000007429750e", "name": "contractor", "description": "Role granted to contract workers for 2020", "temporalConstraints": [ { "duration": "2020-03-01T00:00:00.000Z/2020-08-31T00:00:00.000Z" } ] }
This example specifies the time zone as Coordinated Universal Time (UTC) by appending Z
to the time. If no time zone information is provided, the time zone is assumed to be local time. To specify a different time zone, include an offset (from UTC) in the format ±hh:mm
. For example, an interval of 2020-03-01T00:00:00.000-07:00/2020-08-31T00:00:00.000-07:00
specifies a time zone seven hours behind UTC.
When the period defined by the constraint ends, the role object remains in the repository, but the effective roles script will not include the role in the list of effective roles for any user.
The following example assumes the user scarter was granted a role contractor-march
. A temporal constraint was included in the contractor-march
role definition, specifying that the role should be applicable only during the month of March 2020. At the end of this period, a query on scarter’s entry shows that his roles
property still includes the contractor-march
role (with ID 0face495-772d-4d36-a30d-8594618aba0d
), but his effectiveRoles
property does not:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user/<scarterUUID>?_fields=_id,userName,roles,effectiveRoles" { "_id": "scarter", "_rev": "00000000e5fdeb51", "userName": "scarter", "effectiveRoles": [], "roles": [ { "_ref": "managed/realm-name_role/0face495-772d-4d36-a30d-8594618aba0d", "_refResourceCollection": "managed/realm-name_role", "_refResourceId": "0face495-772d-4d36-a30d-8594618aba0d", "_refProperties": { "_id": "5f41d5a5-19b4-4524-a4b1-445790ff14da", "_rev": "00000000cb339810" } } ] }
The role is still in place but is no longer effective.
To restrict the period a role is valid by using the IDM admin UI, select Temporal Constraint on the role Details tab, then select a time zone offset relative to GMT and the start and end dates for the required period.
Add a temporal constraint to a role grant
To restrict the validity of a role for individual users, apply a temporal constraint at the grant level, rather than as part of the role definition. In this case, the temporal constraint is taken into account per user, when the user’s effective roles are calculated. Temporal constraints defined at the grant level can differ for each user who is a member of that role.
To apply a temporal constraint to a grant over the REST interface, include the constraint as one of the _refProperties
of the relationship between the user and the role. The following example assumes a contractor
role, with ID ed761370-b24f-4e21-8e58-a3230942da67
. The command adds user bjensen as a member of that role, with a temporal constraint that specifies she be a member of the role for one year only, from January 1, 2020 to January 1, 2021:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request PATCH \ --data '[ { "operation": "add", "field": "/members/-", "value": { "_ref": "managed/realm-name_user/bjensen", "_refProperties": { "temporalConstraints": [{"duration": "2020-01-01T00:00:00.000Z/2021-01-01T00:00:00.000Z"}] } } } ]' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_role/<contractorUUID>" { "_id": "ed761370-b24f-4e21-8e58-a3230942da67", "_rev": "000000007429750e", "name": "contractor", "description": "Role granted to contract workers for 2020", "temporalConstraints": [ { "duration": "2020-03-01T00:00:00.000Z/2020-08-31T00:00:00.000Z" } ] }
A query on bjensen’s roles property shows the temporal constraint was applied to this grant:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user/<bjensenUUID>/roles?_queryFilter=true" { "result": [ { "_id": "40600260-111d-4695-81f1-450365025784", "_rev": "00000000173daedb", "_ref": "managed/realm-name_role/ed761370-b24f-4e21-8e58-a3230942da67", "_refResourceCollection": "managed/realm-name_role", "_refResourceId": "ed761370-b24f-4e21-8e58-a3230942da67", "_refProperties": { "temporalConstraints": [ { "duration": "2020-01-01T00:00:00.000Z/2021-01-01T00:00:00.000Z" } ], "_id": "40600260-111d-4695-81f1-450365025784", "_rev": "00000000173daedb" } } ], ... }
To restrict the period that a role grant is valid using the IDM admin UI, set a temporal constraint when you add the member to the role.
For example, to specify that bjensen is added to a Contractor role only for the period of her employment contract, select Manage > Role, select the Contractor role, then select Add Role Members. On the Add Role Members screen, select bjensen from the list, then enable the Temporal Constraint, and specify the start and end date of her contract.
Use assignments to provision users
Authorization roles control access to IDM itself. Provisioning roles define the rules for how attribute values update on external systems.
You configure these rules using assignments that are attached to a provisioning role definition or directly assigned to a user. Assignments provision an attribute or set of attributes based on an object’s role membership or through a direct assignment. After you configure a synchronization mapping configuration between two resources to provide the basic account provisioning logic (how an account is mapped from a source to a target system), then you can use role assignments to add more logic. The attributes and values that are updated by using assignments might include membership in external groups, access to specific external resources, and so on. A set of assignments can collectively represent a role.
Assignment objects are created, updated, and deleted like any other managed object, and are attached to a role by using the relationships mechanism, in much the same way as a role is granted to a user. Assignments are stored in the repository and are accessible at the context path /openidm/managed/realm-name_assignment
.
This section describes how to manage assignments over the REST interface, and by using the Advanced Identity Cloud admin UI.
When you create an assignment, and if desired, attach it to a role definition, all user objects that reference that role definition will, as a result, reference the corresponding assignment in their effectiveAssignments
attribute.
If you have mapped roles and assignments to properties on a target system, and you are preloading the result set into memory, make sure that your The following mapping excerpt indicates that the target query must return the
json For more information about preloading the result set for reconciliation operations, refer to Improve Reconciliation Query Performance. |
Create an assignment
You can create assignments over the REST interface or using the Advanced Identity Cloud admin UI.
- Over REST
-
To create a new assignment over REST, send a PUT or POST request to the
/openidm/managed/realm-name_assignment
context path.The following example creates a new managed assignment named
employee
. The JSON payload in this example shows the following:-
The assignment is applied for the mapping
managedAlpha_user_systemLdapAccounts
, so attributes will be updated on the external LDAP system specified in this mapping. -
The name of the attribute on the external system whose value will be set is
employeeType
, and its value will be set toEmployee
. -
When the assignment is applied during a sync operation, the attribute value
Employee
is added to any existing values for that attribute. When the assignment is removed (if the role is deleted, or if the user is no longer a member of that role), the attribute valueEmployee
is removed from the values of that attribute.curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request POST \ --data '{ "name": "employee", "description": "Assignment for employees", "mapping": "managedAlpha_user_systemLdapAccounts", "attributes": [ { "name": "employeeType", "value": [ "Employee" ], "assignmentOperation": "mergeWithTarget", "unassignmentOperation": "removeFromTarget" } ] }' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_assignment?_action=create" { "_id": "1a6a3af3-024f-4cf1-b4f6-116b98053816", "_rev": "132bbd98-b3d6-4d70-9274-7bcd4e765d3a-6329", "name": "employee", "description": "Assignment for employees", "mapping": "managedAlpha_user_systemLdapAccounts", "attributes": [ { "name": "employeeType", "value": [ "Employee" ], "assignmentOperation": "mergeWithTarget", "unassignmentOperation": "removeFromTarget" } ] }
At this stage the assignment is not linked to any role, so no user can make use of the assignment. To make use of the assignment, either Add a user directly to an assignment or Add an assignment to a role.
-
- Using the Advanced Identity Cloud admin UI
-
-
Select Identities > Manage > Alpha realm - Assignments > + New Alpha realm - assignment.
-
Enter a name, description, and select the mapping to which the assignment should apply.
The mapping indicates the target resource, that is, the resource on which the attributes specified in the assignment will be adjusted.
-
Click Next.
-
Click + Add an attribute to attach an attribute to your assignment.
-
Select the Target system attribute, enter the Value of the attribute.
-
Click the gear icon and determine the action to take when assigning and unassigning the attribute to a user:
-
On Assignment select one of the following:
-
Merge with target: The attribute value is added to any existing values for that attribute. This operation merges the existing value of the target object attribute with the value(s) from the assignment. If duplicate values are found (for attributes that take a list as a value), each value is included only once in the resulting target. This assignment operation is used only with complex attribute values like arrays and objects, and does not work with strings or numbers.
-
Replace target: The attribute value overwrites any existing values for that attribute. The value from the assignment becomes the authoritative source for the attribute.
-
-
On Unassignment select one of the following:
-
Remove from target: The attribute value is removed from the system object when the user is no longer a member of the role, or when the assignment itself is removed from the role definition.
-
No Operation: When you remove the assignment from the user’s effectiveAssignments, it has no effect on the current state of the attribute in the system object.
-
-
-
Repeat steps 4-6 until you have added all the attributes required for the assignment.
-
Click Save.
-
Modify an assignment
After you create an assignment, you can modify it by doing one or more of the following:
Add script logic when assignment is granted or revoked
After you create an assignment, you can specify custom logic to take place during assignment or unassignment of an assignment.
These scripts apply additional logic or operations that should be performed when a user (or other object) receives or loses an entire assignment. This logic must not be restricted to an operation on a single attribute.
For example, if an assignment is removed from a user, in the onUnassignment
event, the system can automatically perform additional actions such as revoking access to any external systems, sending notifications to managers or IT staff, and archiving or deleting the users’s data.
To create a script to associate with an assignment event:
-
On the Details tab of the assignment in the Event Scripts section, click Add an event script.
-
In the Event box, select the script to apply to
onAssignment
oronUnassignment
of the assignment to the user. -
Define the script by specifying what should happen to each attribute in the script.
The scriptable
onAssignment
andonUnassignment
events operate at the assignment level, rather than the attribute level.The onAssignment
andonUnassignment
events occur before the onCreate or onUpdate scripts.Table 1. Variables available in assignment script Variable Description sourceObject
The full, original object from the source system (in this case, Advanced Identity Cloud).
targetObject
The current, computed value, from the mapping logic. This results from the property mapping logic or prior assignment computation.
existingTargetObject
The object that exists (if any) in the current target system, before the update is made.
linkQualifier
A string value that represents a version of the source object as it is mapped to a record in the target system. There can be multiple
linkQualifiers
for a given mapping, but in this context, it is the one being processed.For more information, refer to Map a single source object to multiple target objects.
attributeName
The name of the attribute in the assignment to reference.
attributeValue
The value of an attribute in the assignment to reference.
attributesInfo
A mechanism that allows one invocation of an
onAssignment
oronUnassignment
events to communicate helpful information to other invocations, as needed.Role assignment scripts must always return
targetObject
, otherwise other scripts and code that occur downstream of your script will not work as expected. For example, specify:return targetObject;
Add a user directly to an assignment
You can add an assignment directly to users in Advanced Identity Cloud instead of through a role.
Add users to an assignment directly over REST or using the Advanced Identity Cloud admin UI.
- Over REST
-
Update the assignment definition to include a reference to the ID of the user in the
members
property of the assignment.The following example adds the user (ID
1a6a3af3-024f-4cf1-b4f6-116b98053816
) to an existing assignment (IDassignmentTest
):curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request PATCH \ --data '[ { "operation": "add", "field": "/members/-", "value": { "_ref": "managed/realm-name_user/1a6a3af3-024f-4cf1-b4f6-116b98053816" } } ]' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_assignment/assignmentTest" { "_id": "assignmentTest", "_rev": "4f50bccb-dbad-46dd-b703-962ae61c77c9-1683", "name": "assignmentTest", "description": "This is an assignment", "mapping": "managedAlpha_user_systemLdapAccounts", "attributes": [] }
- Using the Advanced Identity Cloud admin UI
-
-
Select Identities > Manage > Alpha realm - Assignments > assignment.
-
Select the Assignment Members tab.
-
Click +Add Assignment Members.
-
Select the user(s) to directly add to the assignment.
-
Click Save.
-
Add an assignment to a role
After you create a role and an assignment, create a relationship between the assignment and the role, in much the same way as a user references a role.
Update a role definition to include one or more assignments over the REST interface or using the Advanced Identity Cloud admin UI:
- Over REST
-
Update the role definition to include a reference to the ID of the assignment in the
assignments
property of the role. The following example adds theemployee
assignment (ID1a6a3af3-024f-4cf1-b4f6-116b98053816
) to an existingemployee
role (ID2243f5f8-ed75-4c3b-b4b3-058d5c58fbb4
):curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request PATCH \ --data '[ { "operation": "add", "field": "/assignments/-", "value": { "_ref": "managed/realm-name_assignment/1a6a3af3-024f-4cf1-b4f6-116b98053816" } } ]' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_role/2243f5f8-ed75-4c3b-b4b3-058d5c58fbb4" { "_id": "2243f5f8-ed75-4c3b-b4b3-058d5c58fbb4", "_rev": "132bbd98-b3d6-4d70-9274-7bcd4e765d3a-4145", "privileges": [], "name": "employee", "description": "Roll granted to all permanent employees" }
To check that the assignment was added successfully, query the role’s
assignments
property:curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_role/2243f5f8-ed75-4c3b-b4b3-058d5c58fbb4/assignments?_queryFilter=true&_fields=_ref/*,name,assignments" { "result": [ { "_id": "8189bbb9-a7fb-45cb-b4c0-49a6ddd47b64", "_rev": "132bbd98-b3d6-4d70-9274-7bcd4e765d3a-4144", "_refResourceCollection": "managed/realm-name_assignment", "_refResourceId": "1a6a3af3-024f-4cf1-b4f6-116b98053816", "_refResourceRev": "132bbd98-b3d6-4d70-9274-7bcd4e765d3a-6329", "name": "Employee", "_ref": "managed/realm-name_assignment/alpha_assignment/1a6a3af3-024f-4cf1-b4f6-116b98053816", "_refProperties": { "_id": "8189bbb9-a7fb-45cb-b4c0-49a6ddd47b64", "_rev": "132bbd98-b3d6-4d70-9274-7bcd4e765d3a-4144" } } ], ... }
The
assignments
property references the assignment shown in the previous step.To remove an assignment from a role definition, remove the reference to the assignment from the role’s
assignments
property. - Using the Advanced Identity Cloud admin UI
-
You can assign an assignment to a role in the following ways:
-
From an assignment to a role
-
From a role to an assignment
- From assignment to role
-
-
Select Identities > Manage > Alpha realm - Assignments > assignment.
-
Click the Managed Roles tab.
-
Click + Add Managed Roles.
-
Select the role(s) to associate to the assignment.
-
Click Save.
-
- From role to assignment
-
-
Select Identities > Manage > Alpha realm - Roles > role.
-
Select the Managed Assignments tab and click + Add Managed Assignments.
-
Select the assignment(s) to associate to the role.
-
Click Save.
-
-
Delete an assignment
You can delete assignments over REST or using the Advanced Identity Cloud admin UI.
Deleting an assignment may result in large downstream impacts, such as removing attributes or access to many users in an external system. |
You can delete an assignment, even if it is referenced by a managed role. When the assignment is removed, any users to whom the corresponding roles were granted will no longer have that assignment in their list of effectiveAssignments . For more information about effective roles and effective assignments, refer to Effective roles and effective assignments.
|
- Over REST
-
To delete an assignment over the REST interface, simply delete that object. The following example deletes the
employee
assignment created in the previous example:curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request DELETE \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_assignment/1a6a3af3-024f-4cf1-b4f6-116b98053816" { "_id": "1a6a3af3-024f-4cf1-b4f6-116b98053816", "_rev": "132bbd98-b3d6-4d70-9274-7bcd4e765d3a-6329", "name": "employee", "description": "Assignment for employees", "mapping": "managedAlpha_user_systemLdapAccounts", "attributes": [ { "name": "employeeType", "value": [ "Employee" ], "assignmentOperation": "mergeWithTarget", "unassignmentOperation": "removeFromTarget" } ] }
- Using the Advanced Identity Cloud admin UI
-
-
In the Advanced Identity Cloud admin UI, select Identities > Manage > Alpha realm - Assignments > assignment.
-
In the Details tab > Delete Alpha realm - Assignment section, click Delete Alpha realm - Assignment.
-
A confirmation dialog displays. Click Delete.
-
Effective roles and effective assignments
Effective roles and effective assignments are virtual properties of a user object. IDM uses the relationships between objects to know when to recalculate the values of these properties.
The relationships between objects are configured using the notify
, notifySelf
, and notifyRelationships
settings for managed/realm-name_user
, managed/realm-name_role
, and managed/realm-name_assignment
. The queryConfig
property is used to configure which related objects to traverse for this calculation.
Calculation or recalculation is performed when IDM notifies the related objects that the roles or assignments for a managed user have been added, removed, or changed.
The following excerpt of the IDM managed object schema shows how these two virtual properties are constructed for each managed user object:
"effectiveRoles" : {
"type" : "array",
"title" : "Effective Roles",
"description" : "Effective Roles",
"viewable" : false,
"returnByDefault" : true,
"isVirtual" : true,
"queryConfig" : {
"referencedRelationshipFields" : ["roles"]
},
"usageDescription" : "",
"isPersonal" : false,
"items" : {
"type" : "object",
"title" : "Effective Roles Items"
}
},
"effectiveAssignments" : {
"type" : "array",
"title" : "Effective Assignments",
"description" : "Effective Assignments",
"viewable" : false,
"returnByDefault" : true,
"isVirtual" : true,
"queryConfig" : {
"referencedRelationshipFields" : ["roles", "assignments"],
"referencedObjectFields" : ["*"]
},
"usageDescription" : "",
"isPersonal" : false,
"items" : {
"type" : "object",
"title" : "Effective Assignments Items"
}
}
When a user references a role which references an assignment, that user automatically references the assignment in its list of effective assignments.
effectiveRoles
uses the roles
relationship to calculate the grants currently in effect, including any qualified by temporal constraints.
effectiveAssignments
uses the roles
relationship and the assignments
relationship for each role to calculate the current assignments in effect for that user. The synchronization engine reads the calculated value of the effectiveAssignments
attribute when it processes the user. The target system is updated according to the configured assignmentOperation
for each assignment.
When a user’s roles or assignments are updated, IDM calculates their effectiveRoles
and effectiveAssignments
based on the current value of their roles
property and the assignments
property of any roles referenced by that property. The previous set of examples showed the creation of a role employee
that referenced an assignment employee
and was granted to user bjensen. Querying that user entry would show the following effective roles and effective assignments:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user/<bjensenUUID>?_fields=userName,roles,effectiveRoles,effectiveAssignments" { "_id": "ca8855fd-a404-42c7-88b7-02f8a8a825b2", "_rev": "0000000081eebe1a", "userName": "bjensen", "effectiveRoles": [ { "_refResourceCollection": "managed/realm-name_role", "_refResourceId": "2243f5f8-ed75-4c3b-b4b3-058d5c58fbb4" "_ref": "managed/realm-name_role/2243f5f8-ed75-4c3b-b4b3-058d5c58fbb4" } ], "effectiveAssignments": [ { "name": "employee", "description": "Assignment for employees.", "mapping": "managedUser_systemLdapAccounts", "attributes": [ { "assignmentOperation": "mergeWithTarget", "name": "employeeType", "unassignmentOperation": "removeFromTarget", "value": [ "employee" ] } ], "_rev": "0000000087d5a9a5", "_id": "46befacf-a7ad-4633-864d-d93abfa561e9" "_refResourceCollection": "managed/realm-name_assignment", "_refResourceId": "46befacf-a7ad-4633-864d-d93abfa561e9", "_ref": "managed/realm-name_assignment/46befacf-a7ad-4633-864d-d93abfa561e9" } ], "roles": [ { "_ref": "managed/realm-name_role/2243f5f8-ed75-4c3b-b4b3-058d5c58fbb4", "_refResourceCollection": "managed/realm-name_role", "_refResourceId": "2243f5f8-ed75-4c3b-b4b3-058d5c58fbb4", "_refProperties": { "_id": "93552530-10fa-49a4-865f-c942dffd2801", "_rev": "0000000081ed9f2b" } } ] }
In this example, synchronizing the managed/realm-name_user
repository with the external LDAP system defined in the mapping populates user bjensen’s employeeType
attribute in LDAP with the value employee
.
Roles and relationship change notification
Before you read this section, see Configure relationship change notification to understand the notify
and notifyRelationships
properties, and how change notification works for relationships in general. In the case of roles, the change notification configuration exists to ensure that managed users are notified when any of the relationships that link users, roles, and assignments are manipulated (that is, created, updated, or deleted).
Consider the situation where a user has role R
. A new assignment A
is created that references role R
. Ultimately, we want to notify all users that have role R
so that their reconciliation state will reflect any attributes in the new assignment A
. We achieve this notification with the following configuration:
In the managed object schema, the assignment
object definition has a roles
property that includes a resourceCollection
. The path
of this resource collection is managed/realm-name_role
and "notify" : true
for the resource collection:
{
"name" : "assignment",
"schema" : {
...
"properties" : {
...
"roles" : {
...
"items" : {
...
"resourceCollection" : [
{
"notify" : true,
"path" : "managed/realm-name_role",
"label" : "Role",
"query" : {
"queryFilter" : "true",
"fields" : [
"name"
]
}
}
...
}
With this configuration, when assignment A
is created, with a reference to role R
, role R
is notified of the change. However, we still need to propagate that notification to any users
who are members
of role R
. To do this, we configure the role
object as follows:
{
"name" : "role",
"schema" : {
...
"properties" : {
...
"assignments" : {
...
"notifyRelationships" : ["members"]
}
...
}
When role R
is notified of the creation of a new relationship to assignment A
, the notification is propagated through the assignments
property. Because "notifyRelationships" : ["members"]
is set on the assignments
property, the notification is propagated across role R
to all members of role R
.
Map external groups to internal authz roles
A user’s access to Advanced Identity Cloud is based on one or more authorization roles. Authorization roles are cumulative, and are calculated for a user in the following order:
-
Roles set specifically in the user’s
userRoles
property -
Group roles — based on group membership in an external system
Group roles are controlled with the following properties in the authentication configuration:
-
groupMembership
: the property on the external system that represents group membership. In a DS directory server, that property isldapGroups
by default. In an Active Directory server, the property ismemberOf
by default. For example:"groupMembership" : "ldapGroups"
jsonThe value of the groupMembership
property must be the ICF property name defined in the provisioner file, rather than the property name on the external system. For more information on the attributes in connectors, refer to Connector objects and properties. -
groupRoleMapping
: a mapping between an IDM role and a group on the external system. Setting this property ensures that if a user authenticates through pass-through authentication, they are given specific IDM roles depending on their membership in groups on the external system. In the following example, users who are members of the groupcn=admins,ou=Groups,dc=example,dc=com
are given the internalopenidm-admin
role when they authenticate:"groupRoleMapping" : { "internal/role/openidm-admin" : ["cn=admins,ou=Groups,dc=example,dc=com"] }
json -
groupComparisonMethod
: the method used to check whether the authenticated user’s group membership matches one of the groups mapped to an IDM role (in thegroupRoleMapping
property).The
groupComparisonMethod
can be one of the following:-
equals
: a case-sensitive equality check -
caseInsensitive
: a case-insensitive equality check -
ldap
: a case-insensitive and whitespace-insensitive equality check. Because LDAP directories do not take case or whitespace into account in group DNs, you must set thegroupComparisonMethod
if you are using pass-through authentication with an LDAP directory.
-
-
To control access to external systems, use provisioning roles and assignments, as described in Use assignments to provision users. |
Groups
Groups may not be enabled in your tenant. To check if groups are enabled, from the Advanced Identity Cloud admin UI, go to Identities > Manage. If Alpha realm - Groups is present, then groups are enabled. If this is not present, enable groups using the Feature enablement endpoint. If you previously used AM static groups, submit a Ping Identity Support ticket for guidance on how to migrate group membership to managed groups. |
Groups are an important tool for identity management because they simplify managing collections of users by applying permissions and authorizations to all members of a group rather than to individual users. Groups may follow an organization structure or be based on the needs and privileges of an arbitrary set of users.
The managed group object is a default managed object type and is defined like any other managed object type. Managed groups simplify management by using common groups across the entire platform.
Users are made members of groups through the relationships mechanism. You should understand how relationships work before you read about IDM groups.
A group can be assigned to a user manually, as a static value of the user’s groups
attribute, or dynamically, as a result of a condition or script. For example, a user might be assigned to a group such as sales
dynamically, if that user is in the sales
organization.
A user’s groups
attribute takes an array of references as a value, where the references point to the managed groups. For example, if user bjensen has been assigned to two groups (employees
and supervisors
), the value of bjensen’s groups
attribute would look something like the following:
"groups": [
{
"_ref": "managed/realm-name_group/employees",
"_refResourceCollection": "managed/realm-name_group",
"_refResourceId": "employees",
"_refProperties": {
"_id": "38a23ddc-1345-48d6-b753-ad97f472a90e",
"_rev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-1692"
}
},
{
"_ref": "managed/realm-name_group/supervisors",
"_refResourceCollection": "managed/realm-name_group",
"_refResourceId": "supervisors",
"_refProperties": {
"_id": "0fabd212-f0c2-4d91-91f2-2b211bb58e89",
"_rev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-1974"
}
}
]
We recommend you use managed objects for all data management in Advanced Identity Cloud. While managed groups display in the AM admin UI and can serve the same function as a static group created in AM, they are not the same. A managed group supports dynamic, conditional membership you can leverage in other parts of Advanced Identity Cloud. |
The _refResourceCollection
is the container that holds the group. The _refResourceId
is the ID of the group. The _ref
property is a resource path derived from the _refResourceCollection
and the URL-encoded _refResourceId
. _refProperties
provides more information about the relationship.
In most cases, Advanced Identity Cloud uses UUIDs as the |
Manage groups
You can manage groups over REST or by using the Advanced Identity Cloud admin UI.
You can perform the following actions with groups:
Create a group
You can create groups using REST or by using the Advanced Identity Cloud admin UI.
Using REST
To create a group, send a PUT or POST request to the /openidm/managed/realm-name_group
context path. The following example creates a group named employees
, with ID employees
:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request POST \ --data '{ "name": "employees", "description": "Group that includes temporary and permanent employees" }' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_group?_action=create" { "_id": "employees", "_rev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-1028", "name": "employees", "condition": null, "description": "Group that includes temporary and permanent employees" }
You can also omit ?_action=create
and achieve the same result:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request POST \ --data '{ "name": "employees2", "description": "Second group that includes temporary and permanent employees" }' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_group" { "_id": "employees2", "_rev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-1053", "name": "employees2", "condition": null, "description": "Second group that includes temporary and permanent employees" }
Using the Advanced Identity Cloud admin UI
-
From the navigation bar, click Identities > Manage > Alpha realm - Groups.
-
On the Groups page, click New Alpha realm - Group.
-
On the New Alpha realm - Group page, enter a name and description, and click Next.
-
Optionally, create a conditional filter to assign the group dynamically. Conditional filters are custom rules you create that, when met, assign the user to your group automatically.
-
Click Save.
List groups
Using REST
To list groups over REST, query the openidm/managed/realm-name_group
endpoint. The following example shows the employees
group that you created in the previous example:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_group?_queryFilter=true" { "result": [ { "_id": "employees", "_rev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-1028", "name": "employees", "condition": null, "description": "Group that includes temporary and permanent employees" }, { "_id": "employees2", "_rev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-1053", "name": "employees2", "condition": null, "description": "Second group that includes temporary and permanent employees" } ], "resultCount": 2, "pagedResultsCookie": null, "totalPagedResultsPolicy": "NONE", "totalPagedResults": -1, "remainingPagedResults": -1 }
Add users to a group
You add users to a group through the relationship mechanism. Relationships are references from one managed object to another; in this case, from a user object to a group object. For more information, refer to Relationships between objects.
You can add group members statically (manually) or dynamically (automated assigning through rules).
To add members statically, do one of the following:
-
Update the value of the user’s
groups
property to reference the group. -
Update the value of the group’s
members
property to reference the user.
Dynamic groups use the result of a condition or script to update a user’s list of groups.
Add group members statically
Add a user to a group statically using the REST interface or the Advanced Identity Cloud admin UI.
Using REST
Use one of the following methods to add group members over REST:
-
Add the user as a group member. The following example adds user scarter as a member of the
employees
group:curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request POST \ --data '{ "_ref":"managed/realm-name_user/d5b52064-6571-488a-8d85-440a99ed00d4" }' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_group/employees/members?_action=create" { "_id": "7ab79f9b-70cc-4205-acec-e675a55c9bcf", "_rev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-1479", "_ref": "managed/realm-name_user/d5b52064-6571-488a-8d85-440a99ed00d4", "_refResourceCollection": "managed/realm-name_user", "_refResourceId": "d5b52064-6571-488a-8d85-440a99ed00d4", "_refProperties": { "_id": "7ab79f9b-70cc-4205-acec-e675a55c9bcf", "_rev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-1479" } }
This is the preferred method as it does not incur an unnecessary performance cost for groups with many members. -
Update the user’s
groups
property.The following example adds the
employees
group to user scarter:curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request PATCH \ --data '[ { "operation": "add", "field": "/groups/-", "value": {"_ref" : "managed/realm-name_group/employees2"} } ]' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user/d5b52064-6571-488a-8d85-440a99ed00d4" { "_id": "d5b52064-6571-488a-8d85-440a99ed00d4", "_rev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-1569", "country": null, "telephoneNumber": null, "mail": "scarter@example.com", "memberOfOrgIDs": [], "city": null, "displayName": null, "assignedDashboard": [], "effectiveAssignments": [], "postalCode": null, "description": null, "profileImage": null, "expireAccount": null, "accountStatus": "active", "aliasList": [], "kbaInfo": [], "inactiveDate": null, "activeDate": null, "consentedMappings": [], "sn": "Carter", "effectiveGroups": [ { "_refResourceCollection": "managed/realm-name_group", "_refResourceId": "employees", "_ref": "managed/realm-name_group/employees" }, { "_refResourceCollection": "managed/realm-name_group", "_refResourceId": "employees2", "_ref": "managed/realm-name_group/employees2" } ], "preferences": null, "organizationName": null, "givenName": "Sam", "stateProvince": null, "userName": "scarter", "postalAddress": null, "effectiveRoles": [], "activateAccount": null }
When you update a user’s existing groups array, use the
-
special index to add the new value to the set. For more information, refer to Set semantic arrays in Patch. -
Update the group’s
members
property to refer to the user.The following sample command makes scarter a member of the
employees
group:curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request PATCH \ --data '[ { "operation": "add", "field": "/members/-", "value": {"_ref" : "managed/realm-name_user/d5b52064-6571-488a-8d85-440a99ed00d4"} } ]' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_group/employees" { "_id": "employees", "_rev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-1028", "name": "employees", "condition": null, "description": "Group that includes temporary and permanent employees" }
The
members
property of a group is not returned by default in the output. To show all members of a group, you must specifically request themembers
property. The following example lists the members of theemployees
group:curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_group/employees?_fields=name,members" { "_id": "employees", "_rev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-1028", "name": "employees", "members": [ { "_ref": "managed/realm-name_user/d5b52064-6571-488a-8d85-440a99ed00d4", "_refResourceCollection": "managed/realm-name_user", "_refResourceId": "d5b52064-6571-488a-8d85-440a99ed00d4", "_refProperties": { "_id": "38a23ddc-1345-48d6-b753-ad97f472a90e", "_rev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-1692" } } ] }
Using the Advanced Identity Cloud admin UI
Use one of the following UI methods to add members to a group:
-
Update the user entry:
-
Select Identities > Manage > Alpha realm - Users and select the user to add.
-
Select the Group tab and click Add Groups.
-
Select the group from the Groups list and click Save.
-
-
-
Update the group entry:
-
Select Identities > Manage > Alpha realm - Groups and select the group to which you want to add members.
-
Select the Members tab and click Add Members.
-
Select the user from the Members list and click Save.
-
Add group members dynamically
To add a member to a group dynamically, use a condition, expressed as a query filter, in the group definition. If the condition is true
for a member, they are added to the group.
A conditional group is a group whose members are based on a defined condition, which you can specify when you create or modify a group. You can create a condition after you create the group as well.
You must configure the properties you use to create a conditional filter for a group as searchable . To configure a property as searchable , update its definition in your managed object configuration. You can find more information in General purpose extension attributes.
|
When you create or update a conditional group, Advanced Identity Cloud performs the following actions:
-
Assesses all managed users
-
Recalculates the value of the user’s
group
property. This only takes place if the user is a member of the group. -
If you remove a condition from a group and members in the group are now not a part of the condition, all members are removed from the group and their
group
property is updated.
When you define a conditional group in a data set, every user entry (including the mapped entries on remote systems) updates with the relationships implied by that conditional group. The time that it takes to create a new conditional group is impacted by the number of managed users affected by the condition. In a data set with a large number of users, creating a new conditional group can incur a significant performance cost when you create it. If possible, set up your conditional groups at the beginning of your deployment to avoid performance issues later. |
Using REST
To create a conditional group over REST, include the query filter as a value of the condition
property in the group definition. The following example creates a group, fr-employees
, whose members will be only users who live in France (whose country
property is set to FR
):
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request POST \ --data '{ "name": "fr-employees", "description": "Group for employees resident in France", "condition": "/country eq \"FR\"" }' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_group?_action=create" { "_id": "fr-employees", "_rev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-1898", "name": "fr-employees", "condition": "/country eq \"FR\"", "description": "Group for employees resident in France" }
Query a user’s group memberships
To list a user’s groups, query their groups
property.
Using REST
The following example shows that scarter is a member of two groups — the employees
group and the supervisors
group:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user/d5b52064-6571-488a-8d85-440a99ed00d4/groups?_queryFilter=true&_fields=_ref/*,name" { "result": [ { "_id": "38a23ddc-1345-48d6-b753-ad97f472a90e", "_rev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-1692", "_refResourceCollection": "managed/realm-name_group", "_refResourceId": "employees", "_refResourceRev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-1028", "name": "employees", "_ref": "managed/realm-name_group/employees", "_refProperties": { "_id": "38a23ddc-1345-48d6-b753-ad97f472a90e", "_rev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-1692" } }, { "_id": "0fabd212-f0c2-4d91-91f2-2b211bb58e89", "_rev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-1974", "_refResourceCollection": "managed/realm-name_group", "_refResourceId": "supervisors", "_refResourceRev": "ae6e63c4-94f5-463b-8fbef-7a359b8e3004-1965", "name": "supervisors", "_ref": "managed/realm-name_group/supervisors", "_refProperties": { "_id": "0fabd212-f0c2-4d91-91f2-2b211bb58e89", "_rev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-1974" } } ], "resultCount": 2, "pagedResultsCookie": null, "totalPagedResultsPolicy": "NONE", "totalPagedResults": -1, "remainingPagedResults": -1 }
Remove a member from a group
To remove a static group membership from a user entry, do one of the following:
-
Update the value of the user’s
groups
property to remove the reference to the role. -
Update the value of the group’s
members
property to remove the reference to that user.
You can use both of these methods over REST or by using the Advanced Identity Cloud admin UI.
A delegated administrator must use PATCH to add or remove relationships. Conditional group membership can only be removed when the condition is changed or removed, or when the group itself is deleted. |
Using REST
Use one of the following methods to remove a member from a group:
-
DELETE the group from the user’s
groups
property, including the reference ID (the ID of the relationship between the user and the group) in the delete request.The following example removes the
employees
group from user scarter. The ID required in the DELETE request is not the ID of the group but the reference_id
of the relationship:curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request DELETE \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user/d5b52064-6571-488a-8d85-440a99ed00d4/groups/e450a32c-e289-49e3-8de5-b0f84e07c740" { "_id": "e450a32c-e289-49e3-8de5-b0f84e07c740", "_rev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-2122", "_ref": "managed/realm-name_group/employees", "_refResourceCollection": "managed/realm-name_group", "_refResourceId": "employees", "_refProperties": { "_id": "e450a32c-e289-49e3-8de5-b0f84e07c740", "_rev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-2122" } }
-
PATCH the user entry to remove the group from the array of groups, specifying the value of the group object in the JSON payload.
When you remove a group in this way, you must include the entire object in the value, as shown in the following example:
curl \ --header "Content-type: application/json" \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request PATCH \ --data '[ { "operation" : "remove", "field" : "/groups", "value" : { "_ref": "managed/realm-name_group/employees", "_refResourceCollection": "managed/realm-name_group", "_refResourceId": "employees", "_refProperties": { "_id": "731120c0-a4e9-4e27-b201-7442169e8b7c", "_rev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-2218" } } } ]' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user/d5b52064-6571-488a-8d85-440a99ed00d4" { "_id": "d5b52064-6571-488a-8d85-440a99ed00d4", "_rev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-2387", "country": null, "telephoneNumber": null, "mail": "scarter@example.com", "memberOfOrgIDs": [], "city": null, "displayName": null, "assignedDashboard": [], "effectiveAssignments": [], "postalCode": null, "description": null, "profileImage": null, "expireAccount": null, "accountStatus": "active", "aliasList": [], "kbaInfo": [], "inactiveDate": null, "activeDate": null, "consentedMappings": [], "sn": "Carter", "effectiveGroups": [ { "_refResourceCollection": "managed/realm-name_group", "_refResourceId": "supervisors", "_ref": "managed/realm-name_group/supervisors" } ], "preferences": null, "organizationName": null, "givenName": "Sam", "stateProvince": null, "userName": "scarter", "postalAddress": null, "effectiveRoles": [], "activateAccount": null }
-
DELETE the user from the group’s
members
property, including the reference ID (the ID of the relationship between the user and the role) in the delete request.The following example first queries the members of the
employees
group, to obtain the ID of the relationship, then removes scarter’s membership from that group:curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_group/employees/members?_queryFilter=true&_fields=_ref/*,name" { "result": [ { "_id": "ef3261cd-a66f-4d3e-aad8-c0850e0b4a0e", "_rev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-2430", "_refResourceCollection": "managed/realm-name_user", "_refResourceId": "d5b52064-6571-488a-8d85-440a99ed00d4", "_refResourceRev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-2432", "_ref": "managed/realm-name_user/d5b52064-6571-488a-8d85-440a99ed00d4", "_refProperties": { "_id": "ef3261cd-a66f-4d3e-aad8-c0850e0b4a0e", "_rev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-2430" } } ], "resultCount": 1, "pagedResultsCookie": null, "totalPagedResultsPolicy": "NONE", "totalPagedResults": -1, "remainingPagedResults": -1 } curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request DELETE \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_group/employees/members/ef3261cd-a66f-4d3e-aad8-c0850e0b4a0e" { "_id": "ef3261cd-a66f-4d3e-aad8-c0850e0b4a0e", "_rev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-2430", "_ref": "managed/realm-name_user/d5b52064-6571-488a-8d85-440a99ed00d4", "_refResourceCollection": "managed/realm-name_user", "_refResourceId": "d5b52064-6571-488a-8d85-440a99ed00d4", "_refProperties": { "_id": "ef3261cd-a66f-4d3e-aad8-c0850e0b4a0e", "_rev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-2430" } }
Using the Advanced Identity Cloud admin UI
Use one of the following methods to remove a group member:
-
Select Identities > Manage > Users and select the user whose group or groups you want to remove.
Select the Group tab, select the group you want to remove, then select Remove.
-
Select Identities > Manage > Groups, and select the group whose members you want to remove.
Select the Members tab, select the member or members you want to remove, then select Remove.
Delete a group
Deleting a group removes all users in the group. This action cannot be undone. |
Using REST
To delete a group over the REST interface, simply delete that managed object. The following command deletes the employees
group created in the previous section:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request DELETE \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_group/employees" { "_id": "employees", "_rev": "ae6e63c4-94f5-463b-8bef-7a359b8e3004-1028", "name": "employees", "condition": null, "description": "Group that includes temporary and permanent employees" }
Organizations
Organization objects let you arrange and manage users in hierarchical trees. Organizations also allow you to give users fine-grained administrative privileges to various parts of the tree based on their location in that tree. For example, an administrator of one organization might have full access to the users within that organization but no access to the users in an adjacent organization.
IDM comes with two types of managed objects for organizations: Alpha realm organizations and Bravo realm organizations. The default schemas for these two organization types are similar, except that Alpha realm organizations have relationships with Alpha realm users, while Bravo realm organizations have relationships with Bravo realm users. You can modify the default schemas of either of these managed object types; refer to Define managed object schema for more information.
The Alpha and Bravo organization object types have array attributes called admins
, owners
, and members
. These attribute enable the hierarchical organization model.
Users and organizations have a set of relationship-derived virtual properties used by the delegated administration filters to provide the visibility and access constraints that underpin the organization model. Users have the ids
of all the organizations of which they are members, and organizations have the ids
of all their admin and owner users.
Only IDM administrative users can create top-level organizations. Within organizations, there are various levels of privileges, depending on how a user is related to the organization.
Refer to the organization use case for an example that illustrates organization concepts, including:
-
Organizations in the Alpha and Bravo realms
-
Hierarchies of organizations
-
Organization owners
-
Organization administrators
Manage organizations over REST
IDM provides RESTful access to managed organizations, at the context path /openidm/managed/realm-name_organization
.
You can add, change, and delete organizations by using the IDM admin UI or over the REST interface.
To use the IDM admin UI, select Manage > Organization.
The examples on this page show how to add, query, modify, and delete organizations over the REST interface. For a reference of all managed organization endpoints and actions, refer to Managed organizations.
Add and modify organizations
The examples in this section create the example-org
organization and add admins and members to the organization.
In this organization, users bjensen and scarter can create and delete child organizations, also known as suborganizations, of example-org
, and can create and delete members within the child organizations:

Add a top level organization to IDM.
Only IDM tenant administrators can create top level organizations.
curl \ --header "Authorization: Bearer <token>" \ --header "Content-Type: application/json" \ --header "Accept-API-Version: resource=1.0" \ --header "If-None-Match: *" \ --request PUT \ --data '{ "name": "example-org" }' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_organization/example-org" { "_id": "example-org", "name": "example-org" ... }
Make a user the organization’s owner.
Advanced Identity Cloud tenant administrators can designate organizations' owners.
In this example, the tenant administrator makes bjensen the owner of the example-org
organization created previously.
The example assumes the user bjensen already exists:
curl \ --header "Authorization: Bearer <token>" \ --header "Content-Type: application/json" \ --header "Accept-API-Version: resource=1.0" \ --request POST \ --data '{ "_ref":"managed/realm-name_user/<bjensenUUID>" }' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_organization/example-org/owners?_action=create"
Add a member to the organization.
Organization owners can create members in the organizations that they own.
In this example, bjensen creates user scarter.
bjensen also makes scarter a member of the example-org
organization:
curl \ --header "Authorization: Bearer <token>" \ --header "Content-Type: application/json" \ --header "Accept-API-Version: resource=1.0" \ --request POST \ --data '{ "userName": "scarter", "sn": "Carter", "givenName": "Steven", "mail": "scarter@example.com", "password": "Th3Password!", "memberOfOrg": [{"_ref": "managed/realm-name_organization/example-org"}] }' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_action=create" { ... "mail":"scarter@example.com", "memberOfOrgIDs":["example-org"], ... }
Make one of the organization’s members an admin.
Organization owners can designate admins for the organizations they own.
An organization admin must be a member of the organization.
In this example, bjensen makes scarter an admin of the example-org
organization:
curl \ --header "Authorization: Bearer <token>" \ --header 'Content-Type: application/json' \ --header "Accept-API-Version: resource=1.0" \ --request PATCH \ --data '[ { "operation": "add", "field": "/admins/-", "value": { "_ref": "managed/realm-name_user/<scarterUUID>" } } ]' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_organization/example-org" { "_id": "example-org", ... "name": "example-org" }
Add a member to the organization.
Organization admins can add members to the organizations they administer.
In this example, the organization admin, scarter, creates a new member, jsanchez.
scarter also makes jsanchez a member of the example-org
organization:
curl \ --header "Authorization: Bearer <token>" \ --header "Content-Type: application/json" \ --header "Accept-API-Version: resource=1.0" \ --request POST \ --data '{ "userName": "jsanchez", "sn": "Sanchez", "givenName": "Juanita", "mail": "jsanchez@example.com", "password": "Th3Password!", "memberOfOrg": [{"_ref": "managed/realm-name_organization/example-org"}] }' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_action=create" { ... "mail":"jsanchez@example.com", "memberOfOrgIDs":["example-org"], ... }
Create a child organization.
Organization owners and admins can create and manage child organizations of the organizations they own or administer.
In this example, the organization owner, bjensen, creates a new organization named example-child-org
, and makes it a child organization of the example-org
organization:
curl \ --header "Authorization: Bearer <token>" \ --header "Content-Type: application/json" \ --header "Accept-API-Version: resource=1.0" \ --header "If-None-Match: *" \ --request POST \ --data '{ "name": "example-child-org", "parent": {"_ref": "managed/realm-name_organization/example-org"} }' \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_organization?_action=create" { ... "parentIDs":["example-org"], ... "name":"example-child-org" }
When creating a child organization, you need to add custom attributes to the access flags for the For more information on adding and updating privileges that apply to managed organizations, refer to Server configuration. |
Query organizations
The examples in this section demonstrate several ways you can query organizations and organization membership:
List all the organizations a user owns.
This example lists the organizations bjensen owns:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user/<bjensenUUID>/ownerOfOrg?_queryFilter=true" { "result": [ { ... "_ref": "managed/realm-name_organization/example-org", "_refResourceCollection": "managed/realm-name_organization", "_refResourceId": "example-org", ... } ], ... }
List an organization’s members.
Organization owners can list the members of the organizations they own.
In this example, bjensen lists the members of the example-org
organization:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_organization/example-org/members?_queryFilter=true" { "result": [ ... ], "resultCount":1, ... }
List organizations that you own or administer, and list their child organizations.
An organization owner or admin can list the organizations that they own or administer. When a user runs the curl command in this example, it lists:
-
The organizations that the user owns or administers
-
Those organizations' child organizations
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_organization?_queryFilter=true" { "result": [ { "_id":"example-org", "parentIDs":[], "name":"example-org" }, { "_id":"<example-child-orgUUID>", "parentIDs":["example-org"], "name":"example-child-org" } "resultCount":2, ... }
List organizations of which another user is a member.
Organization owners and admins can list all the organizations they own or administer that contain a given user. In this example, scarter lists the organizations of which jsanchez is a member:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user/<jsanchezUUID>?_fields=memberOfOrg" { "_id": ... "memberOfOrg":[ { "_ref":"managed/realm-name_organization/example-org", "_refResourceCollection":"managed/realm-name_organization", "_refResourceId":"example-org", ... }
Grow organizations downward if possible
The relationship-derived virtual properties that support the organization model are calculated in response to relationship signals that travel down the organization tree hierarchy. For example, suppose you:
-
Add a new root organization to an existing organization hierarchy
-
Add a new admin or owner to the root organization in an existing organization hierarchy
The relationship signals that trigger relationship-derived virtual property calculation are propagated down to all organizations in the organization hierarchy, and to all the members of the organizations in the hierarchy. This updates their relationship-derived virtual property state.
If there are many thousands of members of the organizations in the hierarchy, such an operation can take a long time to complete. Because of this, it is a best practice to grow organization hierarchies downward, adding new organizations as leaves of an existing hierarchy, and adding new admins and members to the leaves in the hierarchy tree. This is preferable to growing the hierarchy upwards, starting with the leaves, and then growing the hierarchy up towards the root organization.
If you must add a new root to an existing organization hierarchy with many organizations and many members, or add a new admin or owner to an organization near the top of the hierarchy, perform the operations over the command line, using the examples in Manage organizations over REST.
Use policies to validate data
Advanced Identity Cloud provides a policy service that lets you apply specific validation requirements to various components and properties.
The policy service provides a REST interface for reading policy requirements and validating the properties of components against configured policies. Objects and properties are validated automatically when they are created, updated, or patched. Policies are generally applied to user passwords, but can also be applied to any managed or system object, and to internal user objects.
The policy service lets you accomplish the following tasks:
-
Read the configured policy requirements of a specific component.
-
Read the configured policy requirements of all components.
-
Validate a component object against the configured policies.
-
Validate the properties of a component against the configured policies.
The router service limits policy validation to managed and internal user objects. To apply policies to additional objects, such as the audit service, modify your project’s router configuration. For more information about the router service, refer to Script triggers defined in the router configuration.
A configurable default policy applies to all managed objects.
Apply policies to managed objects
In Advanced Identity Cloud, policies can be applied to managed objects using default policies.
You can add a policy using:
-
The IDM admin UI.
-
The policy configuration.
Be cautious when using validation policies. If a policy relates to an array of relationships Return by Default should always be set to |
The policy configuration determines which policies apply to resources other than managed objects. The default policy configuration includes policies that are applied to internal user objects, but you can extend the configuration to apply policies to system objects.
Policy configuration objects
Each element of the policy is defined in a policy configuration object. The structure of a policy configuration object is as follows:
{
"policyId": "minimum-length",
"policyExec": "minLength",
"clientValidation": true,
"validateOnlyIfPresent": true,
"policyRequirements": ["MIN_LENGTH"]
}
|
A unique ID that enables the policy to be referenced by component objects. |
|
The name of the function that contains the policy implementation. For more information, refer to Policy Implementation Functions. |
|
Indicates whether the policy decision can be made on the client. When |
|
Notes that the policy is to be validated only if the field within the object being validated exists. |
|
An array containing the policy requirement ID of each requirement that is associated with the policy. Typically, a policy will validate only one requirement, but it can validate more than one. |
Policy reference
You can apply policies defined by Advanced Identity Cloud to any managed or internal object.
Advanced Identity Cloud includes the following default policies and parameters:
Policy Id | Parameters | |
---|---|---|
The property is required; not optional. |
||
The property can’t be empty. |
||
The property can’t be null. |
||
The property must be unique. |
||
Tests for uniqueness and internal user conflicts. |
||
Tests for internal user conflicts. |
||
Matches a regular expression. |
|
The regular expression pattern. |
Tests for a valid query filter. |
||
Tests for valid array items. |
||
Tests for a valid date. |
||
Tests for a valid date format. |
||
Tests for a valid time. |
||
Tests for a valid date and time. |
||
Tests for a valid duration format. |
||
Tests for a valid email address. |
||
Tests for a valid name format. |
||
Tests for a valid phone number format. |
||
The property must contain the minimum specified number of capital letters. |
|
Minimum number of capital letters. |
The property must contain the minimum specified number of numbers. |
|
Minimum number of numbers. |
Tests for a valid number. |
||
The property value must be greater than the |
|
The minimum value. |
The property value must be less than the |
|
The maximum value. |
The property’s minimum string length. |
|
The minimum string length. |
The property’s maximum string length. |
|
The maximum string length. |
The property cannot contain values of the specified fields. |
|
A comma-separated list of the fields to check against. For example, the default managed user password policy specifies |
The property cannot contain the specified characters. |
|
A comma-separated list of disallowed characters. For example, the default managed user |
The property cannot contain duplicate characters. |
||
A sync mapping must exist for the property. |
||
Tests for valid permissions. |
||
Tests for valid access flags. |
||
Tests for a valid privilege path. |
||
Tests for valid temporal constraints. |
Policy configuration element
Properties defined in the managed object configuration can include a policies
element that specifies how policy validation should be applied to that property. The following excerpt of the default managed object configuration shows how policy validation is applied to the id
property of a managed/realm-name_user object.
You can only declare policies on top-level managed object attributes. Nested attributes (those within an array or object) cannot have policies declared on them. |
{
"name" : "user",
"schema" : {
"id" : "http://jsonschema.net",
"properties" : {
"_id" : {
"description" : "User ID",
"type" : "string",
"viewable" : false,
"searchable" : false,
"userEditable" : false,
"usageDescription" : "",
"isPersonal" : false,
"policies" : [
{
"policyId" : "cannot-contain-characters",
"params" : {
"forbiddenChars" : [
"/"
]
}
}
]
},
"password" : {
"title" : "Password",
"description" : "Password",
"type" : "string",
"viewable" : false,
"searchable" : false,
"userEditable" : true,
"encryption" : {
"purpose" : "idm.password.encryption"
},
"scope" : "private",
"isProtected": true,
"usageDescription" : "",
"isPersonal" : false
}
}
}
}
The policy for the _id
property references the function cannot-contain-characters
. This is a default policy that you can apply.
Validate managed object data types
The type
property of a managed object specifies the data type of that property; for example, array
, boolean
, number
, null
, object
, or string
. For more information about data types, refer to the JSON Schema Primitive Types section of the JSON Schema standard.
The type
property is subject to policy validation when a managed object is created or updated. Validation fails if data does not match the specified type
, such as when the data is an array
instead of a string
. The default valid-type
policy enforces the match between property values and the type
defined in the managed object configuration.
Advanced Identity Cloud supports multiple valid property types. For example, you might have a scenario where a managed user can have more than one telephone number, or a null telephone number (when the user entry is first created and the telephone number is not yet known). In such a case, you could specify the accepted property type as follows in your managed object configuration:
"telephoneNumber" : {
"type" : "string",
"title" : "Telephone Number",
"description" : "Telephone Number",
"viewable" : true,
"userEditable" : true,
"pattern" : "^\\+?([0-9\\- \\(\\)])*$",
"usageDescription" : "",
"isPersonal" : true,
"policies" : [
{
"policyId" : "minimum-length",
"params" : {
"minLength" : 1
}
},
{
"policyId": "maximum-length",
"params": {
"maxLength": 255
}
}
]
}
In this case, the type is defined in the policy configuration. The policy
checks the telephone number for an accepted type
and pattern
, either for a real telephone number or a null
entry.
Configure policy validation using the admin UI
To configure policy validation for a managed object type using the UI, update the configuration of the object type:
-
From the Advanced Identity Cloud admin UI, click Native Consoles > Identity Management.
-
From the navigation bar, click Configure > Managed Objects.
-
On the Managed Objects page, edit or create a managed object.
-
On the Managed Object NAME page, do one of the following:
-
To edit an existing property, click the property.
-
To create a property, click Add a Property, enter the required information, and click Save.
-
Click the property.
-
-
-
From the Validation tab, click Add Policy.
-
In the Add/Edit Policy window, enter information in the following fields, and click Add or Save:
- Policy Id
-
Refers to the unique
PolicyId
.For a list of the default policies, refer to the Policy Reference.
- Parameter Name
-
Refers to the parameters for the
PolicyId
. For a list of the default policy parameters, refer to the Policy Reference. - Value
-
The parameter’s value to validate.
Show Me

Add conditional policy definitions
You can extend the policy service to support policies that are applied only under specific conditions. To apply a conditional policy to managed objects, add the policy to your project’s managed object configuration. To apply a conditional policy to other objects, add it to your project’s policy configuration.
The following managed object configuration shows a sample conditional policy for the password
property of managed user objects. The policy indicates that sys-admin
users have a more lenient password policy than regular employees:
{
"objects" : [
{
"name" : "user",
...
"properties" : {
...
"password" : {
"title" : "Password",
"type" : "string",
...
"conditionalPolicies" : [
{
"condition" : {
"type" : "text/javascript",
"source" : "(fullObject.org === 'sys-admin')"
},
"dependencies" : [ "org" ],
"policies" : [
{
"policyId" : "at-least-X-numbers",
"params" : {
"numNums" : ["1"]
}
}
]
},
{
"condition" : {
"type" : "text/javascript",
"source" : "(fullObject.org === 'employees')"
},
"dependencies" : [ "org" ],
"policies" : [
{
"policyId" : "at-least-X-numbers",
"params" : {
"numNums" : ["2"]
}
}
]
}
],
"fallbackPolicies" : [
{
"policyId" : "at-least-X-numbers",
"params" : {
"numNums" : ["1"]
}
}
]
}
...
}
There are two distinct scripted conditions (defined in the condition
elements). The first condition asserts that the user object, contained in the fullObject
argument, is a member of the sys-admin
org. If that assertion is true, the at-least-X-numbers
policy is applied to the password
attribute of the user object, and minimum numbers is set to 1
.
The second condition asserts that the user object is a member of the employees
org. If that assertion is true, the at-least-X-numbers
policy is applied to the password
attribute of the user object, and the minimum numbers is 2
.
In the event that neither condition is met (the user object is not a member of the sys-admin
org or the employees
org), an optional fallback policy can be applied. In this example, the fallback policy also references the at-least-X-numbers
policy and specifies that for such users, the minimum numbers is 1
.
The dependencies
field prevents the condition scripts from being run at all, if the user object does not include an org
attribute.
Scripted conditions do not apply to progressive profiling. |
Manage policies over REST
Manage policies over REST through the policy configuration.
List the defined policies
The following REST call displays a list of all the policies defined (policies for objects other than managed objects). The policy objects are returned in JSON format, with one object for each defined policy ID:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/policy" { "_id": "", "resources": [ ... { "resource": "internal/user/*", "properties": [ { "name": "_id", "policies": [ { "policyId": "cannot-contain-characters", "params": { "forbiddenChars": [ "/" ] }, "policyFunction": "\nfunction (fullObject, value, params, property) {\n ...", "policyRequirements": [ "CANNOT_CONTAIN_CHARACTERS" ] } ], "policyRequirements": [ "CANNOT_CONTAIN_CHARACTERS" ] } ... ] ... } ] }
To display the policies that apply to a specific resource, include the resource name in the URL. For example, the following REST call displays the policies that apply to managed users:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/policy/managed/realm-name_user/*" { "_id": "*", "resource": "managed/realm-name_user/*", "properties": [ { "policyRequirements": [ "VALID_TYPE", "CANNOT_CONTAIN_CHARACTERS" ], "fallbackPolicies": null, "name": "_id", "policies": [ { "policyRequirements": [ "VALID_TYPE" ], "policyId": "valid-type", "params": { "types": [ "string" ] } }, { "policyId": "cannot-contain-characters", "params": { "forbiddenChars": [ "/" ] }, "policyFunction": "...", "policyRequirements": [ "CANNOT_CONTAIN_CHARACTERS" ] } ], "conditionalPolicies": null } ... ] }
Validate objects and properties over REST
To verify that an object adheres to the requirements of all applied policies, include the validateObject
action in the request.
The following example verifies that a new managed user object is acceptable, in terms of the policy requirements. Note that the ID in the URL (test
in this example) is ignored—the action simply validates the object in the JSON payload:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request POST \ --data '{ "sn": "Jones", "givenName": "Bob", "telephoneNumber": "0827878921", "passPhrase": null, "mail": "bjones@example.com", "accountStatus": "active", "userName": "bjones@example.com", "password": "123" }' \ "https://<tenant-env-fqdn>/openidm/policy/managed/realm-name_user/test?_action=validateObject" { "result": false, "failedPolicyRequirements": [ { "policyRequirements": [ { "policyRequirement": "MIN_LENGTH", "params": { "minLength": 8 } } ], "property": "password" }, { "policyRequirements": [ { "policyRequirement": "AT_LEAST_X_CAPITAL_LETTERS", "params": { "numCaps": 1 } } ], "property": "password" } ] }
The result (false
) indicates that the object is not valid. The unfulfilled policy requirements are provided as part of the response - in this case, the user password does not meet the validation requirements.
Use the validateProperty
action to verify that a specific property adheres to the requirements of a policy.
The following example checks whether a user’s new password (12345
) is acceptable:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request POST \ --data '{ "password": "12345" }' \ "https://<tenant-env-fqdn>/openidm/policy/managed/realm-name_user/9dce06d4-2fc1-4830-a92b-bd35c2f6bcbb?_action=validateProperty" { "result": false, "failedPolicyRequirements": [ { "policyRequirements": [ { "policyRequirement": "MIN_LENGTH", "params": { "minLength": 8 } } ], "property": "password" }, { "policyRequirements": [ { "policyRequirement": "AT_LEAST_X_CAPITAL_LETTERS", "params": { "numCaps": 1 } } ], "property": "password" } ] }
The result (false
) indicates that the password is not valid. The unfulfilled policy requirements are provided as part of the response - in this case, the minimum length and the minimum number of capital letters.
Validating a property that fulfills the policy requirements returns a true
result, for example:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request POST \ --data '{ "password": "1NewPassword" }' \ "https://<tenant-env-fqdn>/openidm/policy/managed/realm-name_user/9dce06d4-2fc1-4830-a92b-bd35c2f6bcbb?_action=validateProperty" { "result": true, "failedPolicyRequirements": [] }
Validate field removal
To validate field removal, specify the fields to remove when calling the policy validateProperty
action. You cannot remove fields that:
-
Are required in the
required
schema array. -
Have a
required
policy. -
Have a default value.
The following example validates the removal of the fields description
and givenName
:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request POST \ --data '{ "_remove": [ "description", "givenName" ] }' \ "https://<tenant-env-fqdn>/openidm/policy/managed/realm-name_user/ca5a3196-2ed3-4a76-8881-30403dee70e9?_action=validateProperty"
Because givenName
is a required field, IDM returns a failed policy validation:
{
"result": false,
"failedPolicyRequirements": [
{
"policyRequirements": [
{
"policyRequirement": "REQUIRED"
}
],
"property": "givenName"
}
]
}
Force validation of default values
IDM does not perform policy validation for default values specified in the managed objects schema. It may be necessary to force validation when validating properties for an object that does not yet exist. To force validation, include forceValidate=true
in the request URL.
Validate properties to unknown resource paths
To perform a validateProperty
action to a path that is unknown (*
), such as managed/realm-name_user/*
or managed/realm-name_user/userDoesntExistYet
, the payload must include:
-
An
object
field that contains the object details. -
A
properties
field that contains the properties to be evaluated.
Pre-registration validation example
A common use case for validating properties for unknown resources is prior to object creation, such as during pre-registration.
-
Always pass the object and properties content in the POST body because Advanced Identity Cloud has no object to look up.
-
Use any placeholder id in the request URL, as
*
has no special meaning in the API.This example uses a conditional policy for any object with the description
test1
:"givenName" : { ... "conditionalPolicies" : [ { "condition" : { "type" : "text/javascript", "source" : "(fullObject.description === 'test1')" }, "dependencies" : [ "description" ], "policies" : [ { "policyId" : "at-least-X-capitals", "params" : { "numCaps" : 1 } } ] } ],
json -
Using the above conditional policy, you could perform a
validateProperty
action tomanaged/realm-name_user/*
with the request:curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --request POST \ --data '{ "object": { "description": "test1" }, "properties": { "givenName": "passw0rd" } }' \ "https://<tenant-env-fqdn>/openidm/policy/managed/realm-name_user/*?_action=validateProperty" { "result": false, "failedPolicyRequirements": [ { "policyRequirements": [ { "params": { "numCaps": 1 }, "policyRequirement": "AT_LEAST_X_CAPITAL_LETTERS" } ], "property": "givenName" } ] }
Access data objects
Advanced Identity Cloud gives you the ability to access various data objects such as:
-
Managed objects
-
Configuration objects
-
Repository objects
You can perform various actions on these objects. Advanced Identity Cloud standardizes the objects through a uniform programming model. A uniform programming model means that all objects are queried and manipulated using the Resource API. The URL or URI that is used to identify the target object for an operation depends on the object type.
The various subsections explore the following:
-
Access data objects using scripts
-
Access data objects using REST
-
Access data objects (from one Advanced Identity Cloud tenant/IDM instance to another) via a remote proxy
-
Query data objects
Access data objects using scripts
IDM gives you the ability to access various data objects (such as managed objects, configuration objects, repository objects and so on) and perform actions (functions) through inline scripts. Advanced Identity Cloud standardizes the objects through a uniform programming model.
For more information about scripts and the objects available to scripts, refer to Scripting.
You can use the Resource API to obtain managed, system, configuration, and repository objects, as follows:
val = openidm.read("managed/realm-name_organization/mysampleorg")
val = openidm.read("system/mysystem/account")
val = openidm.read("config/custom/mylookuptable")
val = openidm.read("repo/custom/mylookuptable")
For information about constructing an object ID, refer to URI Scheme.
For information on all the actions you can take on a resource, refer to scripting functions.
Access data objects using the REST API
IDM provides access to data objects through the Advanced Identity Cloud REST API. To access objects over REST, you can use a browser-based REST client, such as the Simple REST Client for Chrome or RESTClient for Firefox. Alternatively, you can use the curl command-line utility.
Refer to the REST API for a comprehensive overview.
To obtain a managed object through the REST API, perform an HTTP GET on the corresponding URL; for example:
https://<tenant-env-fqdn>/openidm/managed/realm-name_organization/mysampleorg
Performing an HTTP GET on the corresponding URL is dependent on your security settings and authentication configuration. |
By default, the HTTP GET returns a JSON representation of the object.
In general, you can map any HTTP request to the corresponding openidm.method
call. For more information, refer to script functions.
The following example shows how the parameters provided in an openidm.query
request correspond with the key-value pairs you would include in a similar HTTP GET request. It shows the same call using the Resource API and the REST API:
-
Resource API
-
REST API
Reading an object using the Resource API:
openidm.query("managed/realm-name_user", { "_queryFilter": "true" }, ["userName","sn"])
Reading an object using the REST API:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_queryFilter=true&_fields=userName,sn"
Use a remote proxy to access data objects
You can proxy REST requests to another Advanced Identity Cloud tenant or IDM instance using the /external/idm/instanceName
endpoint via the IDM remote proxy. This lets you treat any other tenant/IDM instance as a resource within the one you are managing.
For more information on determining the exact value for instanceName , refer to How to determine the value for instanceName .
|
The remote proxy acts as a REST client to the tenant/IDM instance; therefore, typical configurations for a remote proxy to operate (DNS resolution, network connectivity, SSL, and so on) are required.
Once you set up and configure the remote proxy, you can then:
-
Use it in a sync mapping
-
Call actions on it
-
Use it within scripts
-
Use it in any other way that you might use a resource
You can call any endpoint in the remote tenant/IDM instance using this proxy.
A few situations where this feature may be useful include:
-
Syncing data in a sandbox or development tenant into the staging environment (or from staging to production).
-
Syncing changes where there are geographically diverse data centers and they need to be kept in sync with one another.
-
Syncing data between existing self-managed IDM and a tenant/IDM instance.
The proxy does not support liveSync/implicit sync from the remote Advanced Identity Cloud resources. This means you are limited to using reconciliation when it comes to pulling data from a remote system.
How to determine the value for instanceName
The instanceName
is a fragment of the external configuration’s name. You can determine the value for instanceName
using REST:
-
Get the configurations:
Requestcurl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/config/"
-
Locate the external configuration:
Return{ "_id": "", "configurations": [ ... { "_id": "emailTemplate/welcome", "pid": "emailTemplate.212e...f7a", "factoryPid": "emailTemplate" }, ... { "_id": "external.idm/name1", (1) "pid": "external.idm.29cd...f4a", "factoryPid": "external.idm" }, ... ] }
json1 In this example, the external configuration "_id": "external.idm/name1"
would be available as a remote system at theopenidm/external/idm/name1
endpoint.
Prerequisites
To connect to a remote instance over SSL, you must import the remote instance’s server certificate into your local instance’s truststore (if the cert is signed by a CA that is not already in the truststore). For further information, refer to Self-managed SSL certificates.
Authenticate to another tenant or IDM instance
The manner in which you authenticate is based on how the remote tenant/IDM instance is configured to authenticate requests:
-
Remote proxy from one tenant to another.
-
Authentication is completed via
bearer
authentication. Ensure you properly configure a client with the client credentials grant flow in the remote tenant before obtaining an access token.For the proxy to work, you must set client_secret_post
as the Token Endpoint Authentication Method (tokenEndpointAuthMethod
).
-
-
Remote proxy from a tenant to a self-managed IDM instance.
-
If you need to remote proxy from a tenant to a self-managed IDM instance (or vice versa), you authenticate by the way in which the self-managed IDM is configured.
If you connect to a self-managed IDM instance, basic authentication or bearer token authentication when IDM is configured to use rsFilter are supported.
-
basic
authentication: Use a simple username/password binding to make the request. -
bearer
authentication: Ensure you properly configure a client with the client credentials grant flow in the remote instance before obtaining an access token.For the proxy to work, you must set client_secret_post
as the Token Endpoint Authentication Method (tokenEndpointAuthMethod
).
-
-
For either method, you must ensure the user authenticating has the required authorization role(s) to perform the necessary operations. Operations depend on the actions you intend to take on the remote tenant/IDM instance.
The authentication method you use determines the available properties:
Property | Required? | Definition |
---|---|---|
|
No |
The enable state of the service. The default is |
|
No |
The requested OAuth2 scope(s). |
|
No |
The scope delimiter to use. Defaults to space. |
|
Yes |
The authentication strategy to use. Either |
|
Yes |
The URL of the remote instance to relay the request to. |
|
With |
The basic authentication user name. |
|
With |
The basic authentication password. |
|
With |
The clientId used to request an access token from the token endpoint. |
|
With |
The client secret used to request an access token from the token endpoint. |
|
With |
The OAuth2 token endpoint. |
For any request sent to the source server that includes an X-Requested-With header, the value of the header is set to RemoteIDMProxy .
|
Examples
The following subsections show examples of how to authenticate via basic
and with bearer
authentication.
Basic authentication
{
"enabled" : true,
"authType" : "basic",
"instanceUrl" : "https://localhost:8443/openidm/",
"userName" : "openidm-admin",
"password" : "openidm-admin"
}
Bearer/Oauth2 authentication
{
"enabled" : true,
"authType" : "bearer",
"instanceUrl" : "https://fr-platform.iam.example.com/openidm/",
"clientId" : "idm-provisioning",
"clientSecret" : "password",
"scope" : [ ],
"tokenEndpoint" : "https://fr-platform.iam.example.com/am/oauth2/realms/root/access_token",
"scopeDelimiter" : " "
}
REST request
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ 'https://<tenant-env-fqdn>/openidm/external/idm/platform/managed/user?_queryFilter=true' { "result": [ { "_id": "95b2b43c-621e-4bca-8a97-efc768f17751", "_rev": "00000000f20217df", "userName": "testUser", "accountStatus": "active", "givenName": "Test", "sn": "User", "mail": "testUser@test.com" } ], "resultCount": 1, "pagedResultsCookie": null, "totalPagedResultsPolicy": "NONE", "totalPagedResults": -1, "remainingPagedResults": -1 }
Use the remote proxy in a sync mapping
To use the remote proxy in a synchronization mapping, add the mapping to your mapping configuration.
For example:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --header "Content-Type: application/json" \ --data '{ "mappings": [ { "name": "onprem_user_to_fidc_alpha_user", "source": "external/idm/65/managed/user", "target": "external/idm/fidc/managed/alpha_user" } ] }' \ --request PUT \ "https://<tenant-env-fqdn>/openidm/config/sync"
To verify the changes, get the mapping configuration.
For example:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/config/sync"
Use the remote proxy in a script
Once you have created a mapping, you can manipulate the remote Advanced Identity Cloud tenant or IDM instance via scripts.
For more information, refer to script functions.
openidm.query("external/idm/fidc/managed/alpha_user", {"_queryFilter": "userName eq 'bjensen'"});
Define and call data queries
You can define and call queries using the REST or Resource API. Queries are supported on both managed and system objects, and you can define them through:
-
Common filter expressions using the
_queryFilter
keyword. -
Parameterized, or predefined queries, such as the keyword
_pageSize
.
Common filter expressions (_queryFilter
)
The Advanced Identity Cloud REST API defines common filter expressions that enable you to form arbitrary queries using a number of supported filter operations. This query capability is the standard way to query data if no predefined query exists and is supported for all managed and system objects.
Common filter expressions are useful because they do not require knowledge of how the object is stored, and they do not require additions to the repository configuration.
Common filter expressions are called with the _queryFilter
keyword. The following example uses a common filter expression to retrieve managed user objects whose user name is Smith:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ 'https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_queryFilter=userName+eq+"smith"'
The filter is URL encoded in this example. The corresponding filter using the resource API would be:
openidm.query("managed/realm-name_user", { "_queryFilter" : '/userName eq "smith"' });
Special characters in queries
JavaScript query invocations are not subject to the same URL-encoding requirements as GET requests. Since JavaScript supports the use of single quotes, it is not necessary to escape the double quotes from most examples in this guide. Make sure to protect against pulling in data that could contain special characters, such as double-quotes ("
). The following example shows one method of handling special characters:
"correlationQuery" : {
"type" : "text/javascript",
"source" : "var qry = {'_queryFilter': org.forgerock.util.query.QueryFilter.equalTo('uid', source.userName).toString()}; qry"
}
Construct queries
The openidm.query
function lets you query managed and system objects. The query syntax is openidm.query(id, params)
, where id
specifies the object upon the query should be performed, and params
provides the parameters passed to the query (the _queryFilter
). For example:
var equalTo = org.forgerock.util.query.QueryFilter.equalTo;
queryParams = {
"_queryFilter": equalTo("uid", value).toString()
};
openidm.query("managed/realm-name_user", queryParams)
Over the REST interface, the query filter is specified as _queryFilter=filter
, for example:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ 'https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_queryFilter=userName+eq+"Smith"'
In |
When called over REST, you must URL encode the filter expression. The following examples show the filter expressions using the Resource API and the REST API but do not show the URL encoding to make them easier to read.
The filter expression is constructed from the building blocks shown in this section. In these expressions, the simplest json-pointer is a field of the JSON resource, such as userName
or id
. A JSON pointer can, however, point to nested elements.
You can also use the negation operator ( |
Comparison expressions
You can use comparison query filters for objects and object array properties that:
Equal a specified value
This is the associated JSON comparison expression: json-pointer eq json-value
.
"_queryFilter" : '/givenName eq "Dan"'
The following REST call returns the user name and given name of all managed users whose first name (givenName
) is "Dan":
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ 'https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_queryFilter=givenName+eq+"Dan"&_fields=userName,givenName' { "result": [ { "givenName": "Dan", "userName": "dlangdon" }, { "givenName": "Dan", "userName": "dcope" }, { "givenName": "Dan", "userName": "dlanoway" } ], ... }
"_queryFilter" : "/stringArrayField eq 'foo'"
The following REST call returns role entries where a value within the stringArrayField
array equals "foo":
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ 'https://<tenant-env-fqdn>/openidm/managed/realm-name_role?_queryFilter=stringArrayField+eq+"foo"' { "result": [ { "_id": "admin2", "_rev": "0", "name": "admin2", "stringArrayField": [ "foo", "bar" ] } ], ... }
Contain a specified value
This is the associated JSON comparison expression: json-pointer co json-value
.
"_queryFilter" : '/givenName co "Da"'
The following REST call returns the username and given name of all managed users whose first name (givenName
) contains "Da":
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ 'https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_queryFilter=givenName+co+"Da"&_fields=userName,givenName' { "result": [ { "givenName": "Dave", "userName": "djensen" }, { "givenName": "David", "userName": "dakers" }, { "givenName": "Dan", "userName": "dlangdon" }, { "givenName": "Dan", "userName": "dcope" }, { "givenName": "Dan", "userName": "dlanoway" }, { "givenName": "Daniel", "userName": "dsmith" }, ... ], "resultCount": 10, "pagedResultsCookie": null, "remainingPagedResults": -1 }
Start with a specified value
This is the associated JSON comparison expression: json-pointer sw json-value
.
"_queryFilter" : '/sn sw "Jen"'
The following REST call returns the user names of all managed users whose last name (sn
) starts with "Jen":
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ 'https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_queryFilter=sn+sw+"Jen"&_fields=userName' { "result": [ { "userName": "bjensen" }, { "userName": "djensen" }, { "userName": "cjenkins" }, { "userName": "mjennings" } ], "resultCount": 4, "pagedResultsCookie": null, "remainingPagedResults": -1 }
Are less than a specified value
This is the associated JSON comparison expression: json-pointer lt json-value
.
"_queryFilter" : '/employeeNumber lt 5000'
The following REST call returns the user names of all managed users whose employeeNumber
is lower than 5000:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ 'https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_queryFilter=employeeNumber+lt+5000&_fields=userName,employeeNumber' { "result": [ { "employeeNumber": 4907, "userName": "jnorris" }, { "employeeNumber": 4905, "userName": "afrancis" }, { "employeeNumber": 3095, "userName": "twhite" }, { "employeeNumber": 3921, "userName": "abasson" }, { "employeeNumber": 2892, "userName": "dcarter" }, ... ], "resultCount": 4999, "pagedResultsCookie": null, "remainingPagedResults": -1 }
Are less than or equal to a specified value
This is the associated JSON comparison expression: json-pointer le json-value
.
"_queryFilter" : '/employeeNumber le 5000'
The following REST call returns the user names of all managed users whose employeeNumber
is 5000 or less:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ 'https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_queryFilter=employeeNumber+le+5000&_fields=userName,employeeNumber' { "result": [ { "employeeNumber": 4907, "userName": "jnorris" }, { "employeeNumber": 4905, "userName": "afrancis" }, { "employeeNumber": 3095, "userName": "twhite" }, { "employeeNumber": 3921, "userName": "abasson" }, { "employeeNumber": 2892, "userName": "dcarter" }, ... ], "resultCount": 5000, "pagedResultsCookie": null, "remainingPagedResults": -1 }
Are greater than a specified value
This is the associated JSON comparison expression: json-pointer gt json-value
"_queryFilter" : '/employeeNumber gt 5000'
The following REST call returns the user names of all managed users whose employeeNumber
is higher than 5000:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ 'https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_queryFilter=employeeNumber+gt+5000&_fields=userName,employeeNumber' { "result": [ { "employeeNumber": 5003, "userName": "agilder" }, { "employeeNumber": 5011, "userName": "bsmith" }, { "employeeNumber": 5034, "userName": "bjensen" }, { "employeeNumber": 5027, "userName": "cclarke" }, { "employeeNumber": 5033, "userName": "scarter" }, ... ], "resultCount": 1458, "pagedResultsCookie": null, "remainingPagedResults": -1 }
Are greater than or equal to a specified value
This is the associated JSON comparison expression: json-pointer ge json-value
.
"_queryFilter" : '/employeeNumber ge 5000'
The following REST call returns the user names of all managed users whose employeeNumber
is 5000 or greater:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ 'https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_queryFilter=employeeNumber+ge+5000&_fields=userName,employeeNumber' { "result": [ { "employeeNumber": 5000, "userName": "agilder" }, { "employeeNumber": 5011, "userName": "bsmith" }, { "employeeNumber": 5034, "userName": "bjensen" }, { "employeeNumber": 5027, "userName": "cclarke" }, { "employeeNumber": 5033, "userName": "scarter" }, ... ], "resultCount": 1457, "pagedResultsCookie": null, "remainingPagedResults": -1 }
Although specific system endpoints also support |
Presence expressions
The following examples show how you can build filters using a presence expression, shown as pr
. The presence expression is a filter that returns all records with a given attribute.
A presence expression filter evaluates to true
when a json-pointer pr
matches any object in which the json-pointer is present and contains a non-null value. Consider the following expression:
"_queryFilter" : '/mail pr'
The following REST call uses that expression to return the mail addresses for all managed users with a mail
property:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ 'https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_queryFilter=mail+pr&_fields=mail' { "result": [ { "mail": "jdoe@exampleAD.com" }, { "mail": "bjensen@example.com" } ], "resultCount": 2, "pagedResultsCookie": null, "remainingPagedResults": -1 }
Depending on the connector, you can apply the presence filter on system objects. The following query returns the email address of all users in a CSV file who have the email
attribute in their entries:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ 'https://<tenant-env-fqdn>/openidm/system/csvfile/account?_queryFilter=email+pr&_fields=email' { "result": [ { "_id": "bjensen", "email": "bjensen@example.com" }, { "_id": "scarter", "email": "scarter@example.com" } ], "resultCount": 2, "pagedResultsCookie": "MA%3D%3D", "totalPagedResultsPolicy": "NONE", "totalPagedResults": -1, "remainingPagedResults": -1 }
Not all connectors support the presence filter. In most cases, you can replicate the behavior of the presence filter with an "equals" ( |
Literal expressions
A literal expression is a boolean:
-
true
matches any object in the resource. -
false
matches no object in the resource.
For example, you can list the _id
of all managed objects as follows:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ 'https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_queryFilter=true&_fields=_id' { "result": [ { "_id": "d2e29d5f-0d74-4d04-bcfe-b1daf508ad7c" }, { "_id": "709fed03-897b-4ff0-8a59-6faaa34e3af6" } ], "resultCount": 2, "pagedResultsCookie": null, "remainingPagedResults": -1 }
In
expression clause
IDM provides limited support for the in expression clause. You can use this clause for queries on singleton string properties or arrays. The in
query expression is not supported through the IDM admin UI or for use by delegated administrators.
The in
operator is shorthand for multiple OR
conditions.
The following example command includes escaped characters. For readability, the non-escaped URL syntax is:
|
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_pageSize=1000&_fields=userName&_queryFilter=userName%20in%20'%5B%22user4a%22%2C%22user3a%22%5D'" { "result": [ { "_id": "e32f9a3d-0039-4cb0-82d7-347cb808672e", "_rev": "000000000ae18357", "userName": "user3a" }, { "_id": "120625c5-cfe7-48e7-b66a-6a0a0f9d2901", "_rev": "000000005ad98467", "userName": "user4a" } ], "resultCount": 2, "pagedResultsCookie": null, "totalPagedResultsPolicy": "NONE", "totalPagedResults": -1, "remainingPagedResults": -1 }
Filter expanded relationships
You can use _queryFilter
to filter expanded relationships from a collection, such as authzRoles
. The following example queries the manager-int
authorization role of a user:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user/b70293db-8743-45a7-9215-1ca8fd8a0073/authzRoles?_queryFilter=name+eq+'manager-int'&_fields=*" { "result": [ { "_id": "b1d78144-7029-4135-8e73-85efe0a40b6b", "_rev": "00000000d4b8ab97", "_ref": "internal/role/c0a38233-c0f2-477d-8f18-f5485b7d002f", "_refResourceCollection": "internal/role", "_refResourceId": "c0a38233-c0f2-477d-8f18-f5485b7d002f", "_refProperties": { "_grantType": "", "_id": "b1d78144-7029-4135-8e73-85efe0a40b6b", "_rev": "00000000d4b8ab97" }, "name": "manager-int", "description": "manager-int-desc", "temporalConstraints": null, "condition": null, "privileges": null } ], "resultCount": 1, "pagedResultsCookie": null, "totalPagedResultsPolicy": "NONE", "totalPagedResults": -1, "remainingPagedResults": -1 }
Complex expressions
You can combine expressions using the boolean operators and
, or
, and !
(not). The following example queries managed user objects located in London with the last name Jensen:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ 'https://<tenant-env-fqdn>/openidm/managed/realm-name_user/?_queryFilter=city+eq+"London"and+sn+eq"Jensen"&_fields=userName,givenName,sn' { "result": [ { "sn": "Jensen", "givenName": "Clive", "userName": "cjensen" }, { "sn": "Jensen", "givenName": "Dave", "userName": "djensen" }, { "sn": "Jensen", "givenName": "Margaret", "userName": "mjensen" } ], "resultCount": 3, "pagedResultsCookie": null, "remainingPagedResults": -1 }
Filter objects in arrays
Use query grouping to perform your query on properties within an array. For example, to query effectiveRoles
for users who have the testManagedRole
, check the _refResourceId
inside the effectiveRoles
array:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ 'https://<tenant-env-fqdn>/openidm/managed/realm-name_user/?_queryFilter=/effectiveRoles\[/_refResourceId+eq+"testManagedRole"]&_fields=userName,givenName,sn,effectiveRoles' { "result": [ { "_id": "917bc052-ef39-4add-ae05-0a278e2de9c0", "_rev": "200bc5d6-7cc1-4648-a854-3137f3d9c103-1565", "userName": "scarter", "sn": "Carter", "givenName": "Steven", "effectiveRoles": [ { "_refResourceCollection": "managed/realm-name_role", "_refResourceId": "testManagedRole", "_ref": "managed/realm-name_role/testManagedRole" } ] }, { "_id": "aca0042c-9f4c-4ad5-8cf7-aca0adeb3470", "_rev": "200bc5d6-7cc1-4648-a854-3137f3d9c103-1545", "userName": "jdoe", "sn": "Doe", "givenName": "John", "effectiveRoles": [ { "_refResourceCollection": "managed/realm-name_role", "_refResourceId": "testManagedRole", "_ref": "managed/realm-name_role/testManagedRole" } ] } ], "resultCount": 2, "pagedResultsCookie": null, "totalPagedResultsPolicy": "NONE", "totalPagedResults": -1, "remainingPagedResults": -1 }
Since |
Page query results
The common filter query mechanism supports paged query results for managed objects, and for some system objects, depending on the system resource. There are two ways to page objects in a query:
-
Using a cookie based on the value of a specified sort key.
-
Using an offset that specifies how many records should be skipped before the first result is returned.
These methods are implemented with the following query parameters:
_pagedResultsCookie
-
Opaque cookie used by the server to keep track of the position in the search results. The format of the cookie is a base-64 encoded version of the value of the unique sort key property. The value of the returned cookie is URL-encoded to prevent values such as
+
from being incorrectly translated.You cannot page results without sorting them (using the
_sortKeys
parameter). If you do not specify a sort key, the_id
of the record is used as the default sort key. At least one of the specified sort key properties must be a unique value property, such as_id
.For paged searches on generic mappings, you should sort on the _id
property, because this is the only property that is stored outside of the JSON blob. If you sort on something other than_id
, the search will incur a performance hit because IDM has to pull the entire result set and then sort it.The server provides the cookie value on the first request. You should then supply the cookie value in subsequent requests until the server returns a null cookie, meaning that the final page of results has been returned.
The
_pagedResultsCookie
parameter is supported only for filtered queries, that is, when used with the_queryFilter
parameter. You cannot use the_pagedResultsCookie
with a_queryId
.The
_pagedResultsCookie
and_pagedResultsOffset
parameters are mutually exclusive and cannot be used together.Paged results are enabled only if the
_pageSize
is a non-zero integer. _pagedResultsOffset
-
Specifies the index within the result set of the number of records to be skipped before the first result is returned. The format of the
_pagedResultsOffset
is an integer value. When the value of_pagedResultsOffset
is greater than or equal to 1, the server returns pages, starting after the specified index.This request assumes that the
_pageSize
is set, and not equal to zero.For example, if the result set includes 10 records, the
_pageSize
is 2, and the_pagedResultsOffset
is 6, the server skips the first 6 records, then returns 2 records, 7 and 8. The_remainingPagedResults
value would be 2, the last two records (9 and 10) that have not yet been returned.If the offset points to a page beyond the last of the search results, the result set returned is empty.
_pageSize
-
An optional parameter indicating that query results should be returned in pages of the specified size. For all paged result requests other than the initial request, a cookie should be provided with the query request.
The default behavior is not to return paged query results. If set, this parameter should be an integer value, greater than zero.
When a
_pageSize
is specified, and non-zero, the server calculates thetotalPagedResults
in accordance with thetotalPagedResultsPolicy
and provides the value as part of the response. If a count policy is specified (_totalPagedResultsPolicy=EXACT
), thetotalPagedResults
returns the total result count. If no count policy is specified in the query, or if_totalPagedResultsPolicy=NONE
, result counting is disabled, and the server returns a value of -1 fortotalPagedResults
. The following example shows a query that requests two results with atotalPagedResultsPolicy
ofEXACT
:curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ "https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_queryFilter=true&_pageSize=2&_totalPagedResultsPolicy=EXACT" { "result": [ { "_id": "adonnelly", "_rev": "0", "userName": "adonnelly", "givenName": "Abigail", "sn": "Donnelly", "telephoneNumber": "12345678", "active": "true", "mail": "adonnelly@example.com", "accountStatus": "active", "effectiveRoles": [], "effectiveAssignments": [] }, { "_id": "bjensen", "_rev": "0", "userName": "bjensen", "givenName": "Babs", "sn": "Jensen", "telephoneNumber": "12345678", "active": "true", "mail": "bjensen@example.com", "accountStatus": "active", "effectiveRoles": [], "effectiveAssignments": [] } ], "resultCount": 2, "pagedResultsCookie": "eyIvX2lkIjoiYm11cnJheSJ9", "totalPagedResultsPolicy": "EXACT", "totalPagedResults": 22, "remainingPagedResults": -1 }
The
totalPagedResults
and_remainingPagedResults
parameters are not supported for all queries. Where they are not supported, their returned value is always-1
. In addition, counting query results using these parameters is not currently supported for a DS repository.Requesting the total result count (with
_totalPagedResultsPolicy=EXACT
) incurs a performance cost on the query.Queries that return large data sets will have a significant impact on heap requirements, particularly if they are run in parallel with other large data requests. To avoid out of memory errors, analyze your data requirements, set the heap configuration appropriately, and modify access controls to restrict requests on large data sets.
Sort query results
For common filter query expressions, you can sort the results of a query using the _sortKeys
parameter. This parameter takes a comma-separated list as a value and orders the way the JSON result is returned based on this list.
The _sortKeys
parameter is not supported for predefined queries.
|
The following query returns all users with the givenName
Dan and sorts the results alphabetically, according to surname (sn
):
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ 'https://<tenant-env-fqdn>/openidm/system/ldap/account?_queryFilter=givenName+eq+"Dan"&_fields=givenName,sn&_sortKeys=sn' { "result": [ { "sn": "Cope", "givenName": "Dan" }, { "sn": "Langdon", "givenName": "Dan" }, { "sn": "Lanoway", "givenName": "Dan" } ], "resultCount": 3, "pagedResultsCookie": null, "remainingPagedResults": -1 }
When you query a relationship field, fields that belong to the related object are not available as |
Recalculate properties based on other properties (virtual) in queries
For managed objects, IDM includes an onRetrieve script hook that enables you to recalculate property values, known as virtual properties, when an object is retrieved as the result of a query. To use the onRetrieve
trigger, the query must include the executeOnRetrieve
parameter, for example:
curl \ --header "Authorization: Bearer <token>" \ --header "Accept-API-Version: resource=1.0" \ --request GET \ 'https://<tenant-env-fqdn>/openidm/managed/realm-name_user?_queryFilter=sn+eq+"Jensen"&executeOnRetrieve=true'
If a query includes executeOnRetrieve
, the query recalculates virtual property values, based on the current state of the system. The result of the query will be the same as a read
on a specific object, because reads always recalculate virtual property values.
If a query does not include executeOnRetrieve
, the query returns the virtual properties of an object based on the value that is persisted in the repository. Virtual property values are not recalculated.
For performance reasons, executeOnRetrieve
is false
by default.
Virtual properties that use queryConfig for calculation instead of an |
Appendix A: Data models and objects reference
You can customize a variety of objects that can be addressed via a URL or URI. IDM can perform a common set of functions on these objects, such as CRUDPAQ (create, read, update, delete, patch, action, and query).
Depending on how you intend to use them, different object types are appropriate.
Object Type | Intended Use | Special Functionality |
---|---|---|
Managed objects |
Serve as targets and sources for synchronization, and to build virtual identities. For more information, refer to Managed objects. |
Provide appropriate auditing, script hooks, declarative mappings and so forth in addition to the REST interface. |
Configuration objects |
Ideal for look-up tables or other custom configuration, which you can configure externally like any other system configuration. |
Adds file view, REST interface, and so forth |
Repository objects |
The equivalent of arbitrary database table access. Appropriate for managing data through the underlying data store or repository API. For information on how to access identity related data using REST, refer to REST and IDM. |
Persistence and API access |
System objects |
Pluggable representations of objects on external systems. They follow the same RESTful resource based design principles as managed objects. There is a default implementation for the ICF framework, which allows any connector object to be represented as a system object. For more information on system objects and connectors, refer to Ping Identity ICF. For information on REST endpoints relating to system objects, refer to System objects. |
|
Audit objects |
Houses audit data in the repository. For more information on how to access audit data in Advanced Identity Cloud, refer to Access logs with API key and secret. |
|
Links |
Link objects define relations between source objects and target objects, usually relations between managed objects and system objects. The link relationship is established by provisioning activity that either results in a new account on a target system, or a reconciliation or synchronization scenario that takes a For more information, refer to Reuse links between mappings. |
|
Managed objects
Managed objects and their properties are defined in the IDM managed object schema.
The default schema includes these types of managed objects:
Each managed object type contains properties for storing information about objects of that type. For example, the user object type has properties for storing usernames, passwords, email addresses, and so forth.
In the IDM admin UI, managed objects represent the identity-related data managed by IDM. In IDM, managed objects are stored in a DS repository.
Data consistency
Single-object operations are consistent within the scope of the operation performed, limited by the capabilities of the underlying data store. Bulk operations have no consistency guarantees. IDM does not expose any transactional semantics in the managed object access API.
For information on conditional header access through the REST API, refer to Conditional Operations.
Managed object triggers
Triggers are user-definable functions that validate or modify object or property state.
State triggers
Managed objects are resource-oriented. A set of triggers is defined to intercept the supported request methods on managed objects. Such triggers are intended to perform authorization, redact, or modify objects before the action is performed. The object being operated on is in scope for each trigger, meaning that the object is retrieved by the data store before the trigger is fired.
If retrieval of the object fails, the failure occurs before any trigger is called. Triggers are executed before any optimistic concurrency mechanisms are invoked. The reason for this is to prevent a potential attacker from getting information about an object (including its presence in the data store) before authorization is applied.
Managed object triggers | Description |
---|---|
|
Called upon a request to create a new object. Throwing an exception causes the create to fail. |
|
Called after the creation of a new object is complete. |
|
Called upon a request to retrieve a whole object or portion of an object. Throwing an exception causes the object to not be included in the result. This method is also called when lists of objects are retrieved via requests to its container object; in this case, only the requested properties are included in the object. It allows for uniform access control for retrieval of objects, regardless of the method in which they were requested. |
|
Called upon a request to store an object. The The If, as a result of the trigger, the values of the |
|
Called after an update request is complete. |
|
Called upon a request to delete an object. Throwing an exception causes the deletion to fail. |
|
Called after an object is deleted. |
|
Called when a managed object is changed, and the change triggers an implicit synchronization operation. The implicit synchronization operation is triggered by calling the sync service that attempts to go through all the configured managed-system mappings. The sync service returns a response or an error. For both the response and the error, the script referenced by the You can use this hook to inject business logic when the sync service fails or succeeds to synchronize all applicable mappings. For an example of how the |
Object storage triggers
An object-scoped trigger applies to an entire object. Unless otherwise specified, the object itself is in scope for the trigger.
- onValidate
-
Validates an object prior to its storage in the data store. If an exception is thrown, the validation fails and the object is not stored.
- onStore
-
Called prior to when an object is stored in the data store. Typically used to transform an object prior to its storage (for example, encryption).
Property storage triggers
A property-scoped trigger applies to a specific property within an object. Only the property itself is in scope for the trigger. No other properties in the object should be accessed during execution of the trigger. Unless otherwise specified, the order of execution of property-scoped triggers is intentionally left undefined.
- onValidate
-
Validates a given property value after its retrieval from and prior to its storage in the data store. If an exception is thrown, the validation fails and the property is not stored.
- onRetrieve
-
Called on all requests that return a single object: read, create, update, patch, and delete.
onRetrieve
is called on queries only ifexecuteOnRetrieve
is set totrue
in the query request parameters. IfexecuteOnRetrieve
is not passed, or if it isfalse
, the query returns previously persisted values of the requested fields. This behavior avoids performance problems when executing the script on all results of a query. - onStore
-
Called before an object is stored in the data store. Typically used to transform a given property before its object is stored.
Storage trigger Sequences
Triggers are executed in the following order:
- Object retrieval Sequence
-
-
Retrieve the raw object from the data store
-
The
executeOnRetrieve
boolean is used to check whether property values should be recalculated. The sequence continues if the boolean is set totrue
. -
Call object
onRetrieve
trigger -
Per-property within the object, call property
onRetrieve
trigger
-
- Object storage sequence
-
-
Per-property within the object:
-
Call property
onValidate
trigger -
Call object
onValidate
trigger
-
-
Per-property trigger within the object:
-
Call property
onStore
trigger -
Call object
onStore
trigger -
Store the object with any resulting changes to the data store
-
-
Managed object encryption
Sensitive object properties can be encrypted prior to storage, typically through the property onStore
trigger. The trigger has access to configuration data, which can include arbitrary attributes that you define, such as a symmetric encryption key. Such attributes can be decrypted during retrieval from the data store through the property onRetrieve
trigger.
Managed object configuration
Configuration of managed objects is provided through an array of managed object configuration objects.
The object is managed-object-config
.
{
"objects": [ managed-object-config object, ... ]
}
- objects
-
array of managed-object-config objects, required
Specifies the objects that the managed object service manages.
Managed object config properties
Specifies the configuration of each managed object.
{
"name" : string,
"actions" : script object,
"onCreate" : script object,
"onDelete" : script object,
"onRead" : script object,
"onRetrieve": script object,
"onStore" : script object,
"onSync" : script object,
"onUpdate" : script object,
"onValidate": script object,
"postCreate": script object,
"postDelete": script object,
"postUpdate": script object,
"schema" : {
"id" : urn,
"icon" : string,
"mat-icon" : string,
"order" : [ list of properties],
"properties": { property-configuration objects },
"$schema" : "http://json-schema.org/draft-03/schema",
"title" : "User",
"viewable" : true
}
}
Property | Description |
---|---|
|
String, required. The name of the managed object. Used to identify the managed object in URIs and identifiers. |
|
Script object, optional. A custom script that initiates an action on the managed object. For more information, refer to Register custom scripted actions. |
|
Script object, optional. A script object to trigger when the creation of an object is being requested. The object to be created is provided in the root scope as an |
|
Script object, optional. A script object to trigger when the deletion of an object is being requested. The object being deleted is provided in the root scope as an |
|
Script object, optional. A script object to trigger when the read of an object is being requested. The object being read is provided in the root scope as an |
|
Script object, optional. A script object to trigger when an object is retrieved from the repository. The object that was retrieved is provided in the root scope as an |
|
Script object, optional. A script object to trigger when an object is about to be stored in the repository. The object to be stored is provided in the root scope as an |
|
Script object, optional. A script object to trigger when a change to a managed object triggers an implicit synchronization operation. The script has access to the |
|
Script object, optional. A script object to trigger when an update to an object is requested. The old value of the object being updated is provided in the root scope as an |
|
Script object, optional. A script object to trigger when the object requires validation. The object to be validated is provided in the root scope as an |
|
Script object, optional. A script object to trigger after an object is created, but before any targets are synchronized. |
|
Script object, optional. A script object to trigger after a delete of an object is complete, but before any further synchronization. The value of the deleted object is provided in the root scope as an |
|
Script object, optional. A script object to trigger after an update to an object is complete, but before any targets are synchronized. The value of the object before the update is provided in the root scope as an |
|
Json-schema object, optional. The schema to use to validate the structure and content of the managed object, and how the object is displayed in the UI. The schema-object format is defined by the JSON Schema specification. |
|
String, optional. The name of the Font Awesome icon to display for this object in the UI. Only applies to standalone IDM. |
|
String, optional. The name of the Material Icon to display for this object in the UI. Only applies to IDM as part of the Ping Identity Platform. |
|
Urn, optional. The URN of the managed object, for example, |
|
List of properties, optional. The order in which properties of this managed object are displayed in the UI. |
|
List of property configuration objects, optional. A list of property specifications. For more information, refer to Property Configuration Properties. |
|
Url, optional. Link to the JSON schema specification. |
|
String, optional. The title of this managed object in the UI. |
|
Boolean, optional. Whether this object is visible in the UI. |
Property configuration properties
Each managed object property, identified by its property-name
, can have the following configurable properties:
"property-name" : {
"description" : string,
"encryption" : property-encryption object,
"isPersonal" : boolean true/false,
"isProtected" : boolean true/false,
"isVirtual" : boolean true/false,
"items" : {
"id" : urn,
"properties" : property-config object,
"resourceCollection" : property-config object,
"reversePropertyName" : string,
"reverseRelationship" : boolean true/false,
"title" : string,
"type" : string,
"validate" : boolean true/false,
},
"onRetrieve" : script object,
"onStore" : script object,
"onValidate" : script object,
"pattern" : string,
"policies" : policy object,
"required" : boolean true/false,
"returnByDefault" : boolean true/false,
"scope" : string,
"searchable" : boolean true/false,
"secureHash" : property-hash object,
"title" : string,
"type" : data type,
"usageDescription": string,
"userEditable" : boolean true/false,
"viewable" : boolean true/false,
}
Property | Description | ||
---|---|---|---|
|
String, optional. A brief description of the property. |
||
|
Property-encryption object, optional. Specifies the configuration for encryption of the property in the repository. If omitted or null, the property isn’t encrypted. |
||
|
Boolean, true/false. Designed to highlight personally identifying information. By default, |
||
|
Boolean, true/false. Specifies whether reauthentication is required if the value of this property changes. |
||
|
Boolean, true/false. Specifies whether the property takes a static value or whether its value is calculated dynamically as the result of a script. The most recently calculated value of a virtual property is persisted by default. The persistence of virtual property values allows PingIDM to compare the new value of the property against the last calculated value to detect change events during synchronization. Virtual property values aren’t persisted by default if you’re using an explicit mapping. |
||
|
Property-configuration object, optional. For |
||
|
Urn, optional. The URN of the property, for example, |
||
|
Property configuration object, optional. A list of properties and their configuration that make up the
json |
||
|
Property configuration object, optional. The collection of resources or objects on which this relationship is based. For example, |
||
|
String, optional For |
||
|
Boolean, true or false. For |
||
|
String, optional. The title of array items displayed in the UI. For example, |
||
|
String, optional. The array type, for example |
||
|
Boolean, true/false. For reverse relationships, |
||
|
Script object, optional. A script object to trigger after a property is retrieved from the repository. That property may be one of two related variables:
|
||
|
Script object, optional. A script object to trigger when a property is about to be stored in the repository. That property may be one of two related variables: |
||
|
Script object, optional. A script object to trigger when the property requires validation. The value of the property to be validated is provided in the root scope as the |
||
|
String, optional. Any specific pattern to which the value of the property must adhere. For example, a property whose value is a date could require a specific date format. Patterns specified here must follow regular expression syntax. |
||
|
Policy object, optional. Any policy validation that must be applied to the property. |
||
|
Boolean, true/false. Specifies whether the property must be supplied when this type of object is created. |
||
|
Boolean, true/false. For virtual properties, |
||
|
String, optional. Specifies whether the property should be filtered from HTTP or external calls. The value can be either
|
||
|
Boolean, true/false. Specifies whether
|
||
|
Property-hash object, optional. Specifies the configuration for hashing the property value in the repository. If omitted or null, the property is not hashed. |
||
|
String, required. A human-readable string, used to display the property in the UI. |
||
|
Data type, required. The data type for the property value, which can be a string, array, boolean, number, object, or resource collection. |
||
|
String, optional. Designed to help end users understand the sensitivity of a property, such as a telephone number. |
||
|
Boolean, true/false. Specifies whether users can edit the property value in the UI. This property applies in the context of the end-user UI, where users are able to edit certain properties of their own accounts. The |
||
|
Boolean, true/false. Specifies whether this property is viewable in the object’s profile in the UI. The |
Script object properties
{
"type" : "text/javascript",
"source": string
}
- type
-
String, required.
IDM supports
"text/javascript"
. - source
-
String, required.
Specifies the source code of the script to be executed (if the keyword is "source").
Property encryption object
{
"cipher": string,
"key" : string
}
- cipher
-
String, optional.
The cipher transformation used to encrypt the property. If omitted or null, the default cipher of
"AES/CBC/PKCS5Padding"
is used. - key
-
String, required.
The alias of the key in the IDM cryptography service keystore used to encrypt the property.
Property hash object
{
"algorithm" : string,
"type" : string
}
- algorithm
-
String, required.
The algorithm that should be used to hash the value.
- type
-
String, optional.
The type of hashing. Currently, only salted hash is supported. If this property is omitted or null, the default
"salted-hash"
is used.
Access managed objects using REST
IDM exposes all managed object functionality through the REST API unless you configure a policy to prevent such access. In addition to the Ping Identity REST functionality of create, read, update, delete, patch, and query, the REST API also supports patch by query. For more information, refer to the PingIDM REST API reference.