Configure LDAP / Active Directory¶
Repod supports authenticating users against an LDAP directory or Microsoft Active Directory. Once configured, users can log in with their existing corporate credentials. Repod uses the ldap3 Python library for all LDAP communication.
1. Prerequisites¶
Before you open the Repod settings screen, gather the following information from your directory administrator:
| Information needed | Example |
|---|---|
| LDAP server hostname or IP | ldap.example.com |
| Port | 389 (LDAP), 636 (LDAPS), 3268 (AD Global Catalog) |
| Transport security | Plain, STARTTLS, or SSL/TLS |
| Bind DN | cn=repod-svc,ou=service-accounts,dc=example,dc=com |
| Bind password | The password for the bind account |
| Base DN | ou=users,dc=example,dc=com |
| User search filter | (objectClass=person) or (objectClass=user) |
| Username attribute | uid (OpenLDAP) or sAMAccountName (AD) |
| Email attribute | mail |
| Group base DN (if using group-role mapping) | ou=groups,dc=example,dc=com |
Tip
Use a dedicated read-only service account as the bind DN. This account only needs read permission on the user and group subtrees. Never use a domain administrator account as the bind account.
2. Step 1 — Open LDAP settings¶
- Log in to the Repod web interface at
http://repod.example.com:3003as an administrator. - Navigate to Settings → LDAP.
- The LDAP configuration panel appears. LDAP is disabled by default until you save a valid configuration and toggle it on.
3. Step 2 — Configure the connection¶
Fill in the connection fields using the information you gathered in the prerequisites section.
| Field | Description |
|---|---|
| Host | Hostname or IP address of your LDAP server. Do not include a scheme (ldap://) — that is controlled by the SSL/STARTTLS toggles below. |
| Port | TCP port. Defaults to 389 for unencrypted/STARTTLS and 636 for LDAPS. |
| SSL / LDAPS | Enable to wrap the entire connection in TLS (connect on port 636). Mutually exclusive with STARTTLS. |
| STARTTLS | Enable to upgrade a plain connection to TLS after the initial handshake (port 389). Preferred over unencrypted when LDAPS is not available. |
| Verify TLS certificate | Enabled by default (verify_cert=true). Repod validates the server certificate against the system CA bundle. Disable only in test environments — never in production. |
| CA bundle path | Optional. Path to a custom CA certificate file (PEM format) inside the backend container, for internal CAs not in the system bundle. |
| Bind DN | The full distinguished name of the service account used to search the directory. |
| Bind password | Password for the bind account. Stored encrypted at rest. |
| Base DN | The root of the directory subtree to search for users. |
| User filter | LDAP search filter applied when looking up a user. Combined with the username attribute at login time. Example: (objectClass=person) |
| Username attribute | The LDAP attribute that holds the login name. uid for OpenLDAP, sAMAccountName for Active Directory. |
| Email attribute | The LDAP attribute that holds the user's email address. Usually mail. |
Never disable certificate verification in production
Setting Verify TLS certificate to off disables all certificate validation. A man-in-the-middle attacker on your network could intercept credentials. This setting exists only for isolated test environments with self-signed certificates. In production, install your CA certificate in the CA bundle path instead.
4. Step 3 — Map groups to roles¶
Repod can assign roles to users automatically based on their LDAP group membership. Configure the mapping in the Group → Role mapping table.
| LDAP group DN | Repod role |
|---|---|
cn=repod-admins,ou=groups,dc=example,dc=com |
admin |
cn=repod-publishers,ou=groups,dc=example,dc=com |
uploader |
cn=repod-viewers,ou=groups,dc=example,dc=com |
viewer |
Repod roles:
| Role | Permissions |
|---|---|
admin |
Full access including settings, user management, GPG, LDAP configuration. |
uploader |
Can upload and import packages. Cannot modify settings or manage users. |
viewer |
Read-only access to package listings and dashboard. Cannot upload. |
If a user belongs to multiple mapped groups, the highest-privilege role is applied. If a user belongs to no mapped group, they are assigned the viewer role by default (configurable).
Note
Group membership is evaluated at login time. If you add a user to a group in LDAP, they receive the corresponding Repod role on their next login — no manual role assignment is needed.
5. Step 4 — Enable auto-provisioning¶
When Auto-provision accounts is toggled on, Repod creates a local user record the first time a person successfully authenticates via LDAP. The local record stores:
- Username (from the username attribute)
- Email (from the email attribute)
- Role (from group mapping, or the default role if no mapping matches)
- A flag marking the account as LDAP-managed
LDAP-managed accounts cannot have their password changed in Repod — authentication always defers to the LDAP directory.
If auto-provisioning is off, a Repod administrator must create the user account manually before the person can log in via LDAP.
6. Step 5 — Test the connection¶
Before saving and enabling LDAP, use the Test connection button at the bottom of the settings panel.
What the test does:
- Opens a TCP connection to the LDAP server on the configured host and port.
- Negotiates TLS if SSL or STARTTLS is enabled.
- Binds as the service account using the bind DN and password.
- Performs a search for one user matching the configured base DN and user filter.
- Returns success or a structured error.
Interpreting the result:
| Result | Meaning |
|---|---|
| "Connection successful" | All fields are correct. Click Save and enable LDAP. |
CERTIFICATE_VERIFY_FAILED |
The server's TLS certificate is not trusted. See troubleshooting below. |
INVALID_CREDENTIALS |
The bind DN or bind password is wrong. |
NO_SUCH_OBJECT |
The base DN does not exist in the directory. |
CONNECTION_REFUSED |
Wrong host or port, or a firewall is blocking the connection. |
SERVER_DOWN |
The LDAP server is unreachable from the Repod backend container. |
Tip
If the test fails with a network error, verify connectivity from inside the backend container: docker compose exec backend nc -zv ldap.example.com 389
7. Step 6 — First LDAP login¶
Once LDAP is enabled and the configuration is saved:
- Open the Repod login page.
- Enter your LDAP username (the value of
sAMAccountNameoruid, not the full DN). - Enter your LDAP password.
- Click Sign in.
Repod binds to the directory as the service account, searches for the user, verifies the credentials, evaluates group membership, and creates or updates the local user record.
The JWT issued after a successful LDAP login is identical to one issued after a local login — all API calls use the same Authorization: Bearer <token> header regardless of authentication method.
8. OpenLDAP example configuration¶
A typical OpenLDAP deployment using uid as the username attribute:
| Field | Value |
|---|---|
| Host | openldap.example.com |
| Port | 636 |
| SSL | Enabled |
| STARTTLS | Disabled |
| Verify TLS certificate | Enabled |
| Bind DN | cn=repod-svc,ou=service-accounts,dc=example,dc=com |
| Bind password | s3cr3tpassword |
| Base DN | ou=users,dc=example,dc=com |
| User filter | (objectClass=inetOrgPerson) |
| Username attribute | uid |
| Email attribute | mail |
Group mapping:
| LDAP group DN | Repod role |
|---|---|
cn=repod-admins,ou=groups,dc=example,dc=com |
admin |
cn=developers,ou=groups,dc=example,dc=com |
uploader |
9. Active Directory example configuration¶
Active Directory uses sAMAccountName for short-form usernames or userPrincipalName for UPN-style (user@domain) logins.
| Field | Value |
|---|---|
| Host | dc01.corp.example.com |
| Port | 636 |
| SSL | Enabled |
| STARTTLS | Disabled |
| Verify TLS certificate | Enabled |
| Bind DN | CN=repod-svc,OU=Service Accounts,DC=corp,DC=example,DC=com |
| Bind password | s3cr3tpassword |
| Base DN | OU=Employees,DC=corp,DC=example,DC=com |
| User filter | (objectClass=user) |
| Username attribute | sAMAccountName |
| Email attribute | mail |
sAMAccountName vs userPrincipalName
Use sAMAccountName if your users log in with their short username (jsmith). Use userPrincipalName if they log in with their UPN (jsmith@corp.example.com). The attribute name must match exactly what your users type into the Repod login field — there is no automatic normalisation.
Group mapping for AD security groups:
| LDAP group DN | Repod role |
|---|---|
CN=Repod-Admins,OU=Groups,DC=corp,DC=example,DC=com |
admin |
CN=Repod-Publishers,OU=Groups,DC=corp,DC=example,DC=com |
uploader |
CN=All-Staff,OU=Groups,DC=corp,DC=example,DC=com |
viewer |
For Active Directory Global Catalog queries (searching across multiple domains), use port 3268 (plain) or 3269 (SSL) instead of the standard LDAP ports.
10. Troubleshooting¶
CERTIFICATE_VERIFY_FAILED
The LDAP server's TLS certificate is not signed by a CA in the backend container's system bundle.
Options: 1. Recommended: Mount your internal CA certificate into the backend container and set the CA bundle path field to its location.
# In docker-compose.yaml, under the backend service:
volumes:
- /etc/ssl/certs/internal-ca.pem:/etc/ssl/certs/internal-ca.pem:ro
/etc/ssl/certs/internal-ca.pem.
- Test environments only: Disable Verify TLS certificate in the LDAP settings. Never do this in production.
INVALID_CREDENTIALS
The bind DN or bind password is incorrect.
- Double-check the bind DN format. Active Directory requires the full
CN=...,DC=...form, not just the username. - Verify the service account password has not expired. AD service accounts should have password expiry disabled.
- Confirm the service account has not been locked out due to failed login attempts from a previous misconfigured connection test.
NO_SUCH_OBJECT
The base DN does not exist in the directory, or the bind account does not have permission to read it.
- Verify the base DN by connecting with
ldapsearchfrom the Repod backend container: - If the command returns results, the base DN is correct and the issue is in Repod's configuration. If it returns
No such object, the base DN itself is wrong.
Group mapping not applied
Users log in successfully but receive the wrong role.
- Verify the group DN in the mapping table is exactly correct, including the case of each component.
- Check that the user is actually a member of the group in LDAP:
- In Active Directory,
memberOfis on the user object; in OpenLDAP,memberis on the group object. Repod queries the group object — ensure the group'smemberattribute contains the user's full DN.