Skip to main content

About Active Directory (on-prem)

The Active Directory (on-prem) integration connects Serval directly to your on-premises Microsoft Active Directory - or another LDAP v3 directory - for user and group sync, group-based access management, and full directory operations from workflows. Unlike SaaS integrations, there is no OAuth and no vendor API: Serval speaks the LDAP protocol directly from the Serval worker, which dials only the server URL you configure. On self-hosted workers configured with local credentials, the worker reads your bind credentials from its own local store at execution time instead of fetching them from Serval’s cloud. Every operation uses a fresh, short-lived connection with TLS 1.2 as the minimum version. Authentication: LDAP simple bind with a dedicated service account (Server URL, Base DN, Bind DN, Bind Password, plus an optional CA certificate). Secrets are stored encrypted. Data sync: Background full sync - users every 4 hours, groups every 16 hours. LDAP has no change-log API, so there is no delta sync; each cycle re-reads the directory in full. Workflow actions (search, group changes, entry edits, password resets) run on demand.

What the Active Directory (on-prem) integration enables

Get your credentials

You need a dedicated Active Directory service account for Serval to bind with, your domain controller’s URL (ldaps:// on port 636 recommended), your domain’s Base DN, and - if your domain controller’s TLS certificate is issued by an internal CA - the root CA certificate in PEM format. Microsoft’s guide to enabling LDAPS is here: Enable LDAP over SSL with a third-party certification authority.
1

Create a service account

Open Active Directory Users and Computers and create a new user in an appropriate OU (for example CN=svc-serval,OU=ServiceAccounts,DC=corp,DC=example,DC=com). Set a strong, non-expiring password.
2

Grant least-privilege permissions

Grant the account read access to the OUs containing your users and groups. Delegate write access on group objects only if Serval should manage group membership, and Reset Password rights only if Serval should reset passwords.
3

Find your Base DN

Run (Get-ADDomain).DistinguishedName in PowerShell on a domain-joined machine, or ldapsearch -x -H ldap://dc01.corp.example.com -s base namingContexts from Linux.
4

Choose a connection method

Use LDAPS (ldaps://, port 636, recommended) or StartTLS (ldap://, port 389). If LDAPS is not yet enabled on the domain controller, provision a server certificate first (for example via AD CS auto-enrollment).
5

Export your root CA certificate (internal CAs only)

If the domain controller’s certificate is issued by an internal CA, export the root CA certificate in PEM format - for example certutil -ca.cert ca.pem on the DC, or openssl s_client -connect dc01.corp.example.com:636 -showcerts to capture the chain. Convert DER to PEM with certutil -encode ca.cer ca.pem or openssl x509 -inform der -in ca.cer -out ca.pem.
6

Verify the certificate

Before pasting it into Serval, confirm openssl s_client -connect dc01.corp.example.com:636 -CAfile ca.pem reports “Verify return code: 0 (ok)”.
7

Confirm network reachability

The host running the Serval worker must be able to resolve and reach the domain controller on the chosen port (636 or 389). For on-prem AD this usually means a hybrid self-hosted worker inside your network, or VPN/Direct Connect routing from the Serval deployment. See Private Network Access.
You need the issuing CA’s certificate (or the full chain), not the domain controller’s own server certificate. Pasting the wrong certificate is the most common cause of TLS verification failures.
A dedicated account named for its purpose (for example svc-serval) makes it easy to audit Serval’s directory activity later.

Connect in Serval

1

Enter the Server URL

Server URL (required) - for example “ldap://10.0.1.4:389 or ldaps://10.0.1.4:636”. As the helper text explains: “ldaps:// uses implicit TLS (port 636); ldap:// upgrades via StartTLS by default”. Anything else is rejected with “Must start with ldap:// or ldaps://” (the backend enforces the same: “serverUrl is required”, “serverUrl must start with ldap:// or ldaps://”). Your integration instance is identified and displayed by this URL.
2

Enter the Base DN

Base DN (required) - for example “DC=example,DC=com”. Leaving it empty fails with “baseDn is required”.
3

Enter the Bind DN

Bind DN (required) - the full DN of the service account, for example “CN=svc-connector,OU=ServiceAccounts,DC=example,DC=com”. Helper text: “Service account used to authenticate with LDAP”. Leaving it empty fails with “bindDn is required”.
4

Enter the Bind Password

Bind Password (required) - the service account password, stored encrypted. Leaving it empty on first connect fails with “bindPassword is required”.
5

Paste the CA Certificate (optional)

CA Certificate - optional PEM-encoded certificate beginning with “-----BEGIN CERTIFICATE-----”. Helper text: “Optional PEM-encoded CA certificate for verifying the LDAP server”. Required in practice whenever your domain controller uses an internal CA. A value that cannot be parsed causes every connection (including the health checks) to fail with “ldap: failed to parse CA certificate”.
6

Leave 'Allow plaintext LDAP' off unless you must

Allow plaintext LDAP - checkbox, off by default: “Skip StartTLS upgrade for ldap:// connections. Credentials are sent unencrypted - only enable if TLS is handled at the network layer (e.g. VPN or tunnel).” As the helper text notes: “When disabled (default), ldap:// connections are automatically upgraded to TLS via StartTLS.”
When you later edit the connection, Bind Password and CA Certificate display masked (bullets plus the last 4 characters). Leave them untouched to keep your stored secrets - Serval only replaces a secret when you actually type a new value.

Verifying the connection

After connecting, Serval runs three health checks:
All three checks green but access provisioning fails? The health checks only test read access. Adding or removing group members requires delegated write access on the target group objects - and provisioning also fails if the user’s email matches zero (or more than one) directory entry across mail and userPrincipalName.

Gotchas and troubleshooting

All LDAP traffic originates from the Serval worker’s built-in LDAP proxy, which dials your configured Server URL directly with a 10-second connection timeout. The worker host needs network routing and DNS resolution to the DC on port 636 (LDAPS) or 389 (LDAP/StartTLS) - typically via a hybrid self-hosted worker inside your network, or VPN/Direct Connect/Transit Gateway connectivity. On self-hosted workers configured with local credentials, the bind password is read from the worker’s local store at execution time. See Private Network Access.
ldaps:// uses implicit TLS; ldap:// is automatically upgraded via StartTLS unless “Allow plaintext LDAP” is enabled. Minimum TLS version is 1.2. Domain controllers using an internal CA will fail certificate verification until you paste the root CA (or full chain) in PEM format into the CA Certificate field - the issuing CA’s certificate, not the DC’s own server certificate.
User sync only ingests user objects that have a mail or userPrincipalName value, and group-member sync skips entries with neither (this deliberately excludes built-in accounts like Administrator and Guest). Computer accounts are always excluded. Many on-prem directories don’t populate mail for everyone - userPrincipalName is the fallback for both sync and access provisioning, and provisioning fails if a user’s email matches zero or multiple directory entries.
LDAP has no change-log API, so there is no delta sync: groups re-sync in full every 16 hours and users every 4 hours. Newly created AD groups or membership changes can take up to one full cycle to appear in Serval unless you trigger a sync manually.
Password resets write AD’s unicodePwd attribute (quoted, UTF-16LE encoded by Serval). Active Directory rejects these changes over plaintext, so password resets fail if “Allow plaintext LDAP” is enabled without TLS.
The single-page search actions default to a 1,000-entry limit, and when the server reports the limit was exceeded, the truncated result set is returned without an error. Use the paged “search all” variants (RFC 2696 paged results, 1,000 per page) when you need every entry.
Group member queries use Microsoft’s matching-rule-in-chain, so members of nested groups are included transitively and computer accounts are filtered out. Non-AD LDAP servers (such as OpenLDAP) don’t support this rule, making group-member operations effectively AD-specific. Plain user/group search and entry CRUD work against generic LDAP, and deactivation detection simply reports active when userAccountControl is absent.
On the edit screen, Bind Password and CA Certificate appear as bullets plus the last 4 characters. Submitting the form with those fields untouched preserves the stored secrets - only typed-in new values replace them.
The backend configuration accepts user and group search-base overrides that scope searches more narrowly than the Base DN (falling back to Base DN when empty), but the connect form does not expose them - it only collects Server URL, Base DN, Bind DN, Bind Password, CA Certificate, and the plaintext toggle.
Every search filter is validated before it is sent - invalid filters are rejected with “invalid LDAP filter: …”. Searches run with a 30-second server-side time limit, and request payloads are capped at 1 MB. Workflow builders should escape user-supplied filter values with the provided escape helper.

Need help? Contact support@serval.com for assistance with your Active Directory (on-prem) integration.