Provisioner
The Provisioner connects Wren:IDM to external systems through connector plugins and exposes them as CREST resources under the /system endpoint.
Wren:IDM ships with one provisioner implementation: the Wren:ICF (OpenICF) provisioner, which integrates with Identity Connector Framework connectors.
Architecture
The provisioner layer consists of three cooperating services.
System Object Set Service
- OSGi service class
-
org.forgerock.openidm.provisioner.impl.SystemObjectSetService - OSGi persistent identifier
-
org.forgerock.openidm.provisioner - Router mapping
-
/system
The System Object Set Service is a singleton that owns the /system route and acts as a hub across all active provisioner instances.
It aggregates any number of running ProvisionerService implementations.
It dispatches system-level actions to the appropriate instance, such as testing connections, triggering live sync, and generating connector configurations.
It also implements the ScheduledService interface, so the Wren:IDM Scheduler can trigger live sync through it.
No configuration file is required.
The service starts unconditionally.
OpenICF Provisioner Service
- OSGi service class
-
org.forgerock.openidm.provisioner.openicf.impl.OpenICFProvisionerService - OSGi persistent identifier
-
org.forgerock.openidm.provisioner.openicf - Configuration file
-
provisioner.openicf-[name].json
One OpenICF Provisioner Service instance is created per connector configuration file.
Each instance registers its own routes under /system/<name> and /system/<name>/{objectClass}, where <name> is read from the name field of the configuration file.
The service resolves the connector bundle asynchronously via ConnectorInfoProviderService and builds a ConnectorFacade when the connector info becomes available.
Setting enabled to false in the configuration prevents connector initialisation and route registration while keeping the OSGi service active.
Connector Info Provider Service
- OSGi service class
-
org.forgerock.openidm.provisioner.openicf.impl.ConnectorInfoProviderService - OSGi persistent identifier
-
org.forgerock.openidm.provisioner.openicf.connectorinfoprovider - Configuration file
-
provisioner.openicf.connectorinfoprovider.json(optional)
The Connector Info Provider Service loads connector bundles from the local file system and from remote Wren:ICF connector servers.
It makes these bundles available to all provisioner instances.
Because its OSGi configuration policy is OPTIONAL, the service starts without a configuration file using built-in defaults.
Connector Info Provider configuration
The optional provisioner.openicf.connectorinfoprovider.json file controls where connectors are loaded from and how remote connector servers are reached.
provisioner.openicf.connectorinfoprovider.json structure{
"connectorsLocation": "connectors",
"remoteConnectorServers": [
{
"name": "myServer",
"host": "connector-host.example.com",
"port": 8759,
"key": { "$crypto": { "type": "x-simple-encryption", "value": { "cipher": "AES/CBC/PKCS5Padding", "data": "..." } } },
"useSSL": false,
"timeout": 0,
"protocol": "websocket"
}
],
"remoteConnectorServersGroups": [
{
"name": "myGroup",
"algorithm": "failover",
"serversList": [ "myServer" ]
}
]
}
connectorsLocation-
Path to the directory containing local connector JAR files. Relative paths resolve against the Wren:IDM installation directory (the
--install-location/-istartup parameter), or the process working directory when that parameter is not set. Default:connectors. remoteConnectorServers-
List of remote Wren:ICF connector servers to connect to.
name-
Unique name for this server. Referenced as
connectorHostRefin provisioner configuration files. Required. host-
Hostname or IP address of the remote connector server. Required.
port-
TCP port. Default:
8759. key-
Shared secret used to authenticate with the remote server. Store as an encrypted value using the
$cryptowrapper. To produce the encrypted value, use the Crypto serviceencryptaction, the Wren:IDM admin UI, or the CLIlocal:encryptcommand. See Crypto service. Required. useSSL-
Whether to use SSL/TLS. Default:
false. timeout-
Connection timeout in milliseconds, passed as the timeout parameter to the ICF
RemoteFrameworkConnectionInfoconstructor. The ICF framework defines the exact scope (TCP establishment vs. socket read).0means no timeout. Default:0. protocol-
Set to
"websocket"to use the WebSocket-based ICF 1.5 protocol. Default: absent (ICF 1.4 Java serialisation protocol is used).
remoteConnectorServersGroups-
Load-balancing groups over named remote servers. A group name can be used as a
connectorHostRefvalue just like a single server name.name-
Group identifier, referenced as
connectorHostRefin provisioner configs. algorithm-
Load-balancing strategy:
"failover"always sends to the first available server in order."roundrobin"distributes requests across all servers in the list. serversList-
Ordered list of server names from
remoteConnectorServersto include in this group. For thefailoveralgorithm, the first reachable server in this list is used. Order therefore determines failover priority.
Connector configuration
One configuration file per connector is required.
The [name] portion after the dash is only a Configuration Admin alias.
The name field inside the JSON body always determines the actual system name used in resource paths, regardless of this alias.
The value must be alphanumeric.
A name that fails this check causes a configuration activation error (JsonValueException).
provisioner.openicf-ldap.json (illustrative, abbreviated){
"name": "ldap",
"enabled": true,
"connectorRef": {
"bundleName": "org.forgerock.openicf.connectors.ldap-connector",
"bundleVersion": "[1.4.0.0,1.5.0.0)",
"connectorName": "org.identityconnectors.ldap.LdapConnector",
"connectorHostRef": "myServer"
},
"poolConfigOption": {
"maxObjects": 10,
"maxIdle": 10,
"maxWait": 150000,
"minEvictableIdleTimeMillis": 120000,
"minIdle": 1
},
"operationTimeout": {
"CREATE": -1,
"UPDATE": -1,
"DELETE": -1,
"SEARCH": -1,
"SYNC": -1,
"TEST": -1,
"AUTHENTICATE": -1,
"SCHEMA": -1,
"VALIDATE": -1,
"SCRIPT_ON_CONNECTOR": -1,
"SCRIPT_ON_RESOURCE": -1
},
"configurationProperties": {},
"resultsHandlerConfig": {
"enableNormalizingResultsHandler": true,
"enableFilteredResultsHandler": true,
"enableCaseInsensitiveFilter": false,
"enableAttributesToGetSearchResultsHandler": true
},
"syncFailureHandler": {
"maxRetries": 5,
"postRetryAction": "logged-ignore"
}
}
name-
The system identifier. It becomes the route segment at
/system/<name>. Required. enabled-
Set to
falseto disable this connector without removing the configuration file. Default:true. connectorRef-
Identifies the connector bundle to load.
bundleName-
OSGi bundle symbolic name of the connector. Required.
bundleVersion-
Version or version range of the connector bundle. Uses OSGi range syntax, where
[is inclusive and)is exclusive (e.g.[1.4.0.0,1.5.0.0)). Required. connectorName-
Fully-qualified Java class name of the connector implementation. Required.
connectorHostRef-
Name of the remote server or group that hosts this connector. The value may be a server name or a group name defined in
remoteConnectorServersGroups. See Connector Info Provider configuration. Omit for locally-deployed connector JARs. When absent, the connector bundle is resolved from the localconnectorsLocationdirectory instead. When set to a name that does not match any entry inremoteConnectorServersorremoteConnectorServersGroups, the connector facade cannot be initialised. All operations on this connector then returnServiceUnavailableExceptionat runtime.
configurationProperties-
Connector-specific key/value properties passed directly to the connector. The available keys are connector-dependent. To discover them, call
createCoreConfig(see System-level actions) with a request body containing aconnectorRefobject. The response includes aconfigurationPropertiesmap with key names and type metadata. Copy this map into the configuration file. For the full annotated schema including per-operation option names, callcreateFullConfigwith a body containing bothconnectorRefand an (initially empty)configurationPropertiesobject. poolConfigOption-
Connection pool settings for the connector instance. When this block is omitted, the ICF framework’s own defaults apply unchanged. The example values shown in the configuration skeleton (10 / 10 / 150000 / 120000 / 1) are illustrative. The actual ICF framework defaults may differ. To get the true defaults for a specific connector, call
createCoreConfig(see System-level actions). The returned skeleton includes apoolConfigOptionblock populated with the ICF framework defaults for that connector.-
maxObjects– Maximum total number of objects (idle + active) in the pool. -
maxIdle– Maximum number of idle objects to keep in the pool. -
maxWait– Maximum wait time in milliseconds for a pooled connection before an error is thrown. -
minEvictableIdleTimeMillis– Minimum time in milliseconds an idle connection must remain in the pool before becoming eligible for eviction. -
minIdle– Minimum number of idle connections to maintain.
-
operationTimeout-
Per-operation timeouts in milliseconds.
-1means no timeout. Recognised keys:CREATE,UPDATE,DELETE,SEARCH,SYNC,TEST,AUTHENTICATE,SCHEMA,VALIDATE,SCRIPT_ON_CONNECTOR,SCRIPT_ON_RESOURCE,GET,RESOLVEUSERNAME. Keys not in this set are never read and have no effect. resultsHandlerConfig-
Controls the ICF results handler chain applied to search results returned by the connector. When this block is omitted, the ICF framework’s own defaults for each field apply. To discover the effective defaults for a specific connector, call
createCoreConfig(see System-level actions). The returned skeleton includes aresultsHandlerConfigblock populated with the ICF framework defaults.enableNormalizingResultsHandler-
When
true, attribute names in search results are normalised to the IDM-side names defined inobjectTypesbefore being returned. enableFilteredResultsHandler-
When
true, Wren:IDM applies the requested filter expression in-memory after receiving all results from the connector. Disable this only when the connector natively supports the filter expression, to avoid fetching the full result set from the remote system. enableCaseInsensitiveFilter-
When
true, the IDM-side filtered results handler compares attributes case-insensitively. Has no effect whenenableFilteredResultsHandlerisfalse. enableAttributesToGetSearchResultsHandler-
When
true, the results handler trims search results to include only the attributes the query explicitly requests. It removes unrequested attributes after the connector returns them.
syncFailureHandler-
Retry and error strategy for live sync delta processing. See Live sync.
objectTypes-
Schema for each connector object type. See Object types.
operationOptions-
Per-operation access control and option definitions. See Operation options.
systemActions-
Named script actions that can be invoked on the connector or target resource. See Script system actions.
Object types
The objectTypes map defines the schema for each object class exposed by the connector.
This field is optional.
When absent, the map defaults to empty.
Only the automatically-added ICF ALL handler is available, and no /system/<name>/<objectType> resource routes are registered until at least one entry is defined.
Keys are IDM-side names chosen by the operator (e.g. account, group).
These names have no special meaning in the provisioner code.
The ICF ObjectClass identity depends entirely on nativeType.
objectTypes entry{
"objectTypes": {
"account": {
"$schema": "http://json-schema.org/draft-03/schema",
"id": "__ACCOUNT__",
"type": "object",
"nativeType": "__ACCOUNT__",
"properties": {
"uid": {
"type": "string",
"nativeName": "__NAME__",
"nativeType": "string"
},
"password": {
"type": "string",
"nativeName": "__PASSWORD__",
"nativeType": "JAVA_TYPE_GUARDEDSTRING",
"flags": [ "NOT_READABLE", "NOT_RETURNED_BY_DEFAULT" ]
}
}
}
}
}
Each object type entry:
$schema-
Not read by the ICF provisioner.
type-
Not read by the ICF provisioner.
id-
Not read by the ICF provisioner. Set it to the same value as
nativeType(e.g.ACCOUNT). nativeType-
ICF
ObjectClassname at the connector level. This is the field actually read by the ICF provisioner code to identify the connector object class. By convention,idshould carry the same value. properties-
Map of IDM-side attribute names to attribute schema definitions.
Each attribute entry:
type-
JSON schema type or Java type constant. Common values:
string,boolean,integer,JAVA_TYPE_GUARDEDSTRING,JAVA_TYPE_GUARDEDBYTEARRAY. nativeName-
The ICF attribute name on the target system (e.g.
NAME,PASSWORD,cn,sAMAccountName). nativeType-
Java type used for ICF serialisation.
flags-
Optional array of modifier flags. When the
flagsarray is absent or empty, the attribute is updateable, creatable, readable, returned by default, single-valued, and optional. Available flag values:-
NOT_CREATABLE– Cannot be set during object creation. -
NOT_UPDATEABLE– Cannot be modified after creation. -
NOT_READABLE– Cannot be read from the target system. -
NOT_RETURNED_BY_DEFAULT– Not included in results unless explicitly requested. -
MULTIVALUED– Holds a list of values rather than a single value. -
PASSWORD– Marks the attribute as a credential value. -
NOT_QUERYABLE– Cannot be used in query filter expressions. -
AUDITED– Value is included in audit log entries. -
STORE_IN_REPOSITORY– Value is persisted in the Wren:IDM repository. -
IGNORE– Defined in the schema but not passed to the connector. -
REMOTE– Value is generated externally and must be read back before being sent to the resource.
-
Operation options
The operationOptions map controls whether specific ICF operations are permitted and what additional options are passed to the connector.
Keys are ICF operation names.
The valid key set is the same as for operationTimeout.
Recognised keys: CREATE, UPDATE, DELETE, SEARCH, SYNC, TEST, AUTHENTICATE, SCHEMA, VALIDATE, SCRIPT_ON_CONNECTOR, SCRIPT_ON_RESOURCE, GET, RESOLVEUSERNAME.
account){
"operationOptions": {
"DELETE": {
"denied": true,
"supportedObjectTypes": [ "account" ]
},
"SEARCH": {
"denied": false,
"supportedObjectTypes": [ "account" ]
}
}
}
Each entry accepts:
denied-
When
true, the operation is blocked and returns an error to the caller. Default:false.denied: truehas no effect unlesssupportedObjectTypesis also present on the same entry. WhensupportedObjectTypesis absent, the denied check is not evaluated. The operation proceeds as if nooperationOptionsentry existed for that key, and no restriction applies. This check runs before any other per-operation logic on the connector. When it blocks,getConnectorFacade0()throwsForbiddenExceptionimmediately, and no further processing occurs. supportedObjectTypes-
List of IDM-side object type names (keys from
objectTypes) to which this entry applies. When present, thedeniedcheck andoperationOptionInfooptions are scoped to the listed types. When absent, thedeniedcheck is never evaluated (regardless of thedeniedvalue), andoperationOptionInfooptions apply to all object types. operationOptionInfo-
JSON schema (draft-03) describing additional ICF
OperationOptionsproperties to include when this operation is invoked. Valid option names are connector-specific. To discover them, call thecreateFullConfigaction (see System-level actions), which returns an annotated configuration skeleton that includes theoperationOptionsschema for the connector. The provisioner applies the defined options automatically from the connector configuration on each invocation. Callers do not pass them explicitly in the HTTP request.
Resource paths and operations
System objects are addressed at:
/system/<name>/<objectType>/<id>
where:
-
<name>is the value of the provisioner’snamefield. -
<objectType>is a key fromobjectTypes. -
<id>is the object identifier. URL-encode it when it contains special characters such as/or+.
The system/ prefix is optional.
Both system/ldap/account/jdoe and ldap/account/jdoe are accepted as identifiers.
|
The ObjectClassResourceProvider handles CREST requests for a given object type and delegates each operation to the corresponding ICF API operation:
-
Create →
CreateApiOp -
Read →
GetApiOp -
Update →
UpdateApiOp -
Delete →
DeleteApiOp -
Patch →
UpdateApiOp -
Query →
SearchApiOp
Operations not supported by the connector return NotSupportedException.
An operation blocked by denied: true in operationOptions also returns an error.
The authenticate action on an object instance verifies a credential against the connector via AuthenticationApiOp.
The action requires username and password as request additional parameters (HTTP query parameters).
For example: POST /openidm/system/ldap/account?_action=authenticate&username=jdoe&password=secret
On success it returns the connector Uid of the authenticated object.
Update and patch operations support a separate re-authentication mechanism.
If the request includes an X-OpenIDM-Reauth-Password HTTP header, the provisioner reads the username from the request body.
It uses the attribute named by the first entry of configurationProperties.accountUserNameAttributes.
It then verifies the credential via AuthenticationApiOp before applying the change.
The denied/supportedObjectTypes coupling also governs re-authentication ordering.
When it blocks the operation, the X-OpenIDM-Reauth-Password header above is never evaluated.
|
System-level actions
Actions are invoked on the /system singleton (SystemObjectSetService) via a CREST action request.
test-
Returns connection status for all active provisioner instances as a JSON array. To test a single named system, include
idas a field in the request body (e.g.{ "id": "ldap" }). The response is then a single status object rather than an array. Each status object contains the following fields:-
name: system name. -
enabled: boolean. -
config: config path. -
connectorRef. -
objectTypes: list of configured type names. -
ok: boolean connection success. -
error: present when the connection fails.The per-connector
testaction (see Per-connector actions) returns this same object for a single connector instance.
-
testConfig-
Tests a connector configuration payload without persisting it. The request body must be a full connector configuration including a
namefield. liveSync/activeSync-
Triggers live sync for a specific object type. Requires a
sourcequery parameter in the formsystem/<name>/<objectType>(e.g.?source=system/ldap/account). Thesystem/prefix is optional here too, per Resource paths and operations. For example,source=ldap/accountis equally valid. The optional boolean query parameterdetailedFailurecontrols whether thesyncDeltafield is included inside thelastExceptionobject of the action response body. Whenfalse(the default), thesyncDeltafield is removed fromlastExceptionbefore the response is returned. Whentrue, the fullsyncDeltaobject is retained inlastException. availableConnectors-
Lists all connector types available through the active Connector Info Provider.
createConfiguration-
Multi-phase configuration wizard invoked as
POST /system?_action=createConfiguration.- Phase 1 (empty request body)
-
Returns a list of available connectors.
- Phase 2 (body contains
connectorRefbut noconfigurationProperties) -
Generates the core configuration skeleton for the selected connector.
- Phase 3 (body contains both
connectorRefandconfigurationProperties) -
Validates and returns the full configuration.
When the connector type is already known,
createCoreConfigandcreateFullConfigcomplete phases 2 and 3 directly, without the phase-1 connector listing step.
createCoreConfig-
Single-call equivalent of phase 2 of
createConfiguration(generates the core configuration skeleton). Endpoint:POST /system?_action=createCoreConfig. The request body must be a JSON object containing aconnectorRefobject (withbundleName,bundleVersion, andconnectorName). TheconfigurationPropertiesfield must be absent or null.Example request body{ "connectorRef": { "bundleName": "org.forgerock.openicf.connectors.ldap-connector", "bundleVersion": "[1.4.0.0,1.5.0.0)", "connectorName": "org.identityconnectors.ldap.LdapConnector" } } createFullConfig-
Single-call equivalent of phase 3 of
createConfiguration(validates and returns the full annotated configuration). Endpoint:POST /system?_action=createFullConfig. The request body must contain bothconnectorRefand aconfigurationPropertiesobject (may be the map returned bycreateCoreConfig, populated with actual values).
Per-connector actions
Actions can be invoked directly on a connector instance at /system/<name>.
test-
Tests the connection for this specific connector and returns its status object.
livesync-
Triggers live sync for this connector instance, equivalent to calling the
liveSyncsystem action with this connector as the source. The action name at the per-connector endpoint islivesync(all lowercase). At the system-level endpoint the equivalent action isliveSync(camelCase). Internally,getActionAsEnum()resolves both names case-insensitively. Either endpoint accepts any casing variant (e.g.LIVESYNC,LiveSync). script-
Executes a named system action defined in
systemActions. See Script system actions.
Live sync
Live sync captures changes that occurred on the external system since the last invocation and delivers them to Wren:IDM.
Not all connectors support live sync.
Support depends on the connector implementing SyncApiOp.
On each invocation, the provisioner reads a sync stage object from repo/synchronisation/pooledSyncStage.
The stage ID is derived from the source path by removing all / characters and uppercasing the result (for example, system/ldap/account becomes SYSTEMLDAPACCOUNT).
The previous stage is passed to ProvisionerService.liveSynchronize(), and the returned updated stage is written back to the repository.
On the first invocation for a given source, no stage record exists in the repository.
The provisioner passes null as the stage to the connector’s sync API.
When the connector receives a null sync token, it determines its own starting point.
This behavior is connector-specific, and Wren:IDM does not control it.
The Scheduler can trigger live sync automatically.
Set the scheduler job’s invokeService to "provisioner" and place action and source in the invokeContext block.
schedule-liveSync-ldap.json){
"enabled": true,
"type": "cron",
"schedule": "0/15 * * * * ?",
"persisted": true,
"invokeService": "provisioner",
"invokeContext": {
"action": "liveSync",
"source": "system/ldap/account"
}
}
The invokeContext fields are:
action-
Must be
"liveSync"(or"activeSync", which is a recognised alias at the system-level endpoint). The value is resolved case-insensitively viaUtils.asEnum."livesync","LIVESYNC", and"liveSync"are all accepted. Use"liveSync"(camelCase) as the canonical form to match the system-level action name. source-
Resource path in the form
system/<name>/<objectType>identifying the object type to sync. Thesystem/prefix is optional here too, per Resource paths and operations.
Sync failure handling
The syncFailureHandler object in the connector configuration controls what happens when processing a sync delta fails.
syncFailureHandler configuration{
"syncFailureHandler": {
"maxRetries": 5,
"postRetryAction": "dead-letter-queue"
}
}
maxRetries-
Number of retry attempts before invoking
postRetryAction.-1or absent means retry indefinitely, andpostRetryActionis never called.0means callpostRetryActionimmediately on first failure without retrying. postRetryAction-
Action taken when retries are exhausted. Accepts a string shorthand or a script object:
"dead-letter-queue"-
Persists the failed sync delta to
repo/synchronisation/deadLetterQueue/<systemIdentifier>/<token>. The stored document contains the following top-level fields:-
token: the sync token value, also used as the resource ID. -
systemIdentifier: the connector name, also used as the sub-path. -
objectType: the object type being synced. -
uid: the ICF UID of the affected object. -
failedRecord: the connector object payload at the time of failure, if available. -
failureCause: the exception message string.Query or drain the queue via the standard repository API at that path.
-
"logged-ignore"-
Logs the failure and discards the delta.
{ "script": { … } }-
Calls a custom script. The inner
scriptobject uses the standard Wren:IDM script registry format. Set"type"to the language identifier (e.g."groovy","javascript"). Supply the script body via"source"(inline text) or"file"(path to a script file). See Scripts for the full field reference and supported engines. The script receives the following bindings:-
context: request context. -
syncFailure: map with keystoken,systemIdentifier,objectType,uid, andfailedRecord. -
failureCause: the exception that caused the failure. -
failureHandlers: a map with pre-built"loggedIgnore"and"deadLetterQueue"handler instances the script can delegate to.
-
Omitting syncFailureHandler entirely has the same effect as an absent maxRetries: sync deltas are retried indefinitely.
|
Script system actions
The systemActions list defines named scripts that execute on the connector or the target resource via the script action at /system/<name>.
systemActions entry{
"systemActions": [
{
"scriptId": "resetPassword",
"actions": [
{
"systemType": "provisioner.openicf.*",
"actionType": "Groovy",
"actionSource": "// Groovy script body"
}
]
}
]
}
scriptId-
The action name, passed as the
scriptIdquery parameter when invoking thescriptaction at/system/<name>. For example:POST /system/ldap?_action=script&scriptId=resetPassword. Required. actions-
List of system type-specific script entries. The
systemTypevalue is matched as a regular expression against the provisioner type string (e.g.provisioner.openicf). Required.systemType-
Regular expression matched against the provisioner type. Required.
actionType-
Script language identifier (e.g.
Groovy,JavaScript). Required. actionSource-
Inline script text. Mutually exclusive with
actionFile. actionFile-
Path to a script file, resolved against the Wren:IDM project root. Mutually exclusive with
actionSource. When both are present,actionFiletakes precedence andactionSourceis ignored.