Active Directory Module¶
Section: Modules | Article 32
Audience: System Administrators
Last Updated: 2026-04-07
Overview¶
The Active Directory (AD) module connects RP-PAM to your on-premises Active Directory environment. It enables RP-PAM to:
- Discover and import users and groups from AD
- Manage group memberships (add/remove users) for just-in-time access provisioning
- Rotate service account passwords
- Read audit logs for anomaly detection
Prerequisites¶
| Requirement | Detail |
|---|---|
| Service accounts created | All three AD service accounts (DRA, PA, ARA) set up per Article 20 |
| Credentials stored in vault | Service account passwords encrypted and stored via rppam-migrate setup-accounts |
| LDAPS (port 636) | LDAPS is required. RP-PAM does not support unencrypted LDAP (port 389) |
| Network access | RP-PAM server can reach at least one domain controller on port 636 |
| Trusted certificate | The domain controller's LDAPS certificate must be trusted by the RP-PAM server |
Why LDAPS Is Required¶
RP-PAM transmits service account credentials over the LDAP connection. Unencrypted LDAP would expose these credentials to network sniffing. LDAPS (LDAP over TLS) encrypts the entire connection.
If your domain controllers do not yet have LDAPS enabled, you must configure it before proceeding. This typically involves: 1. Installing a certificate on each domain controller (from your internal CA or a public CA). 2. Verifying LDAPS connectivity on port 636.
Module Configuration¶
Add or update the AD module configuration in rppam.config.
Windows path: C:\ProgramData\Ravenphyre\RP-PAM\rppam.config
Linux path: /etc/rppam/rppam.config
{
"modules": {
"activeDirectory": {
"enabled": true,
"domain": "corp.local",
"domainControllers": [
"dc1.corp.local",
"dc2.corp.local"
],
"port": 636,
"useLdaps": true,
"validateCertificate": true,
"baseDn": "DC=corp,DC=local",
"serviceAccounts": {
"draVaultKey": "ad-dra-credential",
"paVaultKey": "ad-pa-credential",
"araVaultKey": "ad-ara-credential"
},
"syncIntervalMinutes": 15,
"userSearchBase": "OU=Users,DC=corp,DC=local",
"userSearchFilter": "(&(objectClass=user)(objectCategory=person)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))",
"groupSearchBase": "DC=corp,DC=local",
"groupSearchFilter": "(objectClass=group)",
"managedOUs": [
"OU=Privileged Groups,DC=corp,DC=local",
"OU=Application Groups,DC=corp,DC=local"
],
"excludeGroups": [
"Domain Admins",
"Enterprise Admins",
"Schema Admins"
],
"pageSize": 1000,
"connectionTimeoutSeconds": 10,
"operationTimeoutSeconds": 30
}
}
}
Configuration Field Reference¶
| Field | Description | Required | Default |
|---|---|---|---|
enabled |
Enable the AD module | Yes | false |
domain |
The AD domain name | Yes | -- |
domainControllers |
List of domain controller hostnames or IPs | Yes | -- |
port |
LDAPS port | No | 636 |
useLdaps |
Use LDAPS (TLS). Must be true. |
Yes | true |
validateCertificate |
Validate the DC's TLS certificate | No | true |
baseDn |
Root distinguished name for the domain | Yes | -- |
serviceAccounts.draVaultKey |
Vault key for the DRA credential | Yes | -- |
serviceAccounts.paVaultKey |
Vault key for the PA credential | Yes | -- |
serviceAccounts.araVaultKey |
Vault key for the ARA credential | Yes | -- |
syncIntervalMinutes |
How often to sync users and groups from AD | No | 15 |
userSearchBase |
OU to search for users | No | baseDn |
userSearchFilter |
LDAP filter for user discovery | No | Active, non-disabled users |
groupSearchBase |
OU to search for groups | No | baseDn |
groupSearchFilter |
LDAP filter for group discovery | No | All group objects |
managedOUs |
OUs where RP-PAM is allowed to modify group memberships | Yes | -- |
excludeGroups |
Groups that RP-PAM must never modify | No | Built-in admin groups |
pageSize |
LDAP search page size | No | 1000 |
connectionTimeoutSeconds |
Timeout for LDAP connection attempts | No | 10 |
operationTimeoutSeconds |
Timeout for individual LDAP operations | No | 30 |
Enable the Module¶
Using the Web Portal¶
- Log in as
pam_admin. - Navigate to Modules > Active Directory.
- Fill in the configuration fields.
- Click Test Connection to verify connectivity.
- Click Enable.
Using the API¶
Linux:
curl -s -X PUT http://localhost:7101/api/v1/modules/activeDirectory/config \
-H "Authorization: Bearer $ADMIN_JWT" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"domain": "corp.local",
"domainControllers": ["dc1.corp.local"],
"baseDn": "DC=corp,DC=local",
"serviceAccounts": {
"draVaultKey": "ad-dra-credential",
"paVaultKey": "ad-pa-credential",
"araVaultKey": "ad-ara-credential"
},
"managedOUs": ["OU=Privileged Groups,DC=corp,DC=local"]
}' | jq .
PowerShell:
$config = @{
enabled = $true
domain = "corp.local"
domainControllers = @("dc1.corp.local")
baseDn = "DC=corp,DC=local"
serviceAccounts = @{
draVaultKey = "ad-dra-credential"
paVaultKey = "ad-pa-credential"
araVaultKey = "ad-ara-credential"
}
managedOUs = @("OU=Privileged Groups,DC=corp,DC=local")
} | ConvertTo-Json -Depth 3
Invoke-RestMethod -Uri "http://localhost:7101/api/v1/modules/activeDirectory/config" `
-Method Put `
-Headers @{ Authorization = "Bearer $adminJwt" } `
-ContentType "application/json" `
-Body $config
Restart and Verify¶
After saving the configuration, restart RP-PAM.
Windows PowerShell:
Linux:
Check Module Status¶
Linux:
curl -s http://localhost:7101/api/v1/modules \
-H "Authorization: Bearer $ADMIN_JWT" | jq '.items[] | select(.moduleName == "activeDirectory")'
PowerShell:
$modules = Invoke-RestMethod -Uri "http://localhost:7101/api/v1/modules" `
-Headers @{ Authorization = "Bearer $adminJwt" }
$modules.items | Where-Object { $_.moduleName -eq "activeDirectory" } | ConvertTo-Json
Expected:
{
"moduleName": "activeDirectory",
"status": "healthy",
"domain": "corp.local",
"lastSync": "2026-04-07T10:00:00Z",
"usersDiscovered": 500,
"groupsManaged": 12,
"domainControllersReachable": 2
}
Verify User Lookup¶
Linux:
curl -s "http://localhost:7101/api/v1/users?source=activeDirectory&limit=5" \
-H "Authorization: Bearer $ADMIN_JWT" | jq '.items[].displayName'
PowerShell:
$users = Invoke-RestMethod -Uri "http://localhost:7101/api/v1/users?source=activeDirectory&limit=5" `
-Headers @{ Authorization = "Bearer $adminJwt" }
$users.items | Select-Object displayName, samAccountName | Format-Table
Verify Group Management¶
Linux:
curl -s "http://localhost:7101/api/v1/resources?source=activeDirectory&type=group&limit=5" \
-H "Authorization: Bearer $ADMIN_JWT" | jq '.items[].displayName'
PowerShell:
$groups = Invoke-RestMethod -Uri "http://localhost:7101/api/v1/resources?source=activeDirectory&type=group&limit=5" `
-Headers @{ Authorization = "Bearer $adminJwt" }
$groups.items | Select-Object displayName, memberCount | Format-Table
LDAPS Certificate Trust¶
If validateCertificate is true (recommended), the RP-PAM server must trust the certificate presented by the domain controller.
Linux¶
Add your internal CA certificate to the system trust store:
# Copy the CA cert
sudo cp corp-ca.crt /usr/local/share/ca-certificates/corp-ca.crt
# Update the trust store
sudo update-ca-certificates
Windows¶
Import the CA certificate into the Local Machine certificate store:
Temporarily Disable Validation (Testing Only)¶
For testing, you can set "validateCertificate": false. This disables certificate validation and is not recommended for production.
Troubleshooting¶
| Problem | Cause | Solution |
|---|---|---|
"status": "unhealthy" |
Cannot connect to any domain controller | Verify LDAPS connectivity: openssl s_client -connect dc1.corp.local:636 or Test-NetConnection dc1.corp.local -Port 636 |
"LDAP error: Invalid credentials" |
DRA/PA/ARA password incorrect or expired | Re-store credentials with rppam-migrate setup-accounts |
"Certificate validation failed" |
DC certificate not trusted by RP-PAM server | Import the CA certificate into the server's trust store (see above) |
| No users discovered | userSearchBase or userSearchFilter too restrictive |
Broaden the search base or simplify the filter; test with ldapsearch |
| Groups visible but PA cannot modify members | Delegation not configured on the OU | Re-run delegation for the PA account (see Article 20, Step 3) |
"Connection timed out" |
Firewall blocking port 636 | Open port 636 from the RP-PAM server to the domain controllers |
| Sync takes too long | Too many objects or low pageSize |
Increase pageSize to 2000; narrow userSearchBase to specific OUs |
"Referral returned" |
Search crosses domain boundaries in a forest | Set baseDn to the specific domain, not the forest root |
excludeGroups not working |
Group name mismatch (case-sensitive) | Verify the exact group name in AD matches the excludeGroups entry |
Next Steps¶
- Entra ID Module -- Configure the Entra ID module for cloud identity management
- Service Account Setup (AD) -- Review service account configuration
- Configuration Reference -- Full module configuration options
RP-PAM v1.0.0 -- Copyright 2026 Ravenphyre. All rights reserved.