OpenIDM configuration is split between .properties and container
configuration files, and also dynamic configuration objects. The majority
of OpenIDM configuration files are stored under
openidm/conf/, as described in the appendix listing the
File
Layout.
OpenIDM stores configuration objects in its internal repository. You can manage the configuration by using either the REST access to the configuration objects, or by using the JSON file based views.
OpenIDM exposes internal configuration objects in JSON format. Configuration elements can be either single instance or multiple instance for an OpenIDM installation.
Single instance configuration objects correspond to services that have at most one instance per installation.
JSON file views of these configuration objects are named
.object-name.json
The audit configuration specifies how audit
events are logged.
The authentication configuration controls
REST access.
The endpoint configuration controls any custom
REST endpoints.
The managed configuration defines managed
objects and their schemas.
The policy configuration defines the policy
validation service.
The process access configuration defines access
to any configured workflows.
The repo.
configuration such as repo-typerepo.orientdb or
repo.jdbc configures the internal repository.
The router configuration specifies filters to
apply for specific operations.
The sync configuration defines the mappings that
OpenIDM uses when synchronizing and reconciling managed objects.
The ui configuration defines the configurable
aspects of the default user interface.
The workflow configuration defines the
configuration of the workflow engine.
Multiple instance configuration objects correspond to services that
can have many instances per installation. Configuration objects are named
,
for example, objectname/instancenameprovisioner.openicf/xml.
JSON file views of these configuration objects
are named , for example,
objectname-instancename.jsonprovisioner.openicf-xml.json.
Multiple schedule configurations can run
reconciliations and other tasks on different schedules.
Multiple provisioner.openicf configurations
correspond to the resources connected to OpenIDM.
When you change OpenIDM's configuration objects, take the following points into account.
OpenIDM's authoritative configuration source is the internal repository. JSON files provide a view of the configuration objects, but do not represent the authoritative source.
OpenIDM updates JSON files after making configuration changes, whether those changes are made through REST access to configuration objects, or through edits to the JSON files.
OpenIDM recognizes changes to JSON files when it is running. OpenIDM must be running when you delete configuration objects, even if you do so by editing the JSON files.
Avoid editing configuration objects directly in the internal repository. Rather edit the configuration over the REST API, or in the configuration JSON files to ensure consistent behavior and that operations are logged.
OpenIDM stores its configuration in the internal database by
default. If you remove an OpenIDM instance and do not specifically
drop the repository, the configuration remains in effect for a
new OpenIDM instance that uses that repository. For testing or
evaluation purposes, you can disable this persistent
configuration in the conf/system.properties
file by uncommenting the following line:
# openidm.config.repo.enabled=false
Disabling persistent configuration means that OpenIDM will store its configuration in memory only. You should not disable persistent configuration in a production environment.
Out of the box, OpenIDM is configured to make it easy to install and evaluate. Specific configuration changes are required before you deploy OpenIDM in a production environment.
By default, OpenIDM uses OrientDB for its internal repository so that you do not have to install a database in order to evaluate OpenIDM. Before you use OpenIDM in production, you must replace OrientDB with a supported repository.
For more information, see Installing a Repository for Production in the Installation Guide.
By default, OpenIDM polls the JSON files in the
conf directory periodically for any changes to
the configuration. In a production system, it is recommended that
you disable automatic polling for updates to prevent untested
configuration changes from disrupting your identity service.
To disable automatic polling for configuration changes, edit the
conf/system.properties file by uncommenting the
following line:
# openidm.fileinstall.enabled=false
Before you disable automatic polling, you must have started the OpenIDM instance at least once to ensure that the configuration has been loaded into the database.
Note that scripts are loaded each time the configuration calls the script. Modifications to scripts are therefore not applied dynamically. If you modify a script, you must either modify the configuration that calls the script, or restart the component that uses the modified script. You do not need to restart OpenIDM for script modifications to take effect.
To control configuration changes to the OpenIDM system, you
disable the file-based configuration view and have OpenIDM read its
configuration only from the repository. To disable the file-based
configuration view, edit the conf/system.properties
file to uncomment the following line:
# openidm.fileinstall.enabled=false.
OpenIDM exposes configuration objects under the
/openidm/config context.
You can list the configuration on the local host by performing a GET
http://localhost:8080/openidm/config. The following
example shows the default configuration for an OpenIDM instance started
with Sample 1.
$ curl --request GET
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
http://localhost:8080/openidm/config
{
"configurations": [
{
"_id": "endpoint/getprocessesforuser",
"pid": "endpoint.788f364e-d870-4f46-982a-793525fff6f0",
"factoryPid": "endpoint"
},
{
"_id": "provisioner.openicf/xml",
"pid": "provisioner.openicf.90b18af9-fe27-45a2-a4ae-1056c04a4d31",
"factoryPid": "provisioner.openicf"
},
{
"_id": "ui/configuration",
"pid": "ui.36bb2bf4-8e19-43d2-9df2-a0553ffac590",
"factoryPid": "ui"
},
{
"_id": "managed",
"pid": "managed",
"factoryPid": null
},
{
"_id": "sync",
"pid": "sync",
"factoryPid": null
},
{
"_id": "router",
"pid": "router",
"factoryPid": null
},
{
"_id": "process/access",
"pid": "process.44743c97-a01b-4562-85ad-8a2c9b89155a",
"factoryPid": "process"
},
{
"_id": "endpoint/siteIdentification",
"pid": "endpoint.ef05a7f3-a420-4fbb-998c-02d283cae4d1",
"factoryPid": "endpoint"
},
{
"_id": "endpoint/securityQA",
"pid": "endpoint.e2d87637-c918-4056-99a1-20f25c897066",
"factoryPid": "endpoint"
},
{
"_id": "scheduler",
"pid": "scheduler",
"factoryPid": null
},
{
"_id": "ui/countries",
"pid": "ui.acde0f4c-808f-45fb-9627-d7d2ca702e7c",
"factoryPid": "ui"
},
{
"_id": "org.apache.felix.fileinstall/openidm",
"pid": "org.apache.felix.fileinstall.2dedea63-4592-4074-a709-ffa70f1e841d",
"factoryPid": "org.apache.felix.fileinstall"
},
{
"_id": "schedule/reconcile_systemXmlAccounts_managedUser",
"pid": "schedule.f53b235a-862e-4e18-a3cf-10ae3cbabc1e",
"factoryPid": "schedule"
},
{
"_id": "workflow",
"pid": "workflow",
"factoryPid": null
},
{
"_id": "endpoint/getavailableuserstoassign",
"pid": "endpoint.d19da94f-bae3-4101-922c-fe47ea8616d2",
"factoryPid": "endpoint"
},
{
"_id": "repo.orientdb",
"pid": "repo.orientdb",
"factoryPid": null
},
{
"_id": "audit",
"pid": "audit",
"factoryPid": null
},
{
"_id": "endpoint/gettasksview",
"pid": "endpoint.edcc1ff8-a7ba-4c46-8258-bf5216e85192",
"factoryPid": "endpoint"
},
{
"_id": "ui/secquestions",
"pid": "ui.649e2c65-0cc7-4a0d-a6b1-95f4c5168bdc",
"factoryPid": "ui"
},
{
"_id": "org.apache.felix.fileinstall/activiti",
"pid": "org.apache.felix.fileinstall.a0ba2f7d-bdb9-43b5-b84e-0e8feee6be72",
"factoryPid": "org.apache.felix.fileinstall"
},
{
"_id": "policy",
"pid": "policy",
"factoryPid": null
},
{
"_id": "endpoint/usernotifications",
"pid": "endpoint.e96d5319-6260-41db-af76-bd4e692b792d",
"factoryPid": "endpoint"
},
{
"_id": "org.apache.felix.fileinstall/ui",
"pid": "org.apache.felix.fileinstall.89f8c6dd-f54e-46a4-bfda-1e76ac044c33",
"factoryPid": "org.apache.felix.fileinstall"
},
{
"_id": "authentication",
"pid": "authentication",
"factoryPid": null
}
]
}Single instance configuration objects are located under
openidm/config/.
The following example shows the default object-nameaudit
configuration.
$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
http://localhost:8080/openidm/config/audit
{
"eventTypes": {
"activity": {
"filter": {
"actions": [
"create",
"update",
"delete",
"patch",
"action"
]
}
},
"recon": {}
},
"logTo": [
{
"logType": "csv",
"location": "audit",
"recordDelimiter": ";"
},
{
"logType": "repository"
}
]
}Multiple instance configuration objects are found under
openidm/config/. The following example shows the
configuration for the XML connector provisioner.object-name/instance-name
$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
http://localhost:8080/openidm/config/provisioner.openicf/xml
{
"name": "xmlfile",
"connectorRef": {
"bundleName":
"org.forgerock.openicf.connectors.file.openicf-xml-connector",
"bundleVersion": "",
"connectorName": "com.forgerock.openicf.xml.XMLConnector"
},
"producerBufferSize": 100,
"connectorPoolingSupported": true,
"poolConfigOption": {
"maxObjects": 10,
"maxIdle": 10,
"maxWait": 150000,
"minEvictableIdleTimeMillis": 120000,
"minIdle": 1
},
"operationTimeout": {
"CREATE": -1,
"TEST": -1,
"AUTHENTICATE": -1,
"SEARCH": -1,
"VALIDATE": -1,
"GET": -1,
"UPDATE": -1,
"DELETE": -1,
"SCRIPT_ON_CONNECTOR": -1,
"SCRIPT_ON_RESOURCE": -1,
"SYNC": -1,
"SCHEMA": -1
},
"configurationProperties": {
"xsdIcfFilePath": "samples/sample1/data/resource-schema-1.xsd",
"xsdFilePath": "samples/sample1/data/resource-schema-extension.xsd",
"xmlFilePath": "samples/sample1/data/xmlConnectorData.xml"
},
"objectTypes": {
"account": {
"$schema": "http://json-schema.org/draft-03/schema",
"id": "__ACCOUNT__",
"type": "object",
"nativeType": "__ACCOUNT__",
"properties": {
"description": {
"type": "string",
"nativeName": "__DESCRIPTION__",
"nativeType": "string"
},
"firstname": {
"type": "string",
"nativeName": "firstname",
"nativeType": "string"
},
"email": {
"type": "string",
"nativeName": "email",
"nativeType": "string"
},
"__UID__": {
"type": "string",
"nativeName": "__UID__"
},
"password": {
"type": "string",
"required": false,
"nativeName": "__PASSWORD__",
"nativeType": "JAVA_TYPE_GUARDEDSTRING",
"flags": [
"NOT_READABLE",
"NOT_RETURNED_BY_DEFAULT"
]
},
"name": {
"type": "string",
"required": true,
"nativeName": "__NAME__",
"nativeType": "string"
},
"lastname": {
"type": "string",
"required": true,
"nativeName": "lastname",
"nativeType": "string"
}
}
}
},
"operationOptions": {}
}You can change the configuration over REST by using an HTTP PUT request
to modify the required configuration object. The following example modifies
the router.json file to remove all filters, effectively
bypassing any policy validation.
$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request PUT
--data '{
"filters" : [
{
"onRequest" : {
"type" : "text/javascript",
"file" : "bin/defaults/script/router-authz.js"
}
}
]
}'
"http://localhost:8080/openidm/config/router"
See the REST API Reference appendix for additional details and examples using REST access to update and patch objects.
In an environment where you have more than one OpenIDM instance, you might require a configuration that is similar, but not identical, across the different OpenIDM hosts. OpenIDM supports variable replacement in its configuration which means that you can modify the effective configuration according to the requirements of a specific environment or OpenIDM instance.
Property substitution enables you to achieve the following:
Define a configuration that is specific to a single OpenIDM instance, for example, setting the location of the keystore on a particular host.
Define a configuration whose parameters vary between different environments, for example, the URLs and passwords for test, development, and production environments.
Disable certain capabilities on specific nodes. For example, you might want to disable the workflow engine on specific instances.
When OpenIDM starts up, it combines the system configuration, which might contain specific environment variables, with the defined OpenIDM configuration properties. This combination makes up the effective configuration for that OpenIDM instance. By varying the environment properties, you can change specific configuration items that vary between OpenIDM instances or environments.
Property references are contained within the construct
&{ }. When such references are found, OpenIDM replaces
them with the appropriate property value, defined in the
boot.properties file.
The following example defines two separate OpenIDM environments - a development environment and a production environment. You can specify the environment at startup time and, depending on the environment, the database URL is set accordingly.
The environments are defined by adding the following lines to the
conf/boot.properties file:
PROD.location=production DEV.location=development
The database URL is then specified as follows in the
repo.orientdb.json file:
{
"dbUrl" : "local:./db/&{&{environment}.location}-openidm",
"user" : "admin",
"poolMinSize" : 5,
"poolMaxSize" : 20,
...
}
The effective database URL is determined by setting the
OPENIDM_OPTS environment variable when you start OpenIDM.
To use the production environment, start OpenIDM as follows:
$ export OPENIDM_OPTS="-Xmx1024m -Denvironment=PROD" $ ./startup.sh
To use the development environment, start OpenIDM as follows:
$ export OPENIDM_OPTS="-Xmx1024m -Denvironment=DEV" $ ./startup.sh
You can use property value substitution in conjunction with the system properties, to modify the configuration according to the system on which the OpenIDM instance runs.
The following example modifies the audit.json file so
that the log file is written to the user's directory. The
user.home property is a default Java System property.
{
"logTo" : [
{
"logType" : "csv",
"location" : "&{user.home}/audit",
"recordDelimiter" : ";"
}
]
}
You can define nested properties (that is a property definition within another property definition) and you can combine system properties and boot properties.
The following example uses the user.country property,
a default Java System property. The example defines specific LDAP ports,
depending on the country (identified by the country code) in the
boot.properties file. The value of the LDAP port (set in
the provisioner.openicf-ldap.json file) depends on the
value of the user.country System property.
The port numbers are defined in the boot.properties
file as follows:
openidm.NO.ldap.port=2389 openidm.EN.ldap.port=3389 openidm.US.ldap.port=1389
The following extract from the
provisioner.openicf-ldap.json file shows how the value of
the LDAP port is eventually determined, based on the System property:
"configurationProperties" :
{
"credentials" : "Passw0rd",
"port" : "&{openidm.&{user.country}.ldap.port}",
"principal" : "cn=Directory Manager",
"baseContexts" :
[
"dc=example,dc=com"
],
"host" : "localhost"
}
Note the following limitations when you use property value substitution:
You cannot reference complex objects or properties with syntaxes
other than String. Property values are resolved from the
boot.properties file or from the System properties and the
value of these properties is always in String format.
Property substitution of boolean values is currently only supported in
stringified format, that is, resulting in "true" or
"false".
Substitution of encrypted property values is currently not supported.
You can customize OpenIDM to meet the specific requirements of your
deployment by adding your own RESTful endpoints. Endpoints are configured
in files named conf/endpoint-,
where name.jsonname generally describes the purpose of the
endpoint.
A sample custom endpoint configuration is provided at
openidm/samples/customendpoint. The sample includes
two files:
conf/endpoint-echo.json, which provides the
configuration for the endpoint. |
script/echo.js, which is launched when the
endpoint is accessed. |
The structure of an endpoint configuration file is as follows:
{
"context" : "endpoint/echo",
"type" : "text/javascript",
"file" : "script/echo.js"
}
"context"The URL context under which the endpoint is registered.
Currently this must be under
endpoint/. An endpoint registered under the
context endpoint/echo is addressable over REST at
http://localhost:8080/openidm/endpoint/echo and
with the internal resource API, for example
openidm.read("endpoint/echo").
"type"The type of implementation. Currently only
"text/javascript" is supported.
"source" or "fileThe actual script, inline, or a pointer to the file that
contains the script. The sample script,
(samples/customendpoint/script/echo.js) simply
returns the HTTP request when a request is made on that endpoint.
The endpoint script has a request variable
available in its scope. The request structure carries all the information
about the request, and includes the following properties:
idThe local ID, without the endpoint/ prefix,
for example, echo.
methodThe requested operation, that is, create,
read, update,
delete, patch,
query or action.
paramsThe parameters that are passed in. For example, for an HTTP GET
with ?param=x, the request contains
"params":{"param":"x"}.
parentProvides the context for the invocation, including headers and security.
Note that the interface for this context is still evolving and may change in a future release.
A script implementation should check and reject requests for methods
that it does not support. For example, the following implementation
supports only the read method:
if (request.method == "read") {
...
} else {
throw "Unsupported operation: " + request.method;
}
The final statement in the script is the return value. Unlike for
functions, at this global scope there is no return
keyword. In the following example, the value of the last statement
(x) is returned.
var x = "Sample return"
functioncall();
x
The following example uses the sample provided in
openidm/samples/customendpoint and shows the complete
request structure, which is returned by the query.
$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request GET
"http://localhost:8080/openidm/endpoint/echo?param=x"
{
"type": "resource",
"uuid": "21c5ddc6-a66e-464e-9fa4-9b777505799e",
"params": {
"param": "x"
},
"method": "query",
"parent": {
"path": "/openidm/endpoint/echo",
"headers": {
"Accept": "*/*",
"User-Agent": "curl/7.21.4 ... OpenSSL/0.9.8r zlib/1.2.5",
"Authorization": "Basic b3BlbmlkbS1hZG1pbjpvcGVuaWRtLWFkbWlu",
"Host": "localhost:8080"
},
"query": {
"param": "x"
},
"method": "GET",
"parent": {
"uuid": "bec97cbf-8618-42f8-a841-9f5f112538e9",
"parent": null,
"type": "root"
},
"type": "http",
"uuid": "7fb3e0d9-5f56-4b15-b710-28f2147cf4b4",
"security": {
"openidm-roles": [
"openidm-admin",
"openidm-authorized"
],
"username": "openidm-admin",
"userid": {
"component": "internal/user",
"id": "openidm-admin"
}
}
},
"id": "echo"
}
You must protect access to any custom endpoints by configuring the appropriate authorization for those contexts. For more information, see the Authorization section.