<!-- BusyBot node reference — https://busybot.net/tools/ldap/ -->

> Node: LDAP (`ldap`) · Action · v1
> Category: Development · Credentials: LDAP (`ldapApi`)
> Updated: 2026-08-16

# LDAP

> Interact with LDAP directory servers

## Overview

LDAP (Lightweight Directory Access Protocol) tool for interacting with directory services such as Active Directory, OpenLDAP, and other LDAP-compliant servers. Supports searching entries with filters, comparing attribute values, creating new entries, updating (add/replace/delete) attributes on existing entries, deleting entries, and renaming/moving entries by changing their distinguished name. Uses the ldapjs library for direct LDAP protocol communication over TCP with optional TLS/STARTTLS encryption.

**Category:** Development  
**Tool Name:** `ldap`  
**Version:** 1

**Appearance:** Icon: `lucide-Network` | Color: `#6C3483`

## Node Type

**Action** — processes input items and produces output

## Input / Output

| Direction | Port(s) |
|-----------|--------|
| Input | `Input` |
| Output | `Output`, `Error` |

## Credentials

This tool requires **LDAP** credentials.
See the [Credentials Guide](https://busybot.net/credentials/ldap-api/) for setup instructions.

### Operations

| Operation | Value | Description |
|-----------|-------|-------------|
| Compare | `compare` | Compare an attribute value |
| Create | `create` | Create a new entry |
| Delete | `delete` | Delete an entry |
| Rename | `rename` | Rename the DN of an existing entry |
| Search | `search` | Search the LDAP directory |
| Update | `update` | Update attributes on an existing entry |

### Parameters

#### Compare (`compare`)

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| DN | `string` | Yes | — | The distinguished name of the entry. Supports expressions like {{ $json.userDn }}. |
| Attribute ID | `string` | Yes | — | The attribute ID to compare. Find attribute names by performing a search operation on the entry first. Supports expressions. |
| Value | `string` | No | — | The value to compare the attribute against. Supports expressions. |

#### Create (`create`)

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| DN | `string` | Yes | — | The distinguished name of the entry. Supports expressions like {{ $json.userDn }}. |
| Attributes (`attributes`) | `fixedCollection` | No | `{}` | Attributes to add to the new entry. |
| — Attribute ID | `string` | Yes | — | The attribute name (e.g. cn, sn, mail, objectClass). |
| — Value | `string` | No | — | The value for this attribute. |

Repeat the Attribute group to set several attributes. Adding the same Attribute ID more than once builds a multi-valued attribute.

#### Delete (`delete`)

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| DN | `string` | Yes | — | The distinguished name of the entry. Supports expressions like {{ $json.userDn }}. |

#### Rename (`rename`)

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| DN | `string` | Yes | — | The distinguished name of the entry. Supports expressions like {{ $json.userDn }}. |
| New DN | `string` | Yes | — | The new distinguished name for the entry. Supports expressions. |

#### Search (`search`)

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Base DN | `string` | Yes | — | The distinguished name of the subtree to search in. Supports expressions. |
| Search For | `options` | No | `custom` | How to construct the search filter. Use "Custom Filter" for raw LDAP filter syntax, or "Object Class Filter" to build a filter from object class + attribute + search text. |
| | | | | Options: `custom` (use a custom LDAP filter string), `objectClass` (search by object class and attribute) |
| Custom Filter | `string` | No | `(objectclass=*)` | Raw LDAP filter string. Escape special characters (* ( ) \\) with a backslash. Example: (&(objectClass=person)(cn=john*)). Supports expressions. _(shown when Search For is `custom`)_ |
| Object Class | `string` | No | `(objectclass=*)` | LDAP object class filter. Use LDAP filter syntax, e.g. (objectclass=person), (objectclass=organizationalUnit). Type the object class name or use * for all. Supports expressions. _(shown when Search For is `objectClass`)_ |
| Attribute | `string` | Yes | — | Attribute name to search by (e.g. cn, mail, sn, uid). Find attribute names by first running a search with a custom filter like (objectclass=*). Supports expressions. _(shown when Search For is `objectClass`)_ |
| Search Text | `string` | Yes | — | Text to match against the attribute. Use * for wildcard matching. Supports expressions. _(shown when Search For is `objectClass`)_ |
| Return All | `boolean` | No | `false` | Whether to return all results or only up to a given limit. |
| Limit | `number` | No | `50` | Max number of results to return. _(shown when Return All is `false`)_ |
| Options | `collection` | No | `{}` | Additional search options. |
| — Attributes | `string` | No | — | Comma-separated list of attribute names to return in results. Leave empty to return all attributes. |
| — Page Size | `number` | No | `1000` | Maximum number of results to request at one time. Set to 0 to disable paging. |
| — Scope | `options` | No | `sub` | The set of entries at or below the BaseDN that may be considered potential matches. |
| | | | | Options: `base` (the base object only), `one` (one level below the base), `sub` (the whole subtree) |

In Object Class Filter mode, the Attribute and Search Text you supply are escaped before the filter is assembled, so a value containing `*`, `(`, `)` or `\` is matched literally rather than changing the filter's meaning. Use Custom Filter when you want wildcards in the value itself.

#### Update (`update`)

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| DN | `string` | Yes | — | The distinguished name of the entry. Supports expressions like {{ $json.userDn }}. |
| Update Attributes (`attributes`) | `fixedCollection` | No | `{}` | Attribute changes to apply. Use Add to add new values, Replace to change existing values, Remove to delete values. |
| — Add: Attribute ID | `string` | Yes | — | The attribute name to add. |
| — Add: Value | `string` | No | — | The value to add. |
| — Replace: Attribute ID | `string` | Yes | — | The attribute name to replace. |
| — Replace: Value | `string` | No | — | The new value for this attribute. |
| — Remove: Attribute ID | `string` | Yes | — | The attribute name to remove. |
| — Remove: Value | `string` | No | — | The specific value to remove (leave empty to remove all values for this attribute). |

Leaving Value empty on an Add or Replace group is rejected, because LDAP would read it as "delete every value of this attribute". Use a Remove group when that is what you want.

#### All Operations

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Max Concurrency | `number` | No | `1` | Maximum number of items to process concurrently. LDAP operations share a single connection, so keep this low to avoid issues. |

## Output Data

Binary data is forwarded unchanged on every operation. Everything else depends on whether you searched or wrote:

| Operation | Output items per input item |
|-----------|-----------------------------|
| `search` | **Fans out** — one item per matching entry. Each entry is **merged onto the input item JSON**, so upstream fields pass through. |
| `compare`, `create`, `delete`, `rename`, `update` | One item whose JSON **replaces** the input item JSON with the result object below. Upstream fields do **not** pass through. |

**Search entries** carry `dn` plus one property per returned attribute. A single-valued attribute is a string; a multi-valued attribute is an array. The Active Directory binary attributes `objectGUID` and `objectSid` are converted to hex strings so they survive JSON. Two flags may appear:

- `_searchResultCount: 0` — the search matched nothing, and one item is emitted anyway so the branch is not silently empty.
- `_truncated: true` — the directory server stopped early because of its own size limit, so the results are incomplete.

**Write results** carry:

| Operation | Fields |
|-----------|--------|
| `compare` | `dn`, `attribute`, `result` (`true` when the value matches) |
| `create` | `dn`, `result: "success"` |
| `delete` | `dn`, `result: "success"` |
| `rename` | `dn` (the **new** DN), `result: "success"` |
| `update` | `dn`, `result: "success"`, `changes[]` — one entry per modification, each `{ operation, modification: { type, values } }` |

**The item's own `dn` field wins.** For every operation except Search, if the incoming item JSON already has a `dn` property, that value is used as the target DN and the DN parameter is ignored. This makes it easy to chain a Search into a Delete or Update without wiring the DN through by hand — but it also means an unrelated upstream `dn` field will silently redirect the operation.

Reference the result downstream by expression, e.g. `{{ $json.dn }}` or `{{ $json.mail }}`.

## Usage Examples

- Search Active Directory for all users in a department
- Create a new LDAP entry for a user
- Update user attributes in LDAP directory
- Delete an LDAP directory entry
- Compare an attribute value for an entry
- Rename/move an LDAP entry to a different OU

## Example Configuration

Search a subtree with a raw LDAP filter, returning only selected attributes:

```json
{
  "type": "ldap",
  "parameters": {
    "operation": "search",
    "baseDN": "ou=users,dc=example,dc=com",
    "searchFor": "custom",
    "customFilter": "(&(objectClass=person)(department=Engineering))",
    "returnAll": false,
    "limit": 100,
    "options": {
      "attributes": "cn, mail, department",
      "scope": "sub",
      "pageSize": 1000
    }
  }
}
```

Search by object class and attribute instead of writing a filter:

```json
{
  "type": "ldap",
  "parameters": {
    "operation": "search",
    "baseDN": "ou=users,dc=example,dc=com",
    "searchFor": "objectClass",
    "objectClassFilter": "(objectclass=person)",
    "attribute": "mail",
    "searchText": "{{ $json.email }}",
    "returnAll": true
  }
}
```

Create a new entry:

```json
{
  "type": "ldap",
  "parameters": {
    "operation": "create",
    "dn": "cn={{ $json.username }},ou=users,dc=example,dc=com",
    "attributes": {
      "attribute": [
        { "id": "objectClass", "value": "inetOrgPerson" },
        { "id": "cn", "value": "{{ $json.username }}" },
        { "id": "sn", "value": "{{ $json.lastName }}" },
        { "id": "mail", "value": "{{ $json.email }}" }
      ]
    }
  }
}
```

Replace one attribute and remove another:

```json
{
  "type": "ldap",
  "parameters": {
    "operation": "update",
    "dn": "{{ $json.dn }}",
    "attributes": {
      "replace": [
        { "id": "department", "value": "{{ $json.newDepartment }}" }
      ],
      "delete": [
        { "id": "telephoneNumber", "value": "" }
      ]
    }
  }
}
```

Check whether an attribute holds a given value:

```json
{
  "type": "ldap",
  "parameters": {
    "operation": "compare",
    "dn": "{{ $json.dn }}",
    "id": "mail",
    "value": "{{ $json.email }}"
  }
}
```

Move an entry to a different OU:

```json
{
  "type": "ldap",
  "parameters": {
    "operation": "rename",
    "dn": "{{ $json.dn }}",
    "targetDn": "cn={{ $json.cn }},ou=archive,dc=example,dc=com"
  }
}
```

### Error Handling

| Mode | Behavior |
|------|----------|
| **stop** | Halts workflow on first error |
| **continue** | Skips failed items, passes successful ones through |
| **errorPort** | Routes failed items to Error output port |

## Tips

Search, create, update, delete, compare, and rename entries in LDAP directory servers like Active Directory or OpenLDAP.