Skip to content

Ldap

Shared LDAP configuration for all transcribes

Channel configuration for the LDAP listener. Only allow authenticated access to the LDAP channels.

Priority: SCRIBE_LDAP_AUTHENTICATION_REQUIRED > config

PropertyValue
Defaulttrue
OverrideSCRIBE_LDAP_AUTHENTICATION_REQUIRED (optional)
ldap.authentication-required = ${?SCRIBE_LDAP_AUTHENTICATION_REQUIRED}

Priority: SCRIBE_LDAP_BIND_DN > config

PropertyValue
Default""
OverrideSCRIBE_LDAP_BIND_DN (optional)
ldap.bind-dn = ${?SCRIBE_LDAP_BIND_DN}

Priority: SCRIBE_LDAP_BIND_PASSWORD > config

PropertyValue
Default""
OverrideSCRIBE_LDAP_BIND_PASSWORD (optional)
ldap.bind-password = ${?SCRIBE_LDAP_BIND_PASSWORD}

The configuration for the LDAP synchronization process. This setting represents a duration that is subtracted from the last saved checkpoint timestamp during the initial synchronization process. The resulting timestamp is used to find entries that were modified after this calculated point in time. The value of checkpoint-offset should be specified as a duration. For example, 30 seconds means that the system will look for entries modified in the 30 seconds before the last checkpoint, 1 minute means it will look for entries modified in the 1 minute before the last checkpoint, and 2 hours means it will look for entries modified in the 2 hours before the last checkpoint. The checkpoint-offset setting can be useful in situations where modifications might have occurred close to the checkpoint timestamp and could have been missed due to timing issues. By setting an appropriate checkpoint-offset, you can ensure that these modifications are included in the synchronization process. The default value for checkpoint-offset is 2 minutes.

Priority: SCRIBE_LDAP_CHECKPOINT_OFFSET > config

PropertyValue
Default2 minutes
OverrideSCRIBE_LDAP_CHECKPOINT_OFFSET (optional)
ldap.checkpoint-offset = ${?SCRIBE_LDAP_CHECKPOINT_OFFSET}

This setting represents the duration of inactivity, or ‘idle period’, after which the system performs certain operations.

  • Save the last modify timestamp as a checkpoint. The checkpoint is a timestamp marking

the last modification time. If no modifications are detected during this idle period, the system will save the current last modify timestamp as a checkpoint. The default value for idle-period is 5 seconds.

Priority: SCRIBE_LDAP_IDLE_PERIOD > config

PropertyValue
Default5 seconds
OverrideSCRIBE_LDAP_IDLE_PERIOD (optional)
ldap.idle-period = ${?SCRIBE_LDAP_IDLE_PERIOD}

This setting controls whether the system should ignore the last saved checkpoint timestamp during the synchronization process. When this setting is enabled (set to true), the system will perform a full synchronization, regardless of the last checkpoint. This means it will retrieve and process all entries, not just those that were modified after the last checkpoint. The ignore-checkpoint-timestamp setting can be useful in situations where you want to force a full synchronization, such as when you’re troubleshooting issues, recovering from errors, or ensuring that all entries are up-to-date. Please note that enabling ignore-checkpoint-timestamp can significantly increase the duration of the synchronization process, as it requires processing all entries. Therefore, it should be used judiciously and primarily in specific situations where a full synchronization is necessary.

Priority: SCRIBE_LDAP_IGNORE_CHECKPOINT_TIMESTAMP > config

PropertyValue
Defaultfalse
OverrideSCRIBE_LDAP_IGNORE_CHECKPOINT_TIMESTAMP (optional)
ldap.ignore-checkpoint-timestamp = ${?SCRIBE_LDAP_IGNORE_CHECKPOINT_TIMESTAMP}

The maximum number of entries to return in a search result.

Priority: SCRIBE_LDAP_MAX_SIZE_LIMIT > config

PropertyValue
Default5000
OverrideSCRIBE_LDAP_MAX_SIZE_LIMIT (optional)
ldap.max-size-limit = ${?SCRIBE_LDAP_MAX_SIZE_LIMIT}

The page-size configuration option determines the number of results to return per page in LDAP sync searches. The default value for page-size is concurrency * 8 (see blow). Adjusting the page-size can have significant effects on both the performance and memory usage of the LDAP sync operation:

  • Performance: A larger page-size can lead to faster LDAP searches as more results are returned in each operation,

reducing the total number of operations required to retrieve all results. This can be especially beneficial in environments where the network latency between the client and the LDAP server is high, as it reduces the impact of this latency.

  • Memory Usage: However, a larger page-size will also result in higher memory usage, as more results need to be stored

in memory at once. If memory usage is a concern, it may be necessary to reduce the page-size. Care should be taken when adjusting the page-size option. Setting it too high could cause excessive memory usage and potentially lead to OutOfMemoryErrors, particularly for large searches. On the other hand, setting it too low could negatively impact performance. As a starting point, the default page-size (concurrency * 8) is recommended. You can then adjust the page-size based on the specific needs and constraints of your environment, monitoring memory usage and performance as you do so to find the optimal balance. Remember that the optimal page-size may vary depending on factors such as the size of your dataset, the available memory, the network latency between the client and the LDAP server, and the specific LDAP operations you are performing.

Priority: SCRIBE_LDAP_PAGE_SIZE > config

PropertyValue
OverrideSCRIBE_LDAP_PAGE_SIZE (optional)
ldap.page-size = ${?SCRIBE_LDAP_PAGE_SIZE}

The reconciliation settings for the LDAP synchronization process. By default we do not run reconciliation for LDAP syncs because we get notifed of changes via the persistent search. If you want to run reconciliation for LDAP syncs, you either set the cron or interval. During startup the reconciliation task will be run for all entries that have not been modified since the last checkpoint regardless of the cron or interval. Enable scheduled reconciliation if:

  • Your LDAP server has unreliable persistent search delete notifications
  • You need guaranteed consistency checks for compliance
  • You experience frequent network partitions

Define a cron expression (unix cron format) to run the reconciliation task at a specific time Default not set, eg no cron window

Priority: SCRIBE_LDAP_RECONCILIATION_CRON > config

cron = ‘0 5 * * *’ # 5am daily

PropertyValue
OverrideSCRIBE_LDAP_RECONCILIATION_CRON (optional)
ldap.reconciliation.cron = ${?SCRIBE_LDAP_RECONCILIATION_CRON}

If enabled, the reconciliation task will be scheduled Defaults to enabled unless readonly is set to true

Priority: SCRIBE_LDAP_RECONCILIATION_ENABLED > config

PropertyValue
Defaulttrue
OverrideSCRIBE_LDAP_RECONCILIATION_ENABLED (optional)
ldap.reconciliation.enabled = ${?SCRIBE_LDAP_RECONCILIATION_ENABLED}

Used after full interval, to check if system can proceed with reconciliation. More permissive than soft thresholds - allows running under moderate load. Only used if interval is set. Defaults to (pressure-based, normalized 0..1 ratios):

Priority: SCRIBE_LDAP_RECONCILIATION_HARD_THRESHOLDS > config

hard-thresholds = {
scribe_ingest_task_pressure = 1.0 # At steady state, not building backlog
scribe_query_permit_pressure = 0.7 # 70% query capacity
jvm_memory_pressure = 0.9 # 90% heap used
}
PropertyValue
OverrideSCRIBE_LDAP_RECONCILIATION_HARD_THRESHOLDS (optional)
ldap.reconciliation.hard-thresholds = ${?SCRIBE_LDAP_RECONCILIATION_HARD_THRESHOLDS}

Define the interval at which the reconciliation task will be run. Thresholds are used to check if the system is idle enough to run the reconciliation task. Values are queried directly from ScribeMetrics (not Prometheus). Any registered gauge can be used. IMPORTANT: If a configured metric is not registered, it will be skipped (logged at WARN level) and will NOT block task execution. Check startup logs for warnings about unregistered metrics. Commonly available gauges (pressure metrics use normalized 0..1 ratios): Pressure metrics (recommended for thresholds):

  • scribe_ingest_task_pressure # ~1.0=steady, <1.0=idle, >1.0=backlog building
  • scribe_ingest_queue_pressure # 0..1 queue fill ratio
  • scribe_query_permit_pressure # 0..1 query permit utilization
  • jvm_memory_pressure # 0..1 heap used/max ratio

Active counts (legacy, requires tuning per deployment):

  • scribe_ingest_tasks_active # Number of active ingest tasks
  • scribe_db_connections_active # Number of active DB connections
  • scribe_ldap_connections_active # Number of active LDAP connections

Other JVM metrics:

  • jvm_thread_count # Active thread count
  • jvm_cpu_count # Available processors

The default value for interval is not set

Priority: SCRIBE_LDAP_RECONCILIATION_INTERVAL > config

PropertyValue
Default18 hour
OverrideSCRIBE_LDAP_RECONCILIATION_INTERVAL (optional)
ldap.reconciliation.interval = ${?SCRIBE_LDAP_RECONCILIATION_INTERVAL}

Used after half of interval, to check if system is idle enough to run reconciliation. All thresholds must be met (metric value <= threshold) for the task to run. Only used if interval is set. Defaults to (pressure-based, normalized 0..1 ratios):

Priority: SCRIBE_LDAP_RECONCILIATION_SOFT_THRESHOLDS > config

soft-thresholds = {
scribe_ingest_task_pressure = 0.5 # Processing at 2x arrival rate (idle)
scribe_query_permit_pressure = 0.3 # 30% query capacity used
jvm_memory_pressure = 0.7 # 70% heap used
}
PropertyValue
OverrideSCRIBE_LDAP_RECONCILIATION_SOFT_THRESHOLDS (optional)
ldap.reconciliation.soft-thresholds = ${?SCRIBE_LDAP_RECONCILIATION_SOFT_THRESHOLDS}

The attributes that should be considered to only have one value. All attributes that are marked as single-value within the schema will be considered single-value automatically and do not need to be listed here. Can be a single string or a list of strings.

Priority: SCRIBE_LDAP_SINGLE_VALUE_ATTRIBUTES > config

single-value-attributes = [
"cn uid ou",
"sn givenName initials displayName fullName",
"employeeNumber, employeeStatus, employeeType"
]
PropertyValue
OverrideSCRIBE_LDAP_SINGLE_VALUE_ATTRIBUTES (optional)
ldap.single-value-attributes = ${?SCRIBE_LDAP_SINGLE_VALUE_ATTRIBUTES}

When the SO_TIMEOUT option is set for a TCP socket, it specifies the maximum amount of time in milliseconds that a read or write operation on the socket will block before timing out.

Default: 0 (read and write operations block indefinitely)

Priority: SCRIBE_LDAP_SO_TIMEOUT > LDAP_SO_TIMEOUT > SO_TIMEOUT > config

PropertyValue
Default0
OverrideSCRIBE_LDAP_SO_TIMEOUT (optional) > LDAP_SO_TIMEOUT (standard) > SO_TIMEOUT (standard)
ldap.so-timeout = 0
ldap.so-timeout = ${?SO_TIMEOUT}
ldap.so-timeout = ${?LDAP_SO_TIMEOUT}
ldap.so-timeout = ${?SCRIBE_LDAP_SO_TIMEOUT}

defaults to the root ssl configuration

The PEM file or directory from which to read the trusted certificate information. May be a file (which may contain one or more PEM-formatted certificates) or a directory (in which case all of the files in that directory, including subdirectories will be recursively processed).

Priority: SCRIBE_LDAP_SSL_CA > config > ssl.ca

PropertyValue
Default"relative/from/config/file/ca.pem"
OverrideSCRIBE_LDAP_SSL_CA (optional)
ldap.ssl.ca = ${?SCRIBE_LDAP_SSL_CA}

The file containing the PEM-formatted X.509 representations of the certificates in the certificate chain. It must contain at least one certificate (the end entity certificate), but may contain additional certificates as needed for the complete certificate chain. Certificates should be ordered such that the first certificate must be the end entity certificate, and each subsequent certificate must be the issuer for the previous certificate. The chain does not need to be complete as long as the peer may be expected to have prior knowledge of any missing issuer certificates.

Priority: SCRIBE_LDAP_SSL_CERT > config > ssl.cert

PropertyValue
Default"relative/from/config/file/cert.pem"
OverrideSCRIBE_LDAP_SSL_CERT (optional)
ldap.ssl.cert = ${?SCRIBE_LDAP_SSL_CERT}

The file containing the PEM-formatted PKCS #8 representation of the private key for the end entity certificate. It must contain exactly one PEM-encoded private key. The private key may optionally be encrypted.

Priority: SCRIBE_LDAP_SSL_KEY > config > ssl.key

PropertyValue
Default"relative/from/config/file/cert.pem"
OverrideSCRIBE_LDAP_SSL_KEY (optional)
ldap.ssl.key = ${?SCRIBE_LDAP_SSL_KEY}

The password needed to decrypt the private key if it is encrypted.

Priority: SCRIBE_LDAP_SSL_PASSWORD > config > ssl.password

PropertyValue
Default"..."
OverrideSCRIBE_LDAP_SSL_PASSWORD (optional)
ldap.ssl.password = ${?SCRIBE_LDAP_SSL_PASSWORD}

When the TCP_KEEPCOUNT option is set for a TCP socket, it specifies the number of keepalive probes that will be sent before the connection is considered invalid.

Default: 10

Priority: SCRIBE_LDAP_TCP_KEEPCOUNT > LDAP_TCP_KEEPCOUNT > TCP_KEEPCOUNT > config

PropertyValue
Default10
OverrideSCRIBE_LDAP_TCP_KEEPCOUNT (optional) > LDAP_TCP_KEEPCOUNT (standard) > TCP_KEEPCOUNT (standard)
ldap.tcp-keepcount = 10
ldap.tcp-keepcount = ${?TCP_KEEPCOUNT}
ldap.tcp-keepcount = ${?LDAP_TCP_KEEPCOUNT}
ldap.tcp-keepcount = ${?SCRIBE_LDAP_TCP_KEEPCOUNT}

When the TCP_KEEPIDLE option is set for a TCP socket, it specifies the idle time in seconds after which the connection will be tested to see if it is still valid.

Default: 120 seconds

Priority: SCRIBE_LDAP_TCP_KEEPIDLE > LDAP_TCP_KEEPIDLE > TCP_KEEPIDLE > config

PropertyValue
Default120
OverrideSCRIBE_LDAP_TCP_KEEPIDLE (optional) > LDAP_TCP_KEEPIDLE (standard) > TCP_KEEPIDLE (standard)
ldap.tcp-keepidle = 120
ldap.tcp-keepidle = ${?TCP_KEEPIDLE}
ldap.tcp-keepidle = ${?LDAP_TCP_KEEPIDLE}
ldap.tcp-keepidle = ${?SCRIBE_LDAP_TCP_KEEPIDLE}

When the TCP_KEEPINTERVAL option is set for a TCP socket, it specifies the interval in seconds at which the connection will be tested to see if it is still valid.

Default: 30 seconds

Priority: SCRIBE_LDAP_TCP_KEEPINTERVAL > LDAP_TCP_KEEPINTERVAL > TCP_KEEPINTERVAL > config

PropertyValue
Default30
OverrideSCRIBE_LDAP_TCP_KEEPINTERVAL (optional) > LDAP_TCP_KEEPINTERVAL (standard) > TCP_KEEPINTERVAL (standard)
ldap.tcp-keepinterval = 30
ldap.tcp-keepinterval = ${?TCP_KEEPINTERVAL}
ldap.tcp-keepinterval = ${?LDAP_TCP_KEEPINTERVAL}
ldap.tcp-keepinterval = ${?SCRIBE_LDAP_TCP_KEEPINTERVAL}

Multiple servers can be specified, separated by a comma, eg “ldap://server1,server2”

Priority: SCRIBE_LDAP_URL > config

PropertyValue
Default"ldap://localhost"
OverrideSCRIBE_LDAP_URL (optional)
ldap.url = "ldap://localhost"
ldap.url = ${?SCRIBE_LDAP_URL}

When the keepalive option is set for a TCP socket and no data has been exchanged across the socket in either direction for a configurable number of seconds, the connection is tested to see if it is still valid.

Priority: SCRIBE_LDAP_SO_KEEPALIVE > LDAP_SO_KEEPALIVE > SO_KEEPALIVE > config

