PAM › Admin Guide
Active Directory
Connect GAccess to an on-premises Active Directory domain with the GAccess AD Agent — install, configure, sync, monitor, run in high availability, upgrade and remove agents
Active Directory
GAccess connects to on-premises Active Directory (AD) through a lightweight agent installed inside your network. The agent only makes outbound connections: to a domain controller over LDAPS, and to GAccess over HTTPS with mutual TLS (mTLS). No inbound firewall rule is needed.
The agent has two jobs:
- Sync users and groups from AD to GAccess.
- Validate passwords of AD users when they log in to GAccess. Passwords are never stored in GAccess.
Prerequisites
- A break-glass account in GAccess. An identity source cannot be added until at least one local break-glass account exists. It is your way in if the directory or the agents are unavailable.
- A Linux server for the agent — x86_64 (64-bit Intel or AMD), with systemd (RHEL, Rocky, Alma, Amazon Linux, Debian, Ubuntu). For high availability, plan two or more servers.
- Network access from the agent server:
| To | Port | Purpose |
|---|---|---|
| A domain controller | TCP 636 (LDAPS) | Sync and password validation. Plain LDAP (389) is not supported. |
gateway.<your-gaccess-host> (e.g. gateway.acme.gaccess.cloud) |
TCP 443 (HTTPS, mTLS) | Everything between the agent and GAccess. An HTTPS proxy can be used — see Proxy configuration. |
- A valid TLS certificate on the domain controller. If it is issued by an internal CA, have that CA certificate ready in PEM format.
- A read-only AD service account. It needs no admin rights, but it must be able to read the users and groups you sync — including every group in the Sync Groups list (see Sync parameters).
- Accurate time on the agent server (NTP). TLS certificates and the certificate renewal check depend on it.
How it works
Enrollment and certificates
When an agent is registered, it creates a 2048-bit RSA key pair on the server and sends a certificate request to GAccess together with a one-time registration token. GAccess signs it with your tenant's certificate authority and returns a client certificate. From then on, every request from the agent is authenticated with that certificate. The private key never leaves the server.
- Registration tokens are valid for 60 minutes and can be used once.
- Agent certificates are valid for 45 days. From agent version 0.2.0, the agent renews its certificate automatically 15 days before it expires (checked at start and every 12 hours) — no action is needed. The new certificate only replaces the old one once the agent has used it successfully, so an interrupted renewal never disconnects the agent.
Configuration delivery
The agent server stores no AD settings and no AD credentials. At start, the agent fetches its configuration (server URL, Base DN, Bind DN, bind password, sync and TLS settings) from GAccess over mTLS and keeps it in memory only. It checks for changes every 5 minutes; when something changes, it reconnects to AD with the new settings. You never edit anything on the agent server after registration.
Login (password validation)
- GAccess picks an agent that sent a heartbeat in the last 90 seconds and has LDAP connectivity, and encrypts the password with that agent's public key (RSA-OAEP, SHA-256).
- The agent, which keeps a long-poll open to GAccess, receives the request and decrypts the password in memory.
- It looks up the user by UPN and binds to the domain controller as that user, on a dedicated connection.
- It returns the result to GAccess, which completes or rejects the login. MFA, if configured, follows a successful bind.
A login request is valid for 30 seconds; if no agent answers within about 10 seconds, the user sees Authentication is temporarily unavailable. The password is never stored or logged.
What the user sees when the bind fails:
| AD result | Shown to the user | Counts towards GAccess lockout |
|---|---|---|
| Wrong password, unknown user, account locked, disabled or expired in AD, password expired or must change, logon hours/workstation restriction | Invalid credentials | Yes |
| No agent online, agent cannot reach AD, request expired | Authentication is temporarily unavailable | No |
Failed logins lock the GAccess account after the number of attempts set in Organization → Security → Account Lockout (default 5 attempts, locked for 30 minutes; configurable from 3 to 20 attempts and 5 to 1440 minutes). An administrator can unlock it early from Users. AD users change their password in AD; GAccess password reset and "forgot password" do not apply to them.
alice@corp.example.com). They must have been synced to GAccess first.Sync
On each cycle, the agent reads the configured scope from AD and compares it with what it last sent successfully. Only new or changed users and groups are sent, plus removals for objects no longer returned. If nothing changed, nothing is sent.
GAccess applies each sync as follows:
- Users are matched by their AD object GUID. New users are created without roles. For existing users, name, email and status are updated. If a user's UPN changes in AD, their GAccess username follows it.
- Groups are matched by GUID, named
<group name>@<AD domain>(e.g.Engineering@corp.example.com). Membership is replaced with the current AD membership. A renamed group stays the same GAccess group, so roles and access policies attached to it keep working. - Removed users are disabled in GAccess, and re-enabled automatically if they come back.
- Removed groups are archived, not deleted, so their role assignments are kept; they are restored if the same group (same GUID) comes back.
An object counts as removed when it is deleted in AD, but also when it leaves the sync scope: moved out of the OU scopes, no longer a direct member of a sync group, or — for users — disabled in AD.
Sync never changes roles, permissions or access policies assigned in GAccess.
Step 1 — Create the identity source
- In the sidebar, open Identity Sources and click Add Identity Source.
- Enter a Name and select Active Directory.
- Fill in the Configuration card:
| Field | Description |
|---|---|
| AD Domain | The DNS name of the domain (e.g. corp.example.com). Used to name synced groups. Cannot be changed after creation, and each domain can be added only once. |
| Sync Interval | How often the leader agent syncs: every 5, 10, 15 (default), 30 or 60 minutes. |
| AD Server URL | The LDAPS endpoint, e.g. ldaps://dc01.corp.example.com:636, or the domain (ldaps://corp.example.com) to let DNS pick a domain controller. Must start with ldaps://. |
| Base DN | Where searches start, e.g. DC=corp,DC=example,DC=com. |
| Bind DN | The read-only service account, e.g. CN=svc-gaccess,OU=ServiceAccounts,DC=corp,DC=example,DC=com. |
| Bind Password | The service account password. Stored encrypted in GAccess and sent only to registered agents, which keep it in memory. On the edit page, leave it empty to keep the current password. |
| OU Scopes | Optional. See Sync parameters. |
| Sync Groups | Optional. See Sync parameters. |
| Advanced TLS settings | Optional. See TLS. |
- Click Create Identity Source. GAccess then offers to add the first agent — follow Step 2, or choose Skip for now and add it later from the identity source.
Every setting except AD Domain can be changed later. Running agents apply changes within 5 minutes.
Sync parameters
OU Scopes
Restricts users and groups to one or more organisational units. Add one full DN per line (e.g. OU=Staff,DC=corp,DC=example,DC=com). Leave it empty to search the whole Base DN. Sub-OUs are included.
Sync Groups
Limits the sync to the direct members of the listed groups. Add each group's full DN (e.g. CN=GAccess-Users,OU=Groups,DC=corp,DC=example,DC=com).
- Empty list: every enabled user in the OU scopes is synced, with all groups in scope.
- With groups: only those groups are synced, and only users who are direct members of at least one of them (and inside the OU scopes). Members of nested groups are not included — list the nested group too.
- Only enabled AD accounts are synced, with or without sync groups.
Groups are followed by their identity (agent 0.2.0 or later). After the first sync, the agent remembers each group's GUID, so a group that is renamed or moved in AD is still found; GAccess updates the DN in the list automatically and nobody loses access.
A group that is not found removes its members. If a listed group is deleted, its DN is mistyped, or the service account cannot read it, the agent treats it as having no members: its users are removed from the sync (and disabled in GAccess) and the group is archived. If none of the listed groups is found, every synced user is disabled. GAccess raises an AD sync group not found alert for each missing group — see Alerts. Before saving the list:
- copy each DN from AD (e.g. Active Directory Users and Computers → Attribute Editor → distinguishedName);
- check that the service account can read the groups;
- upgrade all agents to 0.2.0 or later first (see below).
When you save a change that will remove users (adding the first group, or removing a group), GAccess asks you to confirm first.
Group limits
| Limit | Value | What happens above it |
|---|---|---|
| Groups in the Sync Groups list | 50 | The identity source cannot be saved. |
| Direct members per synced group | about 25,000 | The group is not synced (its members still are, if in scope). The agent logs too large to send in one request — not synced on every sync. Split the group, or use several smaller groups. |
| Nested groups | Not expanded | Only direct members are synced. List nested groups explicitly. |
| Primary group (e.g. Domain Users) | Not supported as a sync group | AD does not list primary-group members in the group's member attribute. Use a regular security group. |
| Group names | Unique among active GAccess groups | If a renamed AD group's new name is already used by another active group, the group keeps its old name in GAccess. Rename one of them. |
Groups with more than 1,500 members are read in pages, so large groups below the limit are synced in full.
Attribute mapping
| AD attribute | GAccess field | Behaviour |
|---|---|---|
objectGUID |
External ID | Permanent link between the AD object and GAccess |
userPrincipalName |
Username | Follows UPN changes. Falls back to sAMAccountName@<domain> if empty. |
displayName |
Name | Updated on every change |
mail |
Updated on every change. Falls back to the UPN if empty. | |
userAccountControl |
Status | Disabled accounts are not synced, so they are disabled in GAccess |
member (groups) |
Group members | Direct members only, within the sync scope |
TLS
The agent connects to AD over LDAPS only and verifies the domain controller's certificate.
- Public or domain-trusted CA: nothing to configure if the CA is in the agent server's system trust store.
- Internal CA: open Advanced TLS settings and paste the CA certificate (PEM,
-----BEGIN CERTIFICATE-----) into CA Certificate. Agents pick it up within 5 minutes. - Skip TLS certificate verification: for labs only. The service account password would be sent without checking who receives it. Never enable it in production.
If the certificate cannot be verified, the agent shows LDAP unreachable and logs the TLS error (x509: certificate signed by unknown authority, certificate is valid for …, not …). Make sure the AD Server URL host name matches a name in the domain controller's certificate.
The connection between the agent and GAccess uses TLS 1.2 or later with the agent's client certificate.
Step 2 — Add an agent
- Open the identity source. In the AD Agents card, click Add New Agent.
- Download and install the package on the agent server:
# RHEL, Rocky, Alma, Amazon Linux
sudo rpm -Uvh gaccess-ad-agent-latest.x86_64.rpm
# Debian, Ubuntu
sudo dpkg -i gaccess-ad-agent-latest.amd64.debThe package installs the binary, creates the unprivileged gaccess-ad-agent system user and enables the gaccess-ad-agent service.
- Register it. Enter an Agent name (letters, numbers and hyphens, up to 63 characters, unique in your tenant — e.g.
dc-site1-agent01) and click Generate command. Copy the command and run it on the server:
sudo gaccess-ad-agent register \
--token <token> \
--server https://gateway.<your-gaccess-host> \
--name <agent-name>| Flag | Description |
|---|---|
--token |
The one-time token from GAccess (valid 60 minutes). |
--server |
Your GAccess gateway URL, always https://gateway.<your-gaccess-host> (e.g. https://gateway.acme.gaccess.cloud). The generated command already contains it. |
--name |
The name shown in GAccess. |
The agent enrolls, writes its certificate and configuration to /etc/gaccess-ad-agent/ and starts the service. If it could not start it, run sudo systemctl start gaccess-ad-agent.
- Wait for it to connect. The window shows connected when the agent is online; it then appears in the agents list as Online, and as Leader if it is the first one.
You can close the window at any time — for example to run the command later or have someone else run it. The agent stays in the list as Pending until it registers. If the token expires (60 minutes), click New Token on its row to get a new one; if it is no longer needed, click Delete.
Proxy configuration
If the agent server reaches the internet through an HTTPS proxy, the agent uses the standard HTTPS_PROXY and NO_PROXY variables for its connection to GAccess. The connection to the domain controller (LDAPS) never uses the proxy.
For registration, pass the proxy on the command line (sudo does not keep your environment):
sudo HTTPS_PROXY=http://proxy.corp.example.com:3128 \
gaccess-ad-agent register --token <token> --server https://gateway.<your-gaccess-host> --name <agent-name>For the service, add a systemd drop-in:
sudo systemctl edit gaccess-ad-agent[Service]
Environment=HTTPS_PROXY=http://proxy.corp.example.com:3128
Environment=NO_PROXY=localhost,127.0.0.1Then restart: sudo systemctl restart gaccess-ad-agent. The drop-in is kept across upgrades.
CONNECT). A proxy that inspects TLS (decrypts and re-signs traffic) breaks mutual TLS: exclude gateway.<your-gaccess-host> from inspection. Proxy authentication can be given in the URL (http://user:password@proxy:3128).Step 3 — First sync
The leader agent syncs as soon as it connects to AD, then on every sync interval. To sync immediately — for example after changing OU scopes or sync groups — click Sync Now in the AD Agents card. The leader picks it up on its next heartbeat (within about 30 seconds).
Synced users appear under Users and groups under Groups. They have no roles: assign roles to the synced groups (or to individual users) to grant access.
Health and monitoring
Agents list
The AD Agents card shows a summary (e.g. 2 of 2 agents online · Last sync 5 minutes ago) and one row per agent:
| Column / status | Meaning |
|---|---|
| Online | Heartbeat received in the last 2 minutes and AD reachable. |
| LDAP unreachable | The agent is running but has not been able to reach or bind to AD for more than 2 minutes. It does not handle logins or syncs until AD is reachable again. |
| Offline | No heartbeat for more than 2 minutes. |
| Pending | Added in GAccess but not registered yet. |
| Enrollment expired | The registration token expired before it was used. New Token issues a new one. |
| Revoked | Permanently disconnected. Can only be deleted. |
| Leader / Standby | Shown next to the name: the leader runs the sync; standbys only handle logins. |
| Last heartbeat | Date and time the agent last reported, in your local time (agents report every 30 seconds). |
| Version | The version the agent reports. |
| Certificate | Days until the agent certificate expires. Shown in red at 7 days or less, which means renewal is failing (or the agent is 0.1.0). |
Short interruptions (a single failed check) are ignored: both the list and the alerts wait 2 minutes before reporting a problem.
The Identity Sources list shows the same summary in its Provisioning column: agents online and the time of the last sync (or Last sync failed).
Alerts
Two alerting conditions cover AD (create rules for them under Alerts, with email or webhook channels):
| Alert | When it fires | When it resolves |
|---|---|---|
| AD agent offline | An agent is Offline or LDAP unreachable — one alert per agent, under its identity source. Checked every minute, with the same 2-minute rule as the agents list. | Automatically, when that agent is online again. |
| AD sync group not found | A group in the Sync Groups list is not found in AD — one alert per group. Default severity high. | Manually, once the DN is fixed or the group restored. |
On the agent server
sudo systemctl status gaccess-ad-agent # running? since when?
sudo journalctl -u gaccess-ad-agent -f # follow the log
sudo journalctl -u gaccess-ad-agent --since "1 hour ago"
sudo journalctl -u gaccess-ad-agent -n 200 --no-pagerThe agent logs to journald (identifier gaccess-ad-agent). Useful lines:
| Log line | Meaning |
|---|---|
GAccess AD Agent <version> started |
Service started; shows the version. |
[ldap] connected to Active Directory |
Bound to AD with the service account. |
[sync] starting (initial / scheduled / admin-requested) |
A sync began (leader only). |
[sync] pushed N users, N groups, N tombstoned users in N request(s) |
Changes sent to GAccess. |
[sync] no changes detected |
Nothing changed since the last sync. |
[sync] standby — leadership held by another agent, skipping |
This agent is a standby. |
[sync] sync group not found in AD: <dn> |
A listed group was not found. |
[sync] sync group <old dn> is now <new dn> |
A listed group was renamed or moved and is still followed. |
[config] configuration changed — reconnecting to AD with new settings |
A setting was changed in GAccess. |
[ldap] ... — reconnecting / connection lost — reconnecting in 10s |
AD connection lost; the agent reconnects by itself. |
[ldap] waiting for configuration update to resume |
The service account password or Bind DN is wrong. Fix it in GAccess. |
[cert] certificate renewed, valid until <date> |
Automatic renewal done. |
[cert] ERROR: the agent certificate expired on <date> |
The agent must be added again. |
[heartbeat] error: ... |
GAccess could not be reached (network, proxy, DNS). |
High availability
Add two or more agents to the same identity source, on separate servers (ideally near different domain controllers). They share the work as follows:
- Sync — one leader. Exactly one agent is the leader and runs the sync. Leadership is a lease renewed on every heartbeat (every 30 seconds, valid 60 seconds). If the leader stops, its lease expires and another healthy agent takes over on its next heartbeat — within about 60–90 seconds. An agent that cannot reach AD gives up leadership immediately.
- Logins — any healthy agent. Each login goes to the agent with the most recent heartbeat that is connected to AD, leader or not. Logins keep working while at least one agent is healthy, including during a leader change.
- Configuration is the same for all agents and comes from GAccess.
A single agent is a single point of failure for both sync and logins. If every agent is down, AD users cannot log in — use a break-glass or local account.
Upgrading
Download the new package from the Add New Agent window (or the same download links) and install it over the existing one:
sudo rpm -Uvh gaccess-ad-agent-latest.x86_64.rpm # RPM
sudo dpkg -i gaccess-ad-agent-latest.amd64.deb # DEBThe package restarts the service on the new version and keeps the registration, certificate and proxy settings — do not register again. Check the result:
systemctl is-enabled gaccess-ad-agent # enabled
systemctl is-active gaccess-ad-agent # active
sudo journalctl -u gaccess-ad-agent -n 20 # "GAccess AD Agent <new version> started"The agents list shows the new version within a minute.
Rolling upgrade in a high-availability pool
Upgrade one agent at a time so logins never stop:
- In the agents list, note which agent is the Leader.
- Upgrade each Standby first. Wait until it is back Online with the new version before moving to the next.
- Upgrade the Leader last. While it restarts, another agent takes over leadership within about 60–90 seconds; logins continue on the other agents, and the sync resumes on the new leader.
- Check that every agent shows the new version and one of them is Leader.
Keep all agents on the same version: the leader's version decides how the sync behaves (for example, sync groups are followed by GUID only from 0.2.0).
Upgrading from 0.1.0
- Upgrade before the agent certificate expires (45 days after registration) — 0.1.0 cannot renew it.
- Upgrade every agent before using Sync Groups.
Replacing an agent whose certificate expired
An agent with an expired certificate is refused by GAccess and cannot recover by itself:
- Revoke it in the agents list, then Delete it.
- On the server, uninstall it and remove
/etc/gaccess-ad-agent(see Uninstalling). - Install the latest package and add it again with Add New Agent.
Uninstalling an agent
- In the agents list, click Revoke on the agent and confirm. GAccess refuses its certificate from then on. This cannot be undone.
- On the server, remove the package. This stops and disables the service:
sudo rpm -e gaccess-ad-agent # RPM
sudo dpkg --purge gaccess-ad-agent # DEB- Remove its certificate, key and state, and optionally the system user:
sudo rm -rf /etc/gaccess-ad-agent
sudo rm -rf /etc/systemd/system/gaccess-ad-agent.service.d # proxy drop-in, if any
sudo userdel gaccess-ad-agent- Back in GAccess, click Delete on the revoked agent to remove it from the list.
Pending and expired agents (never registered) can be deleted directly.
Files on the agent server
| Path | Contents |
|---|---|
/usr/local/bin/gaccess-ad-agent |
Agent binary |
/etc/gaccess-ad-agent/config.yaml |
GAccess URL, agent ID and certificate paths. No AD settings or credentials. |
/etc/gaccess-ad-agent/agent.crt, agent.key |
The agent's client certificate and private key (readable only by the service user) |
/etc/gaccess-ad-agent/ca.crt |
The GAccess CA certificate |
/etc/gaccess-ad-agent/agent-state.json |
Fingerprints of the last synced objects, used to send only changes |
/etc/gaccess-ad-agent/*.new |
Present only for a moment during certificate renewal |
The service runs as the unprivileged gaccess-ad-agent user with systemd hardening (no new privileges, read-only system, write access to /etc/gaccess-ad-agent only), restarts automatically 10 seconds after a crash, and logs to journald.
When the agent stops working
| Situation | What happens | What to do |
|---|---|---|
| Domain controller unreachable or TLS error | LDAP unreachable after 2 minutes. The agent retries (5 s, 10 s, 20 s … up to every 60 s). No sync or logins through this agent. | Check network to port 636, the CA certificate and the AD Server URL host name. |
| Wrong service account password or Bind DN | LDAP unreachable. The agent stops retrying and logs waiting for configuration update. |
Fix it in GAccess; the agent retries within 5 minutes. |
| Service account locked or expired in AD | Same as a wrong password. | Unlock it in AD, then save the identity source again or wait for the next attempt. |
| GAccess unreachable (network, DNS, proxy) | Offline after 2 minutes. The agent keeps retrying; nothing is lost — changes are sent on the next successful sync. | Check access to gateway.<your-gaccess-host>:443 and the proxy settings. |
| TLS-inspecting proxy | Registration or every request fails with a TLS / 401 error. | Exclude the gateway host from TLS inspection. |
| Agent certificate expired | Offline; [cert] ERROR in the log. |
Replace the agent. |
| Agent revoked | Refused by GAccess. | Add a new agent. |
| Sync group not found (deleted, renamed with 0.1.0, unreadable) | Its members are disabled; alert raised. | Fix the DN or the service account's permissions. Users are re-enabled on the next sync. |
| Group too large (about 25,000 direct members) | The group is skipped on every sync; logged. | Split the group. |
| OU scope or Base DN does not exist | The sync is skipped and logged (search base not found); nothing is removed. |
Correct the DN. |
| Server clock wrong | TLS errors, early or late certificate renewal. | Enable NTP. |
| All agents down | AD users cannot log in (temporarily unavailable). | Restore an agent; use a break-glass account meanwhile. |
Sync conflicts
When an AD user matches an existing GAccess account from another source — same email, or same username — the sync cannot tell whether they are the same person, so the AD user is not synced. The identity source page shows a notice (N AD users aren't synced until you choose…); click Review to open the list.
For each conflict (or several at once, using the checkboxes):
| Action | Result |
|---|---|
| Use AD / Use AD and keep roles | The existing account is linked to the AD user: it logs in with its AD password and its username becomes the AD UPN. Its roles, groups and permissions are kept. You are asked to confirm first. Not available for break-glass accounts. |
| Keep existing / Keep existing accounts | The existing account stays as it is, and this AD user is skipped from now on. |
Usernames follow UPN changes in AD, so renaming a user does not create a conflict, and a new user given an old UPN is created as a new account.
Deleting the identity source
An identity source cannot be deleted while a sync is running, or while users or active groups synced from it still exist.
- Delete the synced users under Users (disabled users included).
- Delete the synced groups under Groups (archived groups do not block deletion).
- In Identity Sources, delete the identity source.
All its agents are revoked, and its configuration — including the encrypted bind password — is permanently deleted. Then uninstall the agents from their servers.
Troubleshooting
| Symptom | Likely cause | Action |
|---|---|---|
register fails with enrollment failed (HTTP 401) |
Token expired or already used | Click New Token on the pending agent and run the new command. |
register fails with another HTTP error |
Invalid or duplicate agent name | Use letters, numbers and hyphens, and a name not used by another agent. |
register cannot connect |
Wrong --server, firewall or proxy |
Use https://gateway.<your-gaccess-host>; for a proxy, see Proxy configuration. |
| Agent stays Pending | The command was not run, or failed | Run it again (or with a new token) and check its output. |
| Agent LDAP unreachable | AD not reachable, TLS or service account problem | sudo journalctl -u gaccess-ad-agent -n 100 shows the exact error. See When the agent stops working. |
| Agent Offline after an RPM upgrade | Service not running | sudo systemctl enable --now gaccess-ad-agent |
| Users created in AD do not appear | Interval not elapsed, user disabled, outside the OU scopes or not a direct member of a sync group | Click Sync Now; check the user's OU and group membership. |
| Users were disabled unexpectedly | Disabled in AD, moved out of scope, removed from a sync group, or a sync group not found | Check the alerts and the agent log (sync group not found). Users are re-enabled when they return to scope. |
| A group is missing in GAccess | Outside the scope, not in the Sync Groups list, or too large | See Group limits. |
| An AD user is not created and no error is shown | Sync conflict | Check the conflicts notice on the identity source. |
| Login: Authentication is temporarily unavailable | No healthy agent | Check the agents list; at least one agent must be Online. |
| Login: Invalid credentials with the right password | Not using the UPN, account locked/expired/disabled in AD, password expired, or GAccess lockout | Log in with the UPN; check the account in AD; unlock it in Users if GAccess locked it. |
| Certificate column red | Renewal failing, or agent 0.1.0 | Upgrade to the latest agent; check the log for [cert] lines. |