---
title: Configure connectors
description: You configure connectors through the ICF provisioner service, and access them over REST at the openidm/conf endpoint.
component: openicf
page_id: openicf:connector-reference:configure-connector
canonical_url: https://docs.pingidentity.com/openicf/connector-reference/configure-connector.html
section_ids:
  sample-provisioner-files: Sample provisioner files
  connector-wiz-adminui: Configure connectors with the admin UI
  connector-wiz-REST: Configure connectors over REST
  connector-reference-props: Connector reference properties
  pool-configuration-option: Pool configuration
  operation-timeout: Operation timeouts
  operation-rate-limits: Operation rate limits
  configuration-properties: Connection configuration
  sync-failure-handler: Synchronization failure configuration
  results-handler-config: Configure how results are handled
  exclude-unmodified: Specify which attributes are updated
  object-types: Set the supported object types
  object-extensions-ui: Add objects and properties through the UI
  object-level-extensions: Specify object types on the external resource
  empty-attributes: Behavior for empty attributes
  property-level-extensions: Specify attribute types on the external resource
  operation-options: Configure operation options
---

# Configure connectors

You configure connectors through the ICF provisioner service, and access them over REST at the `openidm/conf` endpoint.

Connector configurations are stored in files in your project's `conf/` directory, and are named `project-dir/conf/provisioner.openicf-name` where *name* corresponds to the name of the connector. If you are creating your own connector configuration files, *do not* include additional dash characters (`-`) in the connector name, as this can cause problems with the OSGi parser. For example, `provisioner.openicf-hrdb.json` is acceptable, and `provisioner.openicf-hr-db.json` is not.

You can create a connector configuration in the following ways:

* Start with the sample provisioner files in the `/path/to/openidm/samples/example-configurations/provisioners` directory. Learn more in the [Sample Provisioner Files](#sample-provisioner-files).

* Configure connectors in the admin UI. Sign on to the admin UI at `https://localhost:8443/admin`, then continue with the process described in [Configure Connectors With the admin UI](#connector-wiz-adminui).

* Use the service that IDM exposes through the REST interface to create basic connector configuration files. Learn more in [Configure Connectors Over REST](#connector-wiz-REST).

* Use the `cli.sh` or `cli.bat` scripts to generate a basic connector configuration. Learn more in the [`configureconnector`](https://docs.pingidentity.com/pingidm/8/setup-guide/chap-cli.html#cli-configureconnector) documentation.

## Sample provisioner files

A number of sample connector configurations are available in the `openidm/samples/example-configurations/provisioners` directory. To use these connector configurations, edit the configuration files as required, and copy them to your project's `conf` directory.

The following example shows a high-level connector configuration. The individual configuration objects are described in detail later in this section:

```json
{
  "connectorRef"              : connector-ref-object,
  "producerBufferSize"        : integer,
  "poolConfigOption"          : pool-config-option-object,
  "operationTimeout"          : operation-timeout-object,
  "operationRateLimits"       : operation-rate-limits-object,
  "configurationProperties"   : configuration-properties-object,
  "syncFailureHandler"        : sync-failure-handler-object,
  "resultsHandlerConfig"      : results-handler-config-object,
  "excludeUnmodified"         : boolean, true/false,
  "objectTypes"               : object-types-object,
  "operationOptions"          : operation-options-object
}
```

## Configure connectors with the admin UI

To configure connectors in the admin UI, select Configure > Connector.

If your project has an existing connector configuration (for example, if you have started IDM with one of the sample configurations), click on that connector to edit it. If you're starting with a new project, click New Connector to configure a new connector.

The connectors displayed on the Connectors page reflect the provisioner files in your project's `conf/` directory. To add a new connector configuration, you can also copy a provisioner file from the `/path/to/openidm/samples/example-configurations/provisioners` directory, then edit it to fit your deployment.

When you add a new connector, the Connector Type dropdown list reflects the connector .jar files that are in the `/path/to/openidm/connectors` directory. You can have more than one connector configuration for a specific connector type. For example, you might use the LDAP connector to set up two connector configurations—one to an Active Directory server and one to a PingDS (DS) instance.

The Connector Types listed here do not include all supported connectors. The *scripted* connectors (such as scripted Groovy, scripted REST, scripted SQL, and PowerShell) are not available in the list of connector types. In general, the scripted connectors require extensive custom configuration changes, and a single HTML template to cover all possible permutations is not feasible. To add a scripted connector configuration, [configure the connector over REST](#connector-wiz-REST).

Alternatively, copy one of the example provisioner files in `/path/to/openidm/samples/example-configurations/provisioners` into your project's `conf` directory and edit the configuration directly in the provisioner file.

Additional connectors are available from the [Backstage download site](https://backstage.forgerock.com/downloads) site. For connectors that are not bundled with IDM, the UI displays a generic template, based on the schema provided by the connector.

The tabs on the connector configuration screens correspond to the objects and properties described in the remaining sections of this chapter.

When a connector configuration is complete, and IDM is able to establish the connection to the remote resource, the Data tab displays the objects in that remote resource. For example, the following image shows the contents of a connected LDAP resource:

![connector-config-data](_images/connector-config-data.png)Figure 1. Data Tab For a Connected LDAP Resource

You can search through these objects with either the Basic Filter shown in each column, or the Advanced Filter option, which lets you build many of the queries shown in [Define and call data queries](https://docs.pingidentity.com/pingidm/8/objects-guide/queries.html).

## Configure connectors over REST

To create a new connector configuration over REST, follow these steps:

1. List the available connectors.

2. Generate the core configuration.

3. Add the target system properties, then connect to the target system to generate the final configuration.

4. Submit the final configuration to IDM.

This procedure walks you through creating a connector configuration over REST, for a CSV file connector.

1. List the available connectors.

   In a default IDM installation, the available connectors are installed in the `openidm/connectors` directory. If you are using a remote connector server, additional connectors might be available in the `openicf/connectors` directory on the remote server.

   Run the following command to list the available connectors:

   ```
   curl \
   --header "X-OpenIDM-Username: openidm-admin" \
   --header "X-OpenIDM-Password: openidm-admin" \
   --header "Accept-API-Version: resource=1.0" \
   --request POST \
   "http://localhost:8080/openidm/system?_action=availableConnectors"
   ```

   On a default IDM installation, this command returns the following output:

   > **Collapse: Sample output**
   >
   > ```json
   > {
   >   "connectorRef": [
   >     {
   >       "displayName": "SSH Connector",
   >       "bundleVersion": "1.5.20.34",
   >       "systemType": "provisioner.openicf",
   >       "bundleName": "org.forgerock.openicf.connectors.ssh-connector",
   >       "connectorName": "org.forgerock.openicf.connectors.ssh.SSHConnector"
   >     },
   >     {
   >       "displayName": "ServiceNow Connector",
   >       "bundleVersion": "1.5.20.34",
   >       "systemType": "provisioner.openicf",
   >       "bundleName": "org.forgerock.openicf.connectors.servicenow-connector",
   >       "connectorName": "org.forgerock.openicf.connectors.servicenow.ServiceNowConnector"
   >     },
   >     {
   >       "displayName": "Scripted SQL Connector",
   >       "bundleVersion": "1.5.20.34",
   >       "systemType": "provisioner.openicf",
   >       "bundleName": "org.forgerock.openicf.connectors.scriptedsql-connector",
   >       "connectorName": "org.forgerock.openicf.connectors.scriptedsql.ScriptedSQLConnector"
   >     },
   >     {
   >       "displayName": "Scripted REST Connector",
   >       "bundleVersion": "1.5.20.34",
   >       "systemType": "provisioner.openicf",
   >       "bundleName": "org.forgerock.openicf.connectors.scriptedrest-connector",
   >       "connectorName": "org.forgerock.openicf.connectors.scriptedrest.ScriptedRESTConnector"
   >     },
   >     {
   >       "displayName": "SCIM Connector",
   >       "bundleVersion": "1.5.20.34",
   >       "systemType": "provisioner.openicf",
   >       "bundleName": "org.forgerock.openicf.connectors.scim-connector",
   >       "connectorName": "org.forgerock.openicf.connectors.scim.ScimConnector"
   >     },
   >     {
   >       "displayName":"Salesforce Connector",
   >       "bundleVersion":"1.5.20.34",
   >       "systemType":"provisioner.openicf",
   >       "bundleName":"org.forgerock.openicf.connectors.salesforce-connector",
   >       "connectorName":"org.forgerock.openicf.connectors.salesforce.SalesforceConnector"
   >     },
   >     {
   >       "displayName":"MSGraphAPI Connector",
   >       "bundleVersion":"1.5.20.34",
   >       "systemType":"provisioner.openicf",
   >       "bundleName":"org.forgerock.openicf.connectors.msgraphapi-connector",
   >       "connectorName":"org.forgerock.openicf.connectors.msgraphapi.MSGraphAPIConnector"
   >     },
   >     {
   >       "displayName": "MongoDB Connector",
   >       "bundleVersion": "1.5.20.34",
   >       "systemType": "provisioner.openicf",
   >       "bundleName": "org.forgerock.openicf.connectors.mongodb-connector",
   >       "connectorName": "org.forgerock.openicf.connectors.mongodb.MongoDBConnector"
   >     },
   >     {
   >       "displayName": "Marketo Connector",
   >       "bundleVersion": "1.5.20.34",
   >       "systemType": "provisioner.openicf",
   >       "bundleName": "org.forgerock.openicf.connectors.marketo-connector",
   >       "connectorName": "org.forgerock.openicf.connectors.marketo.MarketoConnector"
   >     },
   >     {
   >       "displayName": "LDAP Connector",
   >       "bundleVersion": "1.5.20.34",
   >       "systemType": "provisioner.openicf",
   >       "bundleName": "org.forgerock.openicf.connectors.ldap-connector",
   >       "connectorName": "org.identityconnectors.ldap.LdapConnector"
   >     },
   >     {
   >       "displayName": "Kerberos Connector",
   >       "bundleVersion": "1.5.20.34",
   >       "systemType": "provisioner.openicf",
   >       "bundleName": "org.forgerock.openicf.connectors.kerberos-connector",
   >       "connectorName": "org.forgerock.openicf.connectors.kerberos.KerberosConnector"
   >     },
   >     {
   >       "displayName": "Scripted Poolable Groovy Connector",
   >       "bundleVersion": "1.5.20.34",
   >       "systemType": "provisioner.openicf",
   >       "bundleName": "org.forgerock.openicf.connectors.groovy-connector",
   >       "connectorName": "org.forgerock.openicf.connectors.groovy.ScriptedPoolableConnector"
   >     },
   >     {
   >       "displayName": "Scripted Groovy Connector",
   >       "bundleVersion": "1.5.20.34",
   >       "systemType": "provisioner.openicf",
   >       "bundleName": "org.forgerock.openicf.connectors.groovy-connector",
   >       "connectorName": "org.forgerock.openicf.connectors.groovy.ScriptedConnector"
   >     },
   >     {
   >       "displayName": "GoogleApps Connector",
   >       "bundleVersion": "1.5.20.34",
   >       "systemType": "provisioner.openicf",
   >       "bundleName": "org.forgerock.openicf.connectors.googleapps-connector",
   >       "connectorName": "org.forgerock.openicf.connectors.googleapps.GoogleAppsConnector"
   >     },
   >     {
   >       "displayName": "Database Table Connector",
   >       "bundleVersion": "1.5.20.34",
   >       "systemType": "provisioner.openicf",
   >       "bundleName": "org.forgerock.openicf.connectors.databasetable-connector",
   >       "connectorName": "org.identityconnectors.databasetable.DatabaseTableConnector"
   >     },
   >     {
   >       "displayName": "CSV File Connector",
   >       "bundleVersion": "1.5.20.34",
   >       "systemType": "provisioner.openicf",
   >       "bundleName": "org.forgerock.openicf.connectors.csvfile-connector",
   >       "connectorName": "org.forgerock.openicf.csvfile.CSVFileConnector"
   >     },
   >     {
   >       "displayName": "Adobe Marketing Cloud Connector",
   >       "bundleVersion": "1.5.20.34",
   >       "systemType": "provisioner.openicf",
   >       "bundleName": "org.forgerock.openicf.connectors.adobecm-connector",
   >       "connectorName": "org.forgerock.openicf.acm.ACMConnector"
   >     }
   >   ]
   > }
   > ```

2. Generate a core configuration.

   Locate the connector to configure from the previous step's output, and copy the JSON object to insert as the value of the `"connectorRef"` property in the `data` payload of the following command.

   This example generates a core configuration for the CSV file connector:

   ```
   curl \
   --header "X-OpenIDM-Username: openidm-admin" \
   --header "X-OpenIDM-Password: openidm-admin" \
   --header "Accept-API-Version: resource=1.0" \
   --header "Content-Type: application/json" \
   --request POST \
   --data '{
     "connectorRef": {
       "systemType": "provisioner.openicf",
       "bundleName": "org.forgerock.openicf.connectors.csvfile-connector",
       "connectorName": "org.forgerock.openicf.csvfile.CSVFileConnector",
       "displayName": "CSV File Connector",
       "bundleVersion": "1.5.20.34"
     }
   }' \
   "http://localhost:8080/openidm/system?_action=createCoreConfig"
   ```

   The command returns a connector configuration, similar to the following:

   ```json
   {
     "connectorRef": {
       "systemType": "provisioner.openicf",
       "bundleName": "org.forgerock.openicf.connectors.csvfile-connector",
       "connectorName": "org.forgerock.openicf.csvfile.CSVFileConnector",
       "displayName": "CSV File Connector",
       "bundleVersion": "1.5.20.34"
     },
     "resultsHandlerConfig": {
       "enableNormalizingResultsHandler": false,
       "enableFilteredResultsHandler": false,
       "enableCaseInsensitiveFilter": false,
       "enableAttributesToGetSearchResultsHandler": true
     },
     "operationTimeout": {
       "CREATE": 15000,
       "UPDATE": 15000,
       "DELETE": 15000,
       "TEST": 5000,
       "SCRIPT_ON_CONNECTOR": 15000,
       "SCRIPT_ON_RESOURCE": 15000,
       "GET": 15000,
       "RESOLVEUSERNAME": 10000,
       "AUTHENTICATE": 10000,
       "SEARCH": 15000,
       "VALIDATE": 5000,
       "SYNC": 15000,
       "SCHEMA": 10000
     },
     "configurationProperties": {
       "headerPassword": "password",
       "spaceReplacementString": "_",
       "csvFile": null,
       "newlineString": "\n",
       "headerUid": "uid",
       "quoteCharacter": "\"",
       "escapeCharacter": "\\",
       "fieldDelimiter": ",",
       "syncFileRetentionCount": 3
     }
   }
   ```

3. Connect to the target system to generate the final configuration.

   The configuration returned in the previous step is not functional. It does not include the required `configurationProperties` that are specific to the target system (such as the host name and port number of the target system, or the `csvFile` for a CSV file connector). It also doesn't include the complete list of `objectTypes` and `operationOptions`.

   To connect to the target system, add values for the required `configurationProperties`, and submit the updated configuration in the data payload of the following command.

   This example connects to the specified CSV file:

   ```
   curl \
   --header "X-OpenIDM-Username: openidm-admin" \
   --header "X-OpenIDM-Password: openidm-admin" \
   --header "Accept-API-Version: resource=1.0" \
   --header "Content-Type: application/json" \
   --request POST \
   --data '{
     "configurationProperties": {
       "headerPassword": "password",
       "spaceReplacementString": "_",
       "csvFile": "&{idm.instance.dir}/data/csvConnectorData.csv",
       "newlineString": "\n",
       "headerUid": "uid",
       "quoteCharacter": "\"",
       "fieldDelimiter": ",",
       "syncFileRetentionCount": 3
     },
     "connectorRef": {
       "systemType": "provisioner.openicf",
       "bundleName": "org.forgerock.openicf.connectors.csvfile-connector",
       "connectorName": "org.forgerock.openicf.csvfile.CSVFileConnector",
       "displayName": "CSV File Connector",
       "bundleVersion": "1.5.20.34"
     },
     "resultsHandlerConfig": {
       "enableNormalizingResultsHandler": true,
       "enableFilteredResultsHandler": true,
       "enableCaseInsensitiveFilter": false,
       "enableAttributesToGetSearchResultsHandler": true
     },
     "operationTimeout": {
       "CREATE": 15000,
       "UPDATE": 15000,
       "DELETE": 15000,
       "TEST": 5000,
       "SCRIPT_ON_CONNECTOR": 15000,
       "SCRIPT_ON_RESOURCE": 15000,
       "GET": 15000,
       "RESOLVEUSERNAME": 10000,
       "AUTHENTICATE": 10000,
       "SEARCH": 15000,
       "VALIDATE": 5000,
       "SYNC": 15000,
       "SCHEMA": 10000
     }
   }' \
   "http://localhost:8080/openidm/system?_action=createFullConfig"
   ```

   |   |                                                                                                                                                                                                                 |
   | - | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
   |   | The single quotes around the JSON object in the `--data` parameter prevent the command from being executed when a new line is encountered in the content. You can therefore include line feeds for readability. |

   With this command, IDM connects to the target resource, and attempts to read the schema, if it is available. It then iterates through the schema objects and attributes, and creates JSON representations of the supported objects and operations. The command output includes the JSON payload that you submitted, along with the `operationOptions` and `objectTypes`.

   |   |                                                                                                                                                                                                                                                                                                                                                                                              |
   | - | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
   |   | Because IDM produces a full property set for all attributes and all object types in the schema, the resulting configuration can be very large. For an LDAP server, for example, IDM can generate a configuration containing several tens of thousands of lines. It might be useful to reduce the schema on the external resource to a minimum before you run the `createFullConfig` command. |

4. When you have the final configuration, use a PUT request to add it to the IDM configuration, in the JSON payload of the following command:

   ```
   curl \
   --header "X-OpenIDM-Username: openidm-admin" \
   --header "X-OpenIDM-Password: openidm-admin" \
   --header "Accept-API-Version: resource=1.0" \
   --header "Content-Type: application/json" \
   --request PUT \
   --data '{complete-configuration}' \
   "http://localhost:8080/openidm/config/provisioner.openicf/connectorName"
   ```

   Alternatively, you can save the complete configuration in a file named `provisioner.openicf-connectorName.json`, and place the file in the `conf` directory of your project.

## Connector reference properties

The following example shows a connector reference object:

```json
"connectorRef" : {
    "bundleName"    : "org.forgerock.openicf.connectors.csvfile-connector",
    "bundleVersion" : "[1.5.0.0,1.6.0.0)",
    "connectorName" : "org.forgerock.openicf.csvfile.CSVFileConnector",
    "connectorHostRef" : "csv"
}
```

* `bundleName`

  string, required

  The `ConnectorBundle-Name` of the ICF connector.

* `bundleVersion`

  string, required

  The `ConnectorBundle-Version` of the ICF connector. The value can be a single version (such as `1.4.0.0`) or a range of versions, which lets you support multiple connector versions in a single project.

  You can specify a range of versions as follows:

  * `[1.1.0.0,1.4.0.0]` indicates that all connector versions from 1.1 to 1.4, inclusive, are supported.

  * `[1.1.0.0,1.4.0.0)` indicates that all connector versions from 1.1 to 1.4, including 1.1 but excluding 1.4, are supported.

  * `(1.1.0.0,1.4.0.0]` indicates that all connector versions from 1.1 to 1.4, excluding 1.1 but including 1.4, are supported.

  * `(1.1.0.0,1.4.0.0)` indicates that all connector versions from 1.1 to 1.4, exclusive, are supported.

  When a range of versions is specified, IDM uses the latest connector that is available within that range. If your project requires a specific connector version, you must explicitly state the version in your connector configuration file, or constrain the range to address only the version that you need.

* `connectorName`

  string, required

  The connector implementation class name.

* `connectorHostRef`

  string, optional

  If the connector runs remotely, the value of this field must match the `name` field of the `RemoteConnectorServers` object in the connector server configuration file (`provisioner.openicf.connectorinfoprovider.json`). For example:

  ```json
  ...
      "remoteConnectorServers" :
          [
              {
                  "name" : "dotnet",
                  ...
              }
          ]
  ...
  ```

  If the connector runs locally, the value of this field can be one of the following:

  * If the connector .jar is installed in `openidm/connectors/` , the value must be `"#LOCAL"`. This is currently the default, and recommended location.

  * If the connector .jar is installed in `openidm/bundle/` (not recommended), the value must be `"osgi:service/org.forgerock.openicf.framework.api.osgi.ConnectorManager"`.

## Pool configuration

Learn more about [Connection pooling configuration](pooling.html) and the connectors that use each pooling mechanism in [Connector by pooling mechanism](pooling.html#pooling-table).

## Operation timeouts

Use the `operationTimeout` property to configure timeout values for each operation type. Use the value `-1` to configure an operation to have no timeout.

Default operation timeouts

```json
{
  "CREATE"              : 15000,
  "UPDATE"              : 15000,
  "DELETE"              : 15000,
  "TEST"                : 5000,
  "SCRIPT_ON_CONNECTOR" : 15000,
  "SCRIPT_ON_RESOURCE"  : 15000,
  "GET"                 : 15000,
  "RESOLVEUSERNAME"     : 10000,
  "AUTHENTICATE"        : 10000,
  "SEARCH"              : 15000,
  "VALIDATE"            : 5000,
  "SYNC"                : 15000,
  "SCHEMA"              : 10000
}
```

* operation-name

  Timeout in milliseconds

  A value of `-1` disables the timeout.

## Operation rate limits

The `operationRateLimits` property enables you to configure rate limit values per operation type. By default, no rate limit is configured for any operation type. A sample configuration follows:

```json
"operationRateLimits": {
  "CREATE": {
    "requestLimit": 50,
    "requestPeriod": 500,
    "requestTimeout": 5000
  }
}
```

* `operation-name`

  * `requestLimit`

    The number of requests allowed over a period of time (`requestPeriod`). The default value is `50` requests.

  * `requestPeriod`

    The request limit resets after this period of time (in milliseconds). The default value is `500` milliseconds.

    For example, using the previous example configuration allows 50 requests in a 500 millisecond period of time.

  * `requestTimeout`

    The amount of time (in milliseconds) before throwing an `OperationTimeoutException` for an operation. The default is `5000` milliseconds (5 seconds).

## Connection configuration

The `configurationProperties` object specifies the configuration for the connection between the connector and the resource, and is therefore resource-specific.

The following example shows a configuration properties object for the default CSV sample resource connector:

```json
"configurationProperties" : {
    "csvFile" : "&{idm.instance.dir}/data/csvConnectorData.csv"
}
```

* property

  Individual properties depend on the type of connector.

## Synchronization failure configuration

The `syncFailureHandler` object specifies what should happen if a liveSync operation reports a failure for an operation. The following example shows a synchronization failure configuration:

```json
{
    "maxRetries" : 5,
    "postRetryAction" : "logged-ignore"
}
```

* `maxRetries`

  positive integer or `-1`, required

  The number of attempts that IDM should make to process a failed modification. A value of zero indicates that failed modifications should not be reattempted. In this case, the post retry action is executed immediately when a liveSync operation fails. A value of -1 (or omitting the `maxRetries` property, or the entire `syncFailureHandler` object) indicates that failed modifications should be retried an infinite number of times. In this case, no post retry action is executed.

* `postRetryAction`

  string, required

  The action that should be taken if the synchronization operation fails after the specified number of attempts. The post retry action can be one of the following:

  * `logged-ignore` - IDM ignores the failed modification, and logs its occurrence.

  * `dead-letter-queue` - IDM saves the details of the failed modification in a table in the repository (accessible over REST at `repo/synchronisation/deadLetterQueue/provisioner-name`).

  * `script` specifies a custom script that should be executed when the maximum number of retries has been reached.

  Learn more in [Configure the LiveSync Retry Policy](https://docs.pingidentity.com/pingidm/8/synchronization-guide/chap-implicit-live-sync.html#livesync-retry-strategy).

## Configure how results are handled

The `resultsHandlerConfig` object specifies how OpenICF returns results. These configuration properties do not apply to all connectors and depend on the interfaces that are implemented by each connector. For information about the interfaces that connectors support, refer to the [Connector reference](preface.html).

The following example shows a results handler configuration object:

```json
"resultsHandlerConfig" : {
    "enableNormalizingResultsHandler" : true,
    "enableFilteredResultsHandler" : false,
    "enableCaseInsensitiveFilter" : false,
    "enableAttributesToGetSearchResultsHandler" : false
}
```

* `enableNormalizingResultsHandler`

  boolean, false by default

  When this property is enabled, ICF normalizes returned attributes to ensure that they are filtered consistently. If the connector implements the attribute normalizer interface, enable the interface by setting this property to `true`. If the connector does not implement the attribute normalizer interface, the value of this property has no effect.

* `enableFilteredResultsHandler`

  boolean, false by default

  Most connectors use the filtering and search capabilities of the remote connected system. In these cases, you can leave this property set to `false`. If the connector does not use the remote system's filtering and search capabilities, you *must* set this property to `true`.

  All the non-scripted connectors, except for the CSV connector, use the filtering mechanism of the remote system. In the case of the CSV connector, the remote resource has no filtering mechanism, so you must set `enableFilteredResultsHandler` to `true`. For the scripted connectors, the setting will depend on how you have implemented the connector.

* `enableCaseInsensitiveFilter`

  boolean, false by default

  This property applies only if `enableFilteredResultsHandler` is set to `true`. The filtered results handler is case-sensitive by default. For example, a search for `lastName = "Jensen"` will not match a stored user with `lastName : jensen`. When the filtered results handler is enabled, you can use this property to enable case-insensitive filtering. If you leave this property set to `false`, searches on that resource will be case-sensitive.

* `enableAttributesToGetSearchResultsHandler`

  boolean, false by default

  By default, IDM determines which attributes should be retrieved in a search. If you set this property to `true`, the ICF framework removes *all* attributes from the READ/QUERY response, except for those that are specifically requested. For performance reasons, you should set this property to `false` for local connectors and to `true` for remote connectors.

## Specify which attributes are updated

The `excludeUnmodified` property determines which properties are updated during synchronization. When this property is set to `true`, synchronization operations update *only* the modified properties on a target resource, rather than the whole target object. The default behavior is to include all attributes. In the sample LDAP provisioner files provided with IDM, `excludeUnmodified` is set to `true`, so unmodified attributes are excluded during update operations.

## Set the supported object types

The `objectTypes` configuration specifies the object types (user, group, account, and so on) that are supported by the connector. The object names that you define here determine how the object is accessed in the URI. For example:

```none
system/systemName/objectType
```

This configuration is based on the [JSON Schema](https://json-schema.org) with the extensions described in the following section.

Attribute names that start or end with `__` are regarded as *special attributes* by OpenICF. The purpose of the special attributes in ICF is to enable someone who is developing a *new* connector to create a contract regarding how a property can be referenced, regardless of the application that is using the connector. In this way, the connector can map specific object information between an arbitrary application and the resource, without knowing how that information is referenced in the application.

These attributes have no specific meaning in the context of IDM, although some of the connectors that are bundled with IDM use these attributes. The generic LDAP connector, for example, can be used with PingDS (DS), Active Directory, OpenLDAP, and other LDAP directories. Each of these directories might use a different attribute name to represent the same type of information. For example, Active Directory uses `unicodePassword` and DS uses `userPassword` to represent the same thing, a user's password. The LDAP connector uses the special OpenICF `__PASSWORD__` attribute to abstract that difference. In the same way, the LDAP connector maps the `__NAME__` attribute to an LDAP `dn`.

The ICF `__UID__` is a special case. The `__UID__` *must not* be included in the IDM configuration or in any update or create operation. This attribute denotes the unique identity attribute of an object and IDM always maps it to the `_id` of the object.

The following excerpt shows the configuration of an `account` object type:

```json
{
    "account" : {
        "$schema" : "http://json-schema.org/draft-03/schema",
        "id" : "__ACCOUNT__",
        "type" : "object",
        "nativeType" : "__ACCOUNT__",
        "absentIfEmpty" : false,
        "absentIfNull" : true,
        "properties" : {
            "name" : {
                "type" : "string",
                "nativeName" : "__NAME__",
                "nativeType" : "JAVA_TYPE_PRIMITIVE_LONG",
                "flags" : [
                    "NOT_CREATABLE",
                    "NOT_UPDATEABLE",
                    "NOT_READABLE",
                    "NOT_RETURNED_BY_DEFAULT"
                ]
            },
            "groups" : {
                "type" : "array",
                "items" : {
                    "type" : "string",
                    "nativeType" : "string"
                },
                "nativeName" : "__GROUPS__",
                "nativeType" : "string",
                "flags" : [
                    "NOT_RETURNED_BY_DEFAULT"
                ]
            },
            "givenName" : {
                "type" : "string",
                "nativeName" : "givenName",
                "nativeType" : "string"
            },
        }
    }
}
```

ICF supports an `__ALL__` object type that ensures that objects of every type are included in a synchronization operation. The primary purpose of this object type is to prevent synchronization errors when multiple changes affect more than one object type.

For example, imagine a deployment synchronizing two external systems. On system A, the administrator creates a user, `jdoe`, then adds the user to a group, `engineers`. When these changes are synchronized to system B, if the `__GROUPS__` object type is synchronized first, the synchronization will fail, because the group contains a user that does not yet exist on system B. Synchronizing the `__ALL__` object type ensures that user `jdoe` is created on the external system before he is added to the group `engineers`.

The `__ALL__` object type is assumed by default - you do not need to declare it in your provisioner configuration file. If it is not declared, the object type is named `__ALL__`. If you want to map a different name for this object type, declare it in your provisioner configuration. The following excerpt from a sample provisioner configuration uses the name `allobjects`:

```json
"objectTypes": {
    "allobjects": {
        "$schema": "http://json-schema.org/draft-03/schema",
        "id": "__ALL__",
        "type": "object",
        "nativeType": "__ALL__"
    },
    ...
}
```

A liveSync operation invoked with no object type assumes an object type of `__ALL__`. For example, the following call invokes a liveSync operation on all defined object types in an LDAP system:

```
curl \
--header "X-OpenIDM-Username: openidm-admin" \
--header "X-OpenIDM-Password: openidm-admin" \
--header "Accept-API-Version: resource=1.0" \
--request POST \
"http://localhost:8080/openidm/system/ldap?_action=liveSync"
```

|   |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| - | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | Using the `__ALL__` object type requires a mechanism to ensure the order in which synchronization changes are processed. Servers that use the `cn=changelog` mechanism to order sync changes, such as PingDS (DS), Oracle DSEE, and the legacy Sun Directory Server, cannot use the `__ALL__` object type by default. Such servers must be forced to use timestamps to order their sync changes. For these LDAP server types, set `useTimestampsForSync` to `true` in the provisioner configuration.Additionally, you can use the `timestampSyncOffset` LDAP configuration property to account for replication delays between LDAP instances. Refer to [LDAP connector](ldap.html).LDAP servers that use timestamps rather than change logs (such as Active Directory GCs and OpenLDAP) can use the `__ALL__` object type without any additional configuration. Active Directory and Active Directory LDS, which use Update Sequence Numbers, can also use the `__ALL__` object type without additional configuration. |

### Add objects and properties through the UI

To add object types and properties to a connector configuration by using the admin UI, select Configure > Connectors. Select the connector that you want to change, then select the Object Types tab.

In the case of the LDAP connector, the connector reads the schema from the remote resource to determine the object types and properties that can be added to its configuration. When you select one of these object types, you can think of it as a template. Edit the basic object type, as required, to suit your deployment.

To add a property to an object type, select the Edit icon next to the object type, then select Add Property.

### Specify object types on the external resource

At the object level, the `nativeType` property refers to an object type supported by a connector or external resource. For example, an LDAP connector might have object types such as `__ACCOUNT__` and `__GROUP__`.

* `nativeType`

  string, optional

  The native ICF object type.

  The value of this property must be an object type supported by the resource or the connector.

### Behavior for empty attributes

The `absentIfEmpty` and `absentIfNull` object class properties enable you to specify how attributes are handled during synchronization if their values are null (for single-valued attributes) or empty (for multivalued attributes). You can set these properties per object type.

By default, these properties are set as follows:

* `"absentIfEmpty" : false`

  Multivalued attributes whose values are empty are included in the resource response during synchronization.

* `"absentIfNull" : true`

  Single-valued attributes whose values are null are removed from the resource response during synchronization.

### Specify attribute types on the external resource

At the property level, `nativeType` refers to the data type of an attribute on the external resource.

* `nativeType`

  string, optional

  The native ICF attribute type.

  The following native types are supported:

  ```
  JAVA_TYPE_BIGDECIMAL
  JAVA_TYPE_BIGINTEGER
  JAVA_TYPE_BYTE
  JAVA_TYPE_BYTE_ARRAY
  JAVA_TYPE_CHAR
  JAVA_TYPE_CHARACTER
  JAVA_TYPE_DATE
  JAVA_TYPE_DOUBLE
  JAVA_TYPE_FILE
  JAVA_TYPE_FLOAT
  JAVA_TYPE_GUARDEDBYTEARRAY
  JAVA_TYPE_GUARDEDSTRING
  JAVA_TYPE_INT
  JAVA_TYPE_INTEGER
  JAVA_TYPE_LONG
  JAVA_TYPE_OBJECT
  JAVA_TYPE_PRIMITIVE_BOOLEAN
  JAVA_TYPE_PRIMITIVE_BYTE
  JAVA_TYPE_PRIMITIVE_DOUBLE
  JAVA_TYPE_PRIMITIVE_FLOAT
  JAVA_TYPE_PRIMITIVE_LONG
  JAVA_TYPE_STRING
  ```

  |   |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
  | - | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  |   | * IDM only handles JSON primitive types (`boolean`, `map`, `list`, `number`, and `string`). You must encode any non-JSON primitive types so that they can be stored as JSON.

    As a general rule, your connector configurations should always map the property type on the external resource (`nativeType`) to a supported JSON primitive type in IDM. If you are synchronizing pre-hashed passwords, set the `nativeType` to a `JAVA_TYPE_BYTE_ARRAY`, and the IDM `type` to a `string`, for example:

    ```json
    ...
        "userPassword" : {
            "type" : "string",
            "nativeName" : "userPassword",
            "nativeType" : "JAVA_TYPE_BYTE_ARRAY"
        },
    ...
    ```

    With this configuration, when a `userPassword` is read from the remote system, it is returned as a `Byte[]` by the connector. It is then converted to a `String` (Base64-encoded `Byte[]`) by IDM.

    Alternatively, you can make sure that any non-JSON primitive types returned by your connector are appropriately [transformed](https://docs.pingidentity.com/pingidm/8/synchronization-guide/mapping-transforming-attributes.html) into an encoded `string` value in your mapping. For example:

    ```json
    {
        "source": "password",
        "target": "password",
        "transform": {
            "type": "text/javascript",
            "source": "source.toString();"
        }
    },
    ```

  * The `JAVA_TYPE_DATE` property is deprecated. Functionality may be removed in a future release. This type is an alias for `string`. Any dates with this type should be formatted according to ISO 8601. |

* `nativeName`

  string, optional

  The native ICF attribute name.

- `flags`

  string, optional

  The native ICF attribute flags. ICF supports the following attribute flags:

  * `MULTIVALUED`

    The property can be multivalued.

    For multivalued properties, if the property value type is anything other than a `string`, you *must* include an `items` property that declares the data type.

    The following example shows the `entries` property of the `authentication` object in a provisioner file. The `entries` property is multivalued, and its elements are of type `object`:

    ```json
    "authentication" : {
        ...
        "properties" : {
            ...
            "entries" : {
                "type" : "object",
                "required" : false,
                "nativeName" : "entries",
                "nativeType" : "object",
                    "items" : {
                        "type" : "object"
                    },
                "flags" : [
                    "MULTIVALUED"
                ]
            },
            ...
        },
        ...
    }
    ```

    |   |                                                                                                                                                                                                                                                                     |
    | - | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    |   | When comparing multivalued properties across systems, the *order* of the values is important. Two properties with the same values, but in different orders, will be seen as a *change* during reconciliation, regardless of whether the value has actually changed. |

  * `NOT_CREATABLE`, `NOT_READABLE`, `NOT_UPDATEABLE`

    In some cases, the connector might not support manipulating an attribute because the attribute can only be changed directly on the remote system. For example, if the `name` attribute of an account can only be created by Active Directory, and *never* changed by IDM, you would add `NOT_CREATABLE` and `NOT_UPDATEABLE` to the provisioner configuration for that attribute.

  * `NOT_RETURNED_BY_DEFAULT`

    Some attributes, such as LDAP groups or other calculated attributes, can be expensive to read. To avoid returning these attributes in a default read of the object, unless they are explicitly requested, add the `NOT_RETURNED_BY_DEFAULT` flag to the provisioner configuration for that attribute.

    You can also use this flag to prevent properties from being read by default during a synchronization operation. To synchronize changes to a target object, IDM performs an UPDATE rather than a PATCH. This causes *all* attributes that are mapped from the source to the target to be modified when the synchronization is processed (rather than only those attributes that have changed). Although the *value* of a property might not change, the property still registers an update. This behavior can be problematic for properties such as the `password`, which might have restrictions on updating with a similar value. To prevent such properties from being updated during synchronization, set the `NOT_RETURNED_BY_DEFAULT` flag, which effectively prevents the property from being read from the source during the synchronization. For example:

    ```json
    "__PASSWORD__" : {
        "type" : "string",
        "nativeName" : "__PASSWORD__",
        "nativeType" : "JAVA_TYPE_GUARDEDSTRING",
        "flags" : [
            "NOT_RETURNED_BY_DEFAULT"
        ],
        "runAsUser" : true
    }
    ```

You can configure connectors to enable provisioning of any arbitrary property. For example, the following property definitions would enable you to provision image files, used as avatars, to `account` objects in a system resource. The first definition would work for a single photo encoded as a base64 string. The second definition would work for multiple photos encoded in the same way:

```json
"attributeByteArray" : {
    "type" : "string",
    "nativeName" : "attributeByteArray",
    "nativeType" : "JAVA_TYPE_BYTE_ARRAY"
},
```

```json
"attributeByteArrayMultivalue": {
    "type": "array",
    "items": {
        "type": "string",
        "nativeType": "JAVA_TYPE_BYTE_ARRAY"
    },
    "nativeName": "attributeByteArrayMultivalue"
},
```

|   |                                                                                                                                                                                                                                                     |
| - | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | Do not use the dash character ( `-` ) in property names, like `last-name`. Dashes in names make JavaScript syntax more complex. If you cannot avoid the dash, write `source['last-name']` instead of `source.last-name` in your JavaScript scripts. |

## Configure operation options

The `operationOptions` object enables you to deny specific operations on a resource. For example, you can use this configuration object to deny `CREATE` and `DELETE` operations on a read-only resource to avoid IDM accidentally updating the resource during a synchronization operation.

The following example defines the options for the `"SYNC"` operation:

```json
"operationOptions" : {
    "SYNC" : {
        "denied" : true,
        "onDeny" : "DO_NOTHING",
        "objectFeatures" : {
            "__ACCOUNT__" : {
                "denied" : true,
                "onDeny" : "THROW_EXCEPTION",
                "operationOptionInfo" : {
                    "$schema" : "http://json-schema.org/draft-03/schema",
                    "type" : "object",
                    "properties" : {
                        "_OperationOption-float" : {
                            "type" : "number",
                            "nativeType" : "JAVA_TYPE_PRIMITIVE_FLOAT"
                        }
                    }
                }
            },
            "__GROUP__" : {
                "denied" : false,
                "onDeny" : "DO_NOTHING"
            }
        }
    },
    ...
}
```

The ICF Framework supports the following operations:

* `AUTHENTICATE`

* `CREATE`

* `DELETE`

* `GET`

* `RESOLVEUSERNAME`

* `SCHEMA`

* `SCRIPT_ON_CONNECTOR`

* `SCRIPT_ON_RESOURCE`

* `SEARCH`

* `SYNC`

* `TEST`

* `UPDATE`

* `VALIDATE`

For detailed information on these operations, refer to the [ICF API documentation](../_attachments/apidocs/index.html).

The `operationOptions` object has the following configurable properties:

* `denied`

  boolean, optional

  This property prevents operation execution if the value is `true`.

* `onDeny`

  string, optional

  If `denied` is `true`, then the service uses this value. Default value: `DO_NOTHING`.

  * `DO_NOTHING`: On operation the service does nothing.

  * `THROW_EXCEPTION`: On operation the service throws a `ForbiddenException` exception.