PropertyValue
Defaulttrue
OverrideSCRIBE_LDAP_SO_KEEPALIVE (optional) > LDAP_SO_KEEPALIVE (standard) > SO_KEEPALIVE (standard)
ldap.use-keep-alive = true
ldap.use-keep-alive = ${?SO_KEEPALIVE}
ldap.use-keep-alive = ${?LDAP_SO_KEEPALIVE}
ldap.use-keep-alive = ${?SCRIBE_LDAP_SO_KEEPALIVE}

When the TCP_NODELAY option is set for a TCP socket, it disables the Nagle algorithm for that socket.

Priority: SCRIBE_LDAP_TCP_NODELAY > LDAP_TCP_NODELAY > TCP_NODELAY > config

PropertyValue
Defaulttrue
OverrideSCRIBE_LDAP_TCP_NODELAY (optional) > LDAP_TCP_NODELAY (standard) > TCP_NODELAY (standard)
ldap.use-tcp-no-delay = true
ldap.use-tcp-no-delay = ${?TCP_NODELAY}
ldap.use-tcp-no-delay = ${?LDAP_TCP_NODELAY}
ldap.use-tcp-no-delay = ${?SCRIBE_LDAP_TCP_NODELAY}

Virtual Attributes (Computed at query-time) - EXPERIMENTAL

  • filter: an LDAP filter template evaluated against “other” entries with

{{self.entryDN}} referencing the DN of the current entry

  • value: which field to return from the matching “other” entry

Supported value selectors: {{other.entryDN}}, {{other.entryUUID}}, {{other.entryType}}, {{other.etag}}, {{other.createTimestamp}}, {{other.modifyTimestamp}}, {{other.<attributeName>}}

1. Self-reference filters (no {{self.*}} placeholders): Automatically wrapped with identity binding and evaluated against the current entry. No entryType needed—the current entry’s type is implicit.

# Self-reference: checks current entry's own attributes
accountStatus {
filter = "(|(loginDisabled=TRUE)(lockedByIntruder=TRUE))"
value = "disabled"
}

2. Cross-reference filters (contains {{self.*}} placeholders): Evaluated against “other” entries to find related data. Include entryType in the filter for efficient subqueries—a startup warning is logged if missing.

# Cross-reference: finds groups where current user is a member
memberOf {
filter = "(&(entryType=groups)(member={{self.entryDN}}))"
value = "{{other.entryDN}}"
}

3. Explicit self-wrap (comparing self attributes): Use full binding pattern when comparing attributes of the current entry to itself.

Filters can be specified in LDAP, SCIM, or JSON syntax (auto-detected):

# LDAP syntax
filter = "(member={{self.entryDN}})"
# SCIM syntax
filter = "member eq \"{{self.entryDN}}\""
# JSON syntax
filter = "{\"member\": \"{{self.entryDN}}\"}"

By default, virtual attributes cannot be delegated to the upstream LDAP backend. The optional delegatable config controls delegation behavior:

  • false (default): Cannot be delegated
  • true: Delegatable using the same attribute name
  • "backendAttrName": Delegatable with name rewriting

By default, virtual attributes defined at root level are exposed on ALL entry types in REST/GraphQL schemas. Use the optional types field to restrict which entry types expose the virtual attribute:

# Only expose memberOf on user type
memberOf {
types = ["user"]
filter = "(&(entryType=group)(member={{self.entryDN}}))"
value = "{{other.entryDN}}"
}
# Expose on multiple types
sharedAttr {
types = ["user", "admin"]
filter = "..."
value = "..."
}

Behavior:

  • If types is omitted: VA is exposed on all types (backward compatible)
  • If types is specified: VA only appears on those types
  • Transcribe-level VAs automatically include their transcribe’s type
  • If same VA is defined in multiple transcribes, types are merged (union)

Format: List ["user", "group"] or comma-separated string "user, group"

PropertyValue
Default{}
OverrideSCRIBE_LDAP_VIRTUAL_ATTRIBUTES (optional)
ldap.virtual-attributes = ${?SCRIBE_LDAP_VIRTUAL_ATTRIBUTES}