Skip to content

Active Directory in OTOBO via LDAP

Active Directory is the source of agents for most OTOBO installations. LDAP checks the password and copies name, email, and roles into OTOBO. That is not SSO yet.

PathWhat the agent doesWhen
LDAPTypes the AD password into OTOBOAlways the first step, so accounts and roles exist
Kerberos SSOOpens OTOBO on a domain-joined PC, without a passwordOffice network, SPNEGO on Nginx
OpenID ConnectSigns in at Microsoft Entra ID or KeycloakAlso from outside the domain, from OTOBO 11

Kerberos and OpenID Connect replace the LDAP sign-in. Synchronising the account data stays useful while Active Directory owns the roles. The Kerberos account HTTP/… is the wrong user for that job.

The keys below are the ones in Kernel/Config/Defaults.pm of OTOBO 11.1. Put them in Kernel/Config.pm, not in Defaults.

$Self->{AuthModule} = 'Kernel::System::Auth::LDAP';
$Self->{'AuthModule::LDAP::Host'} = 'ldaps://dc1.example.com';
$Self->{'AuthModule::LDAP::BaseDN'} = 'dc=example,dc=com';
$Self->{'AuthModule::LDAP::UID'} = 'sAMAccountName';
$Self->{'AuthModule::LDAP::SearchUserDN'} = 'CN=otobo-ldap,OU=Service,DC=example,DC=com';
$Self->{'AuthModule::LDAP::SearchUserPw'} = 'search-user-secret';
$Self->{'AuthModule::LDAP::AlwaysFilter'} = '(&(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))';
$Self->{'AuthModule::LDAP::Params'} = {
verify => 'require',
};
  • Host with ldaps:// uses port 636. Another port belongs in the URL, for example ldaps://dc1.example.com:737.
  • UID is sAMAccountName. The OTOBO login is then the short AD logon name.
  • The search user is read-only. Anonymous search is usually closed on Active Directory.
  • AlwaysFilter skips disabled accounts. The OID 1.2.840.113556.1.4.803 is the AD bitwise match; flag 2 is ACCOUNTDISABLE.
  • verify => 'require' checks the domain controller certificate. The host has to trust the issuer.

To require membership of an AD group, set UserAttr to DN and AccessAttr to member. AD groups store the member as a distinguished name, not as memberUid.

$Self->{'AuthModule::LDAP::GroupDN'} = 'CN=OTOBO-Agents,OU=Groups,DC=example,DC=com';
$Self->{'AuthModule::LDAP::AccessAttr'} = 'member';
$Self->{'AuthModule::LDAP::UserAttr'} = 'DN';

Keep one local administrator as a second source. If the domain controller is down, that account still works:

$Self->{AuthModule2} = 'Kernel::System::Auth::DB';

Synchronisation runs after a successful sign-in. It creates the agent and sets groups. It is not a nightly full sync.

$Self->{AuthSyncModule} = 'Kernel::System::Auth::Sync::LDAP';
$Self->{'AuthSyncModule::LDAP::Host'} = 'ldaps://dc1.example.com';
$Self->{'AuthSyncModule::LDAP::BaseDN'} = 'dc=example,dc=com';
$Self->{'AuthSyncModule::LDAP::UID'} = 'sAMAccountName';
$Self->{'AuthSyncModule::LDAP::SearchUserDN'} = 'CN=otobo-ldap,OU=Service,DC=example,DC=com';
$Self->{'AuthSyncModule::LDAP::SearchUserPw'} = 'search-user-secret';
$Self->{'AuthSyncModule::LDAP::AlwaysFilter'} = '(&(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))';
$Self->{'AuthSyncModule::LDAP::UserSyncMap'} = {
UserFirstname => 'givenName',
UserLastname => 'sn',
UserEmail => 'mail',
};
$Self->{'AuthSyncModule::LDAP::AccessAttr'} = 'member';
$Self->{'AuthSyncModule::LDAP::UserAttr'} = 'DN';
$Self->{'AuthSyncModule::LDAP::NestedGroupSearch'} = '1';
$Self->{'AuthSyncModule::LDAP::UserSyncRolesDefinition'} = {
'CN=OTOBO-Admins,OU=Groups,DC=example,DC=com' => {
'Service Desk Admin' => 1,
},
'CN=OTOBO-Agents,OU=Groups,DC=example,DC=com' => {
'Service Desk' => 1,
},
};

NestedGroupSearch follows nested directory groups. The names on the left are distinguished names from Active Directory. The names on the right are OTOBO roles, and 1 assigns that role. Create the role first, then attach rights under Role ↔ Group.

The Admin label Group is a bundle of rights (ro, rw, and the rest), not a team. UserSyncGroupsDefinition writes those rights directly and skips roles. Leave it unset. The same mapping, including why the label is misleading, is on OpenID Connect. Put the baseline users right on the role. UserSyncInitialGroups only adds that bundle on the first create.

When you later switch to Kerberos, keep this block. Only AuthModule = LDAP goes away, replaced by HTTPBasicAuth. The search user stays otobo-ldap, not HTTP/otobo.example.com.

The same shape exists for the customer portal under Customer::AuthModule with Kernel::System::CustomerAuth::LDAP. Internal agents and external customers belong in separate search bases. A customer company in Active Directory is not a reason to turn every employee into a customer user.

Frequently asked questions

Is LDAP against Active Directory the same as single sign-on?

No. LDAP checks the password the agent types into the OTOBO form, then creates the user in OTOBO. Single sign-on without that form is Kerberos on the office network, or OpenID Connect with Microsoft Entra ID.

Which attribute is the OTOBO login in Active Directory?

sAMAccountName. A normal Active Directory has no uid attribute. The OTOBO login has to match this value, including after you later switch sign-in to Kerberos or OpenID Connect.

When does OTOBO refresh roles from Active Directory?

On a successful login, not on a schedule. An agent who never signs in keeps the old roles. Nested directory groups need AuthSyncModule::LDAP::NestedGroupSearch. Map those directory groups onto OTOBO roles, not onto the rights bundles the Admin labels as groups.