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.
Warning: Agent version 0.1.0 cannot renew its certificate. Upgrade it to 0.2.0 or later before the certificate expires (see the Certificate column of the agents list). An agent whose certificate has already expired cannot reconnect and must be added again — see Replacing an agent whose certificate expired.

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)

  1. 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).
  2. The agent, which keeps a long-poll open to GAccess, receives the request and decrypts the password in memory.
  3. It looks up the user by UPN and binds to the domain controller as that user, on a dedicated connection.
  4. 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.

Note: AD users log in with their User Principal Name (e.g. 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

  1. In the sidebar, open Identity Sources and click Add Identity Source.
  2. Enter a Name and select Active Directory.
  3. 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.
  1. 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.

Warning: With agent 0.1.0, groups are matched by DN only. Renaming or moving a listed group in AD makes it "not found" and disables its members until you update the DN. 0.1.0 also does not report group status. Use sync groups with agent 0.2.0 or later.

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 Email 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

  1. Open the identity source. In the AD Agents card, click Add New Agent.
  2. 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.deb

The package installs the binary, creates the unprivileged gaccess-ad-agent system user and enables the gaccess-ad-agent service.

  1. 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.

  1. 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.1

Then restart: sudo systemctl restart gaccess-ad-agent. The drop-in is kept across upgrades.

Warning: The proxy must tunnel the connection (HTTP 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-pager

The 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       # DEB

The 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:

  1. In the agents list, note which agent is the Leader.
  2. Upgrade each Standby first. Wait until it is back Online with the new version before moving to the next.
  3. 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.
  4. 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:

  1. Revoke it in the agents list, then Delete it.
  2. On the server, uninstall it and remove /etc/gaccess-ad-agent (see Uninstalling).
  3. Install the latest package and add it again with Add New Agent.

Uninstalling an agent

  1. In the agents list, click Revoke on the agent and confirm. GAccess refuses its certificate from then on. This cannot be undone.
  2. 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
  1. 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
  1. 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.
Warning: A conflict marked Existing AD account means the existing account was synced from this same directory for a different AD user — typically a user who was deleted and recreated in AD. Choose Use AD only if it is the same person: the incoming AD user gets that account's roles and access.

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.

  1. Delete the synced users under Users (disabled users included).
  2. Delete the synced groups under Groups (archived groups do not block deletion).
  3. 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.