LDAP Multi-Domain Controller Authentication (Deployment Plan)¶
Deployment Plan supports configuring multiple domain controller addresses for the same LDAP identity directory. At sign-in, addresses are connected in the configured order; when a service failure that permits failover occurs before the user password is submitted, the next address is tried.
In this document, "multi-domain controller" refers to multiple controllers that share accounts, directory structure, and authentication rules, such as replicas of the same AD domain. It does not provide account routing between multiple independent AD domains, nor does it look up users by trying passwords against each domain. When an independent identity source requires custom authentication, see LDAP Custom Authentication and Func Attribute Processing.
Upgrade and Compatibility¶
Before use, confirm that the deployed Studio backend version includes the LDAPClientSet.authMode and LDAPClientSet.server.hosts configuration capabilities. Updating only the documentation or Func scripts does not add functionality to an older backend.
Existing single-address deployments do not require configuration changes: when authMode is unset or set to builtin, and server.hosts is not configured, is null, or is [], the original single-address authentication path remains in use. The new overall authentication timeout and external function configuration do not change that path. Do not add a hosts list containing only the original address just for an upgrade; a non-empty list explicitly enables the new path.
Before enabling, confirm the following:
- All candidate domain controllers use the same
baseDN, service account, user search criteria, TLS configuration, andmapping; theexterIdof the same user is identical across replicas. - All candidate domain controllers are reachable from the Studio backend container, the CA file is mounted into the container, and the certificate includes the connected domain name.
- The directory allows SIMPLE password authentication using the user DN from search results and protects password transmission through LDAPS or StartTLS. The bind method of the service account and the end-user password verification are two separate steps.
- Use an official service startup method that supports this capability; the new path requires a runtime environment in which network and DNS operations can be interrupted. If a custom startup method results in
gevent_runtimeorgevent_dnsconfiguration errors, fix the startup environment.
Configuring Multiple Domain Controllers¶
Following the Application Configuration Guide, modify the Core configuration in the forethought-core namespace in Launcher. The following is an LDAPS example; replace the domain names, DNs, certificate paths, and placeholder passwords with actual configuration values, and preserve the identity mapping for existing users.
LDAPClientSet:
enable: true
authMode: builtin
authTimeoutSeconds: 20
server:
# A non-empty hosts list completely replaces host; there is no fallback to host after failure.
hosts:
- "ldaps://ldap-a.example.com:636"
- "ldaps://ldap-b.example.com:636"
connect_timeout: 6
use_ssl: true
get_info: SCHEMA
tls:
validate: CERT_REQUIRED
ca_certs_file: "/config/ldap/ca.pem"
connection:
authentication: SIMPLE
client_strategy: SAFE_SYNC
receive_timeout: 5
startTls: false
baseDN: "dc=example,dc=com"
bindDN: "cn=studio-reader,ou=service,dc=example,dc=com"
bindPassword: "<service-account-password>"
searchAttribute: "uid"
personObjectClass: "inetOrgPerson"
mapping:
exterId: uid
username: uid
email: mail
mobile: mobile
AD environments usually require adjusting searchAttribute (for example, sAMAccountName) and personObjectClass (for example, person) according to the actual directory. Do not apply the example directly to overwrite the existing mapping.exterId.
If you use StartTLS, change the candidate addresses to ldap://domain:389, set server.use_ssl: false and startTls: true, and keep certificate validation. The new path completes the TLS handshake before binding the service account; do not enable LDAPS and StartTLS at the same time.
| Configuration Item | Description |
|---|---|
server.hosts |
Up to 8 addresses, tried in the order entered, with identical strings deduplicated. Supports domain names, ldap://domain:port, and ldaps://domain:port, without account passwords, paths, query parameters, or fragments. When a port needs to be specified, write it directly in the address. |
server.host |
Used as a single address only when hosts is empty. A non-empty hosts list is not combined with it. |
authTimeoutSeconds |
Overall time limit for authentication and attribute preparation in the new path, an integer from 1 to 60 seconds, defaulting to 20 seconds; shared by all candidate addresses, not 20 seconds per address. It does not include subsequent account transactions or sign-in authorization code processing. |
server.connect_timeout |
Timeout for a single connection, defaulting to 6 seconds, bounded by the remaining overall time limit. |
connection.receive_timeout |
Receive timeout, defaulting to 5 seconds, bounded by the remaining overall time limit. |
connection.client_strategy |
The new path supports only SAFE_SYNC; this value is used when it is not configured. Do not configure lazy: true; it is recommended not to set auto_bind, so that the authentication flow controls the connection, TLS, and bind order. |
| Other LDAP configuration | Continues to share the existing server.tls, connection, startTls, baseDN, bindDN, bindPassword, search criteria, and mapping; there is no need to duplicate configuration for each controller. |
When configuring the list through environment variables, use a JSON array string, for example:
STUDIO__LDAPClientSet__server__hosts='["ldaps://ldap-a.example.com:636","ldaps://ldap-b.example.com:636"]'
After modifying the configuration, check Restart related services automatically after configuration changes in Launcher and confirm, to ensure that all replicas handling sign-in requests use the same configuration.
Which Failures Trigger Domain Controller Failover¶
Each authentication starts from the first address in the list. Failover is used to handle service unavailability, not to bypass authentication rejections.
| Situation | Try the Next Address? |
|---|---|
| DNS, connection, or network communication failure occurs before the user password is submitted | Yes, except for certificate validation failures, and only while the overall time limit remains |
| LDAP busy/unavailable (51/52) returned during the service account bind or search phase | Yes, and only while the overall time limit remains |
| Incorrect service account password, insufficient permissions, search configuration, or schema error | No, fix the configuration first |
| Untrusted CA, or certificate does not match the domain name | No, fix the certificate or address first |
| User not found, or multiple users found | No, check account synchronization and unique search criteria |
| Incorrect user password | No, the password is not resubmitted to other controllers |
| Password already submitted, then a timeout, disconnection, or service unavailability occurs | No, the result may be uncertain, and the password is not automatically replayed |
| Overall time limit exhausted | No, this authentication attempt fails |
Therefore, when a user is missing from one domain controller, authentication does not continue to other independent directories to "find an account with the same name." First ensure replica synchronization and identity consistency.
Sign-In and Acceptance¶
Users still select LDAP Sign-In on the Deployment Plan sign-in page and enter their existing username and password; there is no need to select a domain controller. Workspace permissions continue to use the existing SSO mapping rules.
It is recommended to validate with a dedicated test account before rolling out to existing users:
- Sign-in succeeds when all addresses are healthy, existing users still enter their original accounts, and workspaces and roles match expectations.
- In a controlled test, simulate the first address being unreachable, confirm that sign-in succeeds through the second address, and verify that the overall elapsed time is bounded by the overall time limit.
- Enter an incorrect password and confirm that password retry counts do not increase due to trying multiple controllers; check the directory-side account lockout policy.
- Verify that certificate errors, service account errors, and user-not-found all fail and are not bypassed through failover.
- Use two controllers to separately check the identity fields and the group attributes required for authorization for the same user, and confirm consistency.
mapping.exterId corresponds to the stable identity of the LDAP user. Changing the mapping field or field value may create a new account; do not rely on the same email address or username to automatically merge identities.
Rollback¶
Keep the pre-upgrade configuration. To restore the old single-address authentication, set authMode to builtin, clear or delete server.hosts, restore the original server.host along with the original connection, TLS, and mapping configuration, and then restart the related services. Modifying only host while keeping a non-empty hosts list will not take effect.
Rolling back the configuration does not automatically merge accounts that have already been created, nor does it restore changed role mappings. If attribute processing or identity mapping was also changed, first review the impact on accounts and authorization.