---
title: Changelog for notifications
description: Some applications require notification when directory data updates occur. For example, an application might need to sync directory data with another database, or the application might need to kick off other processing when certain updates occur. DS replication servers provide an external changelog that replications can use to read changes. This mechanism is more scalable and robust than LDAP persistent searches.
component: pingds
version: 8.1
page_id: pingds:config-guide:changelog
canonical_url: https://docs.pingidentity.com/pingds/8.1/config-guide/changelog.html
revdate: 2025-10-22T14:42:39Z
keywords: ["Features", "LDAP", "Replication", "Setup &amp; Configuration"]
section_ids:
  enable-ecl: Enable the external changelog
  encrypt-ecl: Encrypt changelog data
  read-ecl-as-regular-user: Let a user read the changelog
  ecl-add-attributes: Include unchanged attributes
  ecl-exclude-domain: Exclude a domain
  ecl-legacy-format: Internet-Draft change numbers
  ecl-configure-changenumber-indexer: Change number indexing
---

# Changelog for notifications

Some applications require notification when directory data updates occur. For example, an application might need to sync directory data with another database, or the application might need to kick off other processing when certain updates occur. DS replication servers provide an external changelog that replications can use to read changes. This mechanism is more scalable and robust than LDAP persistent searches.

By default, changelog database files are found under the `opendj/changelogDb` directory.

|   |                                                                                                                                                                                                                                                            |
| - | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | Do not compress, tamper with, or otherwise alter changelog database files directly, unless specifically instructed to do so by a qualified technical support engineer.External changes to changelog database files can render them unusable by the server. |

## Enable the external changelog

DS servers that have a replication server port and an LDAP port publish an external changelog over LDAP:

| Ports Configured   | Examples       | Notes                                                                                                                                                                                                            |
| ------------------ | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| LDAP or LDAPS port | `1389`, `1636` | LDAP client applications use the LDAP or LDAPS port to read changelog data.A standalone replication server may not have an LDAP or LDAPS port configured.                                                        |
| Replication port   | `8989`         | Servers with replication ports maintain a changelog for their own use. The changelog is exposed over LDAP under the base DN, `cn=changelog`.Standalone directory servers do not maintain a changelog by default. |

1. Make sure an LDAP or LDAPS port is configured so that LDAP client applications can read the changelog.

2. Depending on the server configuration, enable the changelog one of the following ways:

   1. For servers with replication ports, make sure replication is properly configured.

      The following example shows how the directory superuser can read the changelog:

      ```console
      $ ldapsearch \
       --hostname localhost \
       --port 1636 \
       --useSsl \
       --trustStorePath /path/to/opendj/config/keystore \
       --trustStoreType PKCS12 \
       --trustStorePassword:file /path/to/opendj/config/keystore.pin \
       --bindDN uid=admin \
       --bindPassword password \
       --baseDN cn=changelog \
       --searchScope base \
       --control "ecl:true" \
       "(&)"
      ```

      > **Collapse: Show output**
      >
      > ```
      > dn: cn=changelog
      > objectclass: top
      > objectclass: container
      > cn: changelog
      > ```

      |   |                                                                                                                                                                         |
      | - | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
      |   | The external changelog (`cn=changelog`) doesn't support the [Simple Paged Results](https://www.rfc-editor.org/info/rfc2696) LDAP control (OID: 1.2.840.113556.1.4.319). |

   2. For standalone directory servers without replication ports, you can manually enable the changelog. These steps cause the server to begin maintaining a replication changelog, which consumes disk space:

      * Update the default replication synchronization configuration entry as in the following example:

        ```console
        $ dsconfig \
         set-synchronization-provider-prop \
         --provider-name "Multimaster Synchronization" \
         --set bootstrap-replication-server:localhost:8989 \
         --hostname localhost \
         --port 4444 \
         --bindDN uid=admin \
         --bindPassword password \
         --trustStorePath /path/to/opendj/config/keystore \
         --trustStoreType PKCS12 \
         --trustStorePassword:file /path/to/opendj/config/keystore.pin \
         --no-prompt
        ```

      * Create a replication server configuration entry as in the following example:

        ```console
        $ dsconfig \
         create-replication-server \
         --provider-name "Multimaster Synchronization" \
         --set replication-port:8989 \
         --hostname localhost \
         --port 4444 \
         --bindDN uid=admin \
         --bindPassword password \
         --trustStorePath /path/to/opendj/config/keystore \
         --trustStoreType PKCS12 \
         --trustStorePassword:file /path/to/opendj/config/keystore.pin \
         --no-prompt
        ```

      * Create a replication domain configuration entry as in the following example:

        ```console
        $ dsconfig \
         create-replication-domain \
         --provider-name "Multimaster Synchronization" \
         --domain-name "Example.com" \
         --set base-dn:dc=example,dc=com \
         --hostname localhost \
         --port 4444 \
         --bindDN uid=admin \
         --bindPassword password \
         --trustStorePath /path/to/opendj/config/keystore \
         --trustStoreType PKCS12 \
         --trustStorePassword:file /path/to/opendj/config/keystore.pin \
         --no-prompt
        ```

3. Make sure the user who needs to read changelog data has the `changelog-read` privilege, and has access to read entries under `cn=changelog`.

   For details, refer to [Let a user read the changelog](#read-ecl-as-regular-user).

## Encrypt changelog data

DS servers do not encrypt changelog data on disk by default. Any user with system access to read directory files can potentially read external changelog data.

In addition to preventing read access by other users, you can configure confidentiality for changelog data. When confidentiality is enabled, the server encrypts changelog records before storing them on disk. The server decrypts changelog records before returning them to client applications.

|   |                                                                                                                                                                  |
| - | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | Encrypting stored directory data does not prevent it from being sent over the network in the clear.Use secure connections to protect data sent over the network. |

DS servers encrypt data using symmetric keys. Servers generate symmetric keys when needed and store them, encrypted with the shared master key, with the data they encrypt. As long as servers have the same shared master key, any server can recover symmetric keys needed to decrypt data.

Symmetric keys for (deprecated) reversible password storage schemes are the exception to this rule. When you configure a reversible password storage scheme, enable the `adminRoot` backend, and configure a replication domain for `cn=admin data`.

Encrypting and decrypting data require cryptographic processing that reduces throughput, and extra space for larger encrypted values. Tests with default settings show that the cost of enabling confidentiality can be quite modest. Your results can vary based on the host system hardware, the JVM, and the settings for `cipher-transformation` and `cipher-key-length`. Make sure you test your deployment to qualify the impact of confidentiality before changing settings in production.

Follow these steps to enable confidentiality:

1. Before you enable confidentiality on a replication server for the changelog data, first enable confidentiality for data stored in directory backends.

   For details, refer to [Data encryption](../security-guide/data.html).

2. Enable changelog confidentiality with the default encryption settings:

   ```console
   $ dsconfig \
    set-replication-server-prop \
    --provider-name "Multimaster Synchronization" \
    --set confidentiality-enabled:true \
    --hostname localhost \
    --port 4444 \
    --bindDN uid=admin \
    --bindPassword password \
    --trustStorePath /path/to/opendj/config/keystore \
    --trustStoreType PKCS12 \
    --trustStorePassword:file /path/to/opendj/config/keystore.pin \
    --no-prompt
   ```

   Encryption applies to the entire changelog regardless of the confidentiality settings for each domain.

   After confidentiality is enabled, new changelog records are encrypted. DS servers do not rewrite old records in encrypted form.

3. If necessary, adjust additional confidentiality settings.

   Use the same cipher suite for changelog confidentiality and data confidentiality.

   The default settings for confidentiality are `cipher-transformation: AES/GCM/NoPadding`, and `cipher-key-length: 128`. This means the algorithm is the Advanced Encryption Standard (AES), and the cipher mode is Galois/Counter Mode (GCM). The syntax for the `cipher-transformation` is `algorithm/mode/padding`. You must specify the *algorithm*, *mode*, and *padding*. When the algorithm does not require a mode, use `NONE`. When the algorithm does not require padding, use `NoPadding`.

## Let a user read the changelog

For a user to read the changelog, the user must have access to read, search, and compare changelog attributes, might have access to use the control to read the external changelog, and must have the `changelog-read` privilege.

1. Give the user access to read and search the changelog.

   The following example adds two global ACIs *(tooltip: \<div class="paragraph">
   \<p>An instruction or rule that can be used to grant or deny access to users to perform operations on a server.\</p>
   \</div>)*. The first ACI gives `My App` read access to root DSE attributes that hold information about the changelog. The second ACI gives `My App` read access to the changelog data:

   ```console
   $ dsconfig \
    set-access-control-handler-prop \
    --add global-aci:"(target=\"ldap:///\")\
   (targetattr=\"changeLog||firstChangeNumber||lastChangeNumber||lastExternalChangeLogCookie\")\
   (version 3.0; acl \"My App can access changelog attributes on root DSE\"; \
   allow (read,search,compare) \
   userdn=\"ldap:///cn=My App,ou=Apps,dc=example,dc=com\";)" \
    --add global-aci:"(target=\"ldap:///cn=changelog\")(targetattr=\"*||+\")\
   (version 3.0; acl \"My App can access cn=changelog\"; \
   allow (read,search,compare) \
   userdn=\"ldap:///cn=My App,ou=Apps,dc=example,dc=com\";)" \
    --hostname localhost \
    --port 4444 \
    --bindDN uid=admin \
    --bindPassword password \
    --trustStorePath /path/to/opendj/config/keystore \
    --trustStoreType PKCS12 \
    --trustStorePassword:file /path/to/opendj/config/keystore.pin \
    --no-prompt
   ```

   The IDM liveSync feature requires access to the root DSE attributes `changeLog`, `firstChangeNumber`, and `lastChangeNumber`.

2. Give the user access to use the public changelog exchange control.

   The following example adds a global ACI to give `My App` access to use the control:

   ```console
   $ dsconfig \
    set-access-control-handler-prop \
    --add global-aci:"(targetcontrol=\"Ecl\")\
   (version 3.0; acl \"My App control access\"; \
   allow (read) \
   userdn=\"ldap:///cn=My App,ou=Apps,dc=example,dc=com\";)" \
    --hostname localhost \
    --port 4444 \
    --bindDN uid=admin \
    --bindPassword password \
    --trustStorePath /path/to/opendj/config/keystore \
    --trustStoreType PKCS12 \
    --trustStorePassword:file /path/to/opendj/config/keystore.pin \
    --no-prompt
   ```

3. Give the user the `changelog-read` privilege:

   ```console
   $ ldapmodify \
    --hostname localhost \
    --port 1636 \
    --useSsl \
    --trustStorePath /path/to/opendj/config/keystore \
    --trustStoreType PKCS12 \
    --trustStorePassword:file /path/to/opendj/config/keystore.pin \
    --bindDN uid=admin \
    --bindPassword password << EOF
   dn: cn=My App,ou=Apps,dc=example,dc=com
   changetype: modify
   add: ds-privilege-name
   ds-privilege-name: changelog-read
   EOF
   ```

4. Check that the user can read the changelog:

   ```console
   $ ldapsearch \
    --hostname localhost \
    --port 1636 \
    --useSsl \
    --trustStorePath /path/to/opendj/config/keystore \
    --trustStoreType PKCS12 \
    --trustStorePassword:file /path/to/opendj/config/keystore.pin \
    --bindDN uid=admin \
    --bindPassword password \
    --baseDN cn=changelog \
    --control "ecl:true" \
    "(&)" \
    changes changeLogCookie targetDN
   ```

   |   |                                                                                                                                                                         |
   | - | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
   |   | The external changelog (`cn=changelog`) doesn't support the [Simple Paged Results](https://www.rfc-editor.org/info/rfc2696) LDAP control (OID: 1.2.840.113556.1.4.319). |

## Include unchanged attributes

The changes returned from a search on the external changelog include only what was actually changed. If you have applications that need additional attributes published with every changelog entry, regardless of whether the attribute itself has changed, specify those with the `ecl-include` and `ecl-include-for-deletes` properties:

1. Set the attributes to include for all update operations:

   ```console
   $ dsconfig \
    set-replication-domain-prop \
    --provider-name "Multimaster Synchronization" \
    --domain-name dc=example,dc=com \
    --set ecl-include:"@person" \
    --set ecl-include:entryUUID \
    --hostname localhost \
    --port 4444 \
    --bindDN uid=admin \
    --bindPassword password \
    --trustStorePath /path/to/opendj/config/keystore \
    --trustStoreType PKCS12 \
    --trustStorePassword:file /path/to/opendj/config/keystore.pin \
    --no-prompt
   ```

   The `entryUUID` can be useful, for example, to ensure integrity when entries are renamed.

2. Set the attributes to include for deletes:

   ```console
   $ dsconfig \
    set-replication-domain-prop \
    --provider-name "Multimaster Synchronization" \
    --domain-name dc=example,dc=com \
    --add ecl-include-for-deletes:"*" \
    --add ecl-include-for-deletes:"+" \
    --hostname localhost \
    --port 4444 \
    --bindDN uid=admin \
    --bindPassword password \
    --trustStorePath /path/to/opendj/config/keystore \
    --trustStoreType PKCS12 \
    --trustStorePassword:file /path/to/opendj/config/keystore.pin \
    --no-prompt
   ```

   With the default configuration, the changelog records only the DN of the deleted entry.

## Exclude a domain

Exclude domains to prevent applications that read the external changelog from having to process update notifications for entries that are not relevant to them:

1. Change the replication server configuration to exclude the domain by base DN.

   The following example prevents the changelog from sending notifications about Example.com entries:

   ```console
   $ dsconfig \
    set-replication-server-prop \
    --provider-name "Multimaster Synchronization" \
    --set changelog-enabled-excluded-domains:dc=example,dc=com \
    --hostname localhost \
    --port 4444 \
    --bindDN uid=admin \
    --bindPassword password \
    --trustStorePath /path/to/opendj/config/keystore \
    --trustStoreType PKCS12 \
    --trustStorePassword:file /path/to/opendj/config/keystore.pin \
    --no-prompt
   ```

## Internet-Draft change numbers

The external changelog can support applications using the [Internet-Draft: Definition of an Object Class to Hold LDAP Change Records](https://datatracker.ietf.org/doc/html/draft-good-ldap-changelog-04) instead of changelog cookies.

The implementation has these characteristics:

* Replication servers must perform [Change number indexing](#ecl-configure-changenumber-indexer) to get the objects specified for this format.

* Change numbers described in the Internet-Draft are simple numbers, not cookies.

* Changelog numbers are ordered locally for each DS server. Each server keeps its own count. The same change numbers can refer to different changes on different servers. For example, if you manually initialize a server from another, the last change numbers are likely to differ.

The following example shows different last change numbers for two such servers:

```console
$ ldapsearch \
 --hostname existing-ds.example.com \
 --port 1636 \
 --useSsl \
 --trustStorePath /path/to/opendj/config/keystore \
 --trustStoreType PKCS12 \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN uid=admin \
 --bindPassword password \
 --baseDN "" \
 --searchScope base \
 "(&)" lastChangeNumber
```

> **Collapse: Show output**
>
> ```
> dn:
> lastChangeNumber: 285924
>
> Result Code:  0 (Success)
> ```

```console
$ ldapsearch \
 --hostname new-ds.example.com \
 --port 1636 \
 --useSsl \
 --trustStorePath /path/to/opendj/config/keystore \
 --trustStoreType PKCS12 \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN uid=admin \
 --bindPassword password \
 --baseDN "" \
 --searchScope base \
 "(&)" lastChangeNumber
```

> **Collapse: Show output**
>
> ```
> dn:
> lastChangeNumber: 198643
>
> Result Code:  0 (Success)
> ```

## Change number indexing

By default, replication servers let applications use cookies instead of change numbers when searching the changelog.

Adjust the replication server `changelog-enabled` settings appropriately on each replication server in your deployment:

* If applications need change notifications and use changelog cookies, leave the default setting `changelog-enabled: enabled-cookie-mode-only`.

* If applications need change notifications and use change numbers, use `changelog-enabled: enabled`.

  |   |                                                                                                                                            |
  | - | ------------------------------------------------------------------------------------------------------------------------------------------ |
  |   | Change number indexing requires more CPU, disk access, and storage. Enable it only when applications require change number-based browsing. |

* If no applications need notifications, use `changelog-enabled: disabled`.

* If applications need notifications for some domains but not for others, refer to [Exclude a domain](#ecl-exclude-domain).
