---
title: PingDS repository
description: IDM supports the following deployment scenarios with a DS repository:
component: pingidm
version: 8.1
page_id: pingidm:install-guide:external-ds
canonical_url: https://docs.pingidentity.com/pingidm/8.1/install-guide/external-ds.html
keywords: ["Installation", "Directory Service"]
section_ids:
  single-external-ds: Configure a single external DS instance as a repository
  two-ds-active-passive: Configure two DS repositories in an active/passive deployment
  external-ds-mtls: Configure mTLS
  secret-rotation-mtls: Storing credentials in a secret
---

# PingDS repository

|   |                                                                                                                                       |
| - | ------------------------------------------------------------------------------------------------------------------------------------- |
|   | If you are using IDM with a DS repository, Ping recommends using mTLS to authenticate to DS to better facilitate credential rotation. |

IDM supports the following deployment scenarios with a DS repository:

* [Single external DS instance](#single-external-ds)

* [Two DS instances in an active/passive configuration](#two-ds-active-passive)

  IDM supports two replicated DS instances for backup/availabilty purposes only. Using multiple replicated DS instances as repositories (in a multimaster DS deployment) is not supported.

## Configure a single external DS instance as a repository

1. If you have not yet installed DS, download it from the [Backstage download site](https://backstage.forgerock.com/downloads) and extract the .zip archive.

2. Install DS according to the instructions in the [DS Installation Guide](https://docs.pingidentity.com/pingds/8.1/install-guide):

   * If you are planning to use a [generic object mapping](../objects-guide/explicit-generic-mapping-ds.html#generic-mappings-ds) for managed users, install DS with the `idm-repo` profile (see [Install DS as an IDM Repository](https://docs.pingidentity.com/pingds/8.1/install-guide/profile-idm-repo.html)).

   * If you are planning to use an [explicit object mapping](../objects-guide/explicit-generic-mapping-ds.html#explicit-mappings-ds) for managed users, install DS with both the `idm-repo` and `am-identity-store` profiles (see [Install DS as an IDM Repository](https://docs.pingidentity.com/pingds/8.1/install-guide/profile-idm-repo.html) and [Install DS for AM Identities](https://docs.pingidentity.com/pingds/8.1/install-guide/profile-am-idrepo.html)).

     This example configures DS on the localhost, listening on the following ports:

     * LDAP port: `31389`

     * Admin port: `34444`

     * LDAPS port: `31636`

   We've used these ports to avoid a port conflict with the default ports used in the LDAP samples. You can use any host and available ports in the setup. If you use a different host and ports, change the `primaryLdapServers` property in your `repo.ds-external.json` file accordingly.

   |   |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
   | - | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
   |   | Every DS deployment requires a *deploymentId* and a *deploymentIdPassword* to secure network connections. The deploymentId is a random string generated by DS software. The deploymentIdPassword is a secret string that you choose. It must be at least 8 characters long. The deploymentId and deploymentIdPassword automate key pair generation and signing without storing the CA private key. For more information, refer to [Deployment IDs](https://docs.pingidentity.com/pingds/8.1/security-guide/pki.html#about-deployment-keys) in the *DS Security Guide*. |

3. In your IDM installation, remove the default DS repository configuration file (`repo.ds.json` ) from your project's `conf/` directory. For example:

   ```
   cd /path/to/openidm/my-project/conf/
   rm repo.ds.json
   ```

4. Copy the external DS repository configuration file (`repo.ds-external.json` ) to your project's `conf` directory and rename it `repo.ds.json` :

   ```
   cp /path/to/openidm/db/ds/conf/repo.ds-external.json my-project/conf/repo.ds.json
   ```

5. Enable IDM to trust the DS server certificate for your deployment.

   For example, in the default case, where DS servers use TLS key pairs generated using a deploymentId and deploymentIdPassword, import the deploymentId-based CA certificate into the IDM truststore:

   ```
   /path/to/opendj/bin/dskeymgr \
   export-ca-cert \
   --deploymentId your-deployment-ID \
   --deploymentIdPassword password \
   --outputFile ds-ca-cert.pem
   ```

   ```
   keytool \
   -importcert \
   -alias ds-ca-cert \
   -keystore /path/to/openidm/security/truststore \
   -storepass:file /path/to/openidm/security/storepass \
   -file ds-ca-cert.pem
   Owner: CN=Deployment key, O=ForgeRock.com
   Issuer: CN=Deployment key, O=ForgeRock.com
   ...
   Trust this certificate? [no]: yes
   Certificate was added to keystore
   ```

6. Adjust the connection settings from IDM to DS in the IDM repository configuration file, `repo.ds.json`:

   * If your DS instance is *not* running on the localhost and listening for LDAP connections on port `31389`, adjust the `primaryLdapServers` property in that file to match your DS setup.

   * Make sure the password for the DS directory superuser (`uid=admin`) matches the DS root user password in the IDM configuration.

   Learn more about connection settings in [Gateway LDAP Connections](https://docs.pingidentity.com/pingds/7.3/rest-guide/rest2ldap.html). IDM shares these configuration settings with the DS REST to LDAP Gateway.

7. Start IDM with the configuration for your project. For example:

   ```
   /path/to/openidm/startup.sh -p my-project
   Executing ./startup.sh...
   Using OPENIDM_HOME:   /path/to/openidm
   Using PROJECT_HOME:   /path/to/my-project
   Using OPENIDM_OPTS:   -Xmx2048m -Xms2048m
   ...
   -> OpenIDM version "8.1.0"
   OpenIDM ready
   ```

8. (Optional) Verify that IDM successfully connects to DS:

   ```
   grep 31389 /path/to/opendj/logs/ldap-access.audit.json | tail -n 1 | jq .
   {
     "eventName": "DJ-LDAP",
     "client": {
       "ip": "127.0.0.1",
       "port": 35874
     },
     "server": {
       "ip": "127.0.0.1",
       "port": 31389
     },
     "request": {
       "protocol": "LDAP",
       "operation": "SEARCH",
       "connId": 1,
       "msgId": 232,
       "dn": "ou=triggers,ou=scheduler,dc=openidm,dc=forgerock,dc=com",
       "scope": "one",
       "filter": "(&(&(fr-idm-json:caseIgnoreJsonQueryMatch:=/state eq \"NORMAL\")(!(fr-idm-json:caseIgnoreJsonQueryMatch:=/nodeId pr)))(objectClass=uidObject)(objectClass=fr-idm-generic-obj)(objectClass=top))",
       "attrs": [
         "objectClass",
         "uid",
         "etag",
         "createTimestamp",
         "modifyTimestamp",
         "fr-idm-json"
       ]
     },
     "transactionId": "transaction-id",
     "response": {
       "status": "SUCCESSFUL",
       "statusCode": "0",
       "elapsedTime": 1,
       "elapsedTimeUnits": "MILLISECONDS",
       "nentries": 0
     },
     "timestamp": "timestamp",
     "_id": "id"
   }
   ```

## Configure two DS repositories in an active/passive deployment

With this configuration, IDM fails over to the secondary DS instance if the primary instance becomes unavailable. When the primary DS instance is restarted, that instance again becomes the target of all requests.

1. Download DS from the [Backstage download site](https://backstage.forgerock.com/downloads), and extract the .zip archive.

2. Install two DS servers, according to the instructions in the [DS Installation Guide](https://docs.pingidentity.com/pingds/8.1/install-guide).

   |   |                                                                                                                                                                                                                                                                                                      |
   | - | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
   |   | When you set up each server, specify a `replicationPort` and `bootstrapReplicationServer` so that both servers are installed as replicas. For information on these setup options, refer to [setup](https://docs.pingidentity.com/pingds/8.1/tools-reference/setup.html) in the *DS Tools Reference*. |

   * If you are planning to use a [generic object mapping](../objects-guide/repository.html#generic-mappings-ds) for managed users, install DS with the `idm-repo` profile (see [Install DS as an IDM Repository](https://docs.pingidentity.com/pingds/8.1/install-guide/profile-idm-repo.html)).

   * If you are planning to use an [explicit object mapping](../objects-guide/repository.html#explicit-mappings-ds) for managed users, install DS with both the `idm-repo` and `am-identity-store` profiles (see [Install DS as an IDM Repository](https://docs.pingidentity.com/pingds/8.1/install-guide/profile-idm-repo.html) and [Install DS for AM Identities](https://docs.pingidentity.com/pingds/8.1/install-guide/profile-am-idrepo.html)).

   |   |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
   | - | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
   |   | Every DS deployment requires a *deploymentId* and a *deploymentIdPassword* to secure network connections. The deploymentId is a random string generated by DS software. The deploymentIdPassword is a secret string that you choose. It must be at least 8 characters long. The deploymentId and deploymentIdPassword automate key pair generation and signing without storing the CA private key. For more information, refer to [Deployment IDs](https://docs.pingidentity.com/pingds/8.1/security-guide/pki.html#about-deployment-keys) in the *DS Security Guide*. |

3. In your IDM installation, remove the default DS repository configuration file (`repo.ds.json`) from your project's `conf/` directory. For example:

   ```
   cd /path/to/openidm/my-project/conf/
   rm repo.ds.json
   ```

4. Copy the external DS repository configuration file (`repo.ds-external.json`) to your project's `conf` directory and rename it `repo.ds.json`:

   ```
   cp /path/to/openidm/db/ds/conf/repo.ds-external.json my-project/conf/repo.ds.json
   ```

5. Enable IDM to trust each DS server certificate for your deployment.

   For example, in the default case, where DS servers use TLS key pairs generated using a deploymentId and deploymentIdPassword, import the deploymentId-based CA certificate *for each server* into the IDM truststore.

   You will need to give the CA certificate of the second server a different alias.

   ```
   /path/to/opendj/bin/dskeymgr \
   export-ca-cert \
   --deploymentId your-deployment-ID \
   --deploymentIdPassword password \
   --outputFile ds-ca-cert.pem keytool \
   -importcert \
   -alias ds-ca-cert \
   -keystore /path/to/openidm/security/truststore \
   -storepass:file /path/to/openidm/security/storepass \
   -file ds-ca-cert.pem
   Owner: CN=Deployment key, O=ForgeRock.com
   Issuer: CN=Deployment key, O=ForgeRock.com
   ...
   Trust this certificate? [no]: yes
   Certificate was added to keystore
   ```

6. Specify the connection settings from IDM to the two DS servers in the `ldapConnectionFactories` property of the repository configuration file (`repo.ds.json` ).

   This example assumes that the first DS server runs on the host `ds1.example.com`, and the second DS server runs on the host `ds2.example.com`:

   ```json
   "ldapConnectionFactories": {
       "bind": {
           "connectionSecurity": "startTLS",
           "heartBeatIntervalSeconds": 60,
           "heartBeatTimeoutMilliSeconds": 10000,
           "primaryLdapServers": [{ "hostname": "ds1.example.com", "port": 31389 }],
           "secondaryLdapServers": [{ "hostname": "ds2.example.com", "port": 31389 }]
   }
   ```

   Adjust the settings to match your DS server setup.

   Learn more about connection settings in [Gateway LDAP Connections](https://docs.pingidentity.com/pingds/7.3/rest-guide/rest2ldap.html). (IDM shares these configuration settings with the DS REST to LDAP Gateway.)

7. Also in the `repo.ds.json` file, check the `authentication` settings:

   ```json
   "root": {
       "inheritFrom": "bind",
       "authentication": {
           "simple": { "bindDn": "uid=admin", "bindPassword": "str0ngAdm1nPa55word" }
       }
   }
   ```

   Make sure that the `bindDn` and `bindPassword` match the bind details of the DS superuser.

8. Start IDM, and verify that the connection to the primary DS server is successful.

9. (Optional) Shut down the primary DS server, and verify that the failover to the secondary server occurs, as expected.

## Configure mTLS

After you have configured DS using one of the above methods, you can enable mTLS between DS and IDM. The following procedure uses a self-signed certificate—adjust it for an official certificate authority (CA) certificate.

1. Install and configure DS:

   * [Configure a single external DS instance as a repository](#single-external-ds)

   * [Configure two DS repositories in an active/passive deployment](#two-ds-active-passive)

2. Create a self-signed, TLS key-pair with the subject DN: `cn=IDM service account,dc=example,dc=com`.

   |   |                                                                                                                                                          |
   | - | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
   |   | You can use any name for the cert alias, but you must update the `sslCertAlias` property in the `repo.ds.json` file to match the value you specify here. |

   ```console
   keytool \
   -genkey \
   -alias client-cert \
   -dname "cn=IDM service account,dc=example,dc=com" \
   -storetype JCEKS \
   -keystore /path/to/openidm/security/keystore.jceks \
   -storepass changeit \
   -keyalg RSA \
   -keysize 2048 \
   -validity 360
   ```

3. Export the certificate:

   ```console
   keytool \
   -exportcert \
   -alias client-cert \
   -file idm-client.crt \
   -storetype JCEKS \
   -keystore /path/to/openidm/security/keystore.jceks \
   -storepass changeit
   ```

4. Import the certificate into the DS keystore:

   ```console
   keytool \
   -importcert \
   -noprompt \
   -alias client-cert \
   -file idm-client.crt \
   -storetype PKCS12 \
   -keystore /path/to/ds/config/keystore \
   -storepass $DEPLOYMENT_KEY
   ```

5. Use `ldapmodify` to map the `uid=admin` user in DS to the generated certificate:

   ```console
   /path/to/ds/bin/ldapmodify \
   --hostname localhost \
   --port 31389 \
   --useStartTls \
   --trustAll \
   --bindDN uid=admin \
   --bindPassword str0ngAdm1nPa55word << EOF
   dn: uid=admin
   changetype: modify
   add: objectclass
   objectclass: ds-certificate-user
   -
   replace: ds-certificate-subject-dn
   ds-certificate-subject-dn: cn=IDM service account,dc=example,dc=com
   EOF
   ```

6. Enable IDM to trust DS certificates:

   ```console
   /path/to/ds/bin/dskeymgr export-ca-cert \
   --deploymentKey $DEPLOYMENT_KEY \
   --deploymentKeyPassword $DEPLOYMENT_KEY_PASSWORD \
   --outputFile ds-ca-cert.pem
   ```

   ```console
   keytool \
   -importcert \
   -alias ds-ca-cert \
   -keystore /path/to/idm/security/truststore \
   -storepass:file /path/to/idm/security/storepass \
   -file ds-ca-cert.pem
   ```

7. Make the following changes to the `repo.ds.json` file:

   ```json
   ...
       "ldapConnectionFactories" : {
           "bind" : {
               "connectionSecurity" : "ssl",
               "sslCertAlias": "client-cert", (1)
               ...
           "root" : {
               "inheritFrom" : "bind",
               "authentication": {
                   "policy": "sasl-external"
               }
           }
       ...
   ```

   |       |                                                                               |
   | ----- | ----------------------------------------------------------------------------- |
   | **1** | Make sure to use the alias value you specified when creating the certificate. |

### Storing credentials in a secret

Optionally, you can configure mTLS to store your credentials in a secret:

1. Add a new secret store to `conf/secrets.json` which defines `idm.repo.ds.tls.signing` and `idm.repo.ds.tls.certificate.verification` as `secretId` fields. `idm.repo.ds.tls.signing` must be `SIGN` `type` and `idm.repo.ds.tls.certificate.verification` must be of `CERT_VERIFY` `type`. This example demonstrates this using a file system secret store:

   ```json
   {
     "name": "dsStore",
     "class": "org.forgerock.openidm.secrets.config.FileSystemStore",
     "config": {
       "directory": "&{idm.install.dir}/secrets",
       "format": "PEM",
       "suffix": ".pem",
       "mappings": [
         {
           "secretId": "idm.repo.ds.tls.signing",
           "types": [
             "SIGN"
           ]
         },
         {
           "secretId": "idm.repo.ds.tls.certificate.verification",
           "types": [
             "CERT_VERIFY"
           ]
         }
       ]
     }
   }
   ```

2. Add the `security` field to `repo.ds.json`:

   ```json
   {
     "security": {
       "trustManager": "purpose",
       "keyManager": "purpose",
       "trustMangerRevocationCheckingEnabled": false (1)
     },
    ...
   }
   ```

   |       |                                                                                                                                                          |
   | ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
   | **1** | `trustMangerRevocationCheckingEnabled` is an optional boolean field. When true, the system fails if the certificate has been revoked by its distributor. |

3. In `repo.ds.json`, remove `sslCertAlias` from the `bind` field of `ldapConnectionFactories`.
