diff --git a/.vale/styles/config/vocabularies/DependencyTrack/accept.txt b/.vale/styles/config/vocabularies/DependencyTrack/accept.txt index 6702e99..c85471e 100644 --- a/.vale/styles/config/vocabularies/DependencyTrack/accept.txt +++ b/.vale/styles/config/vocabularies/DependencyTrack/accept.txt @@ -2,7 +2,9 @@ (?i)triag(e|ing) ACLs APIs +Active Directory Aiven +ApacheDS Artifactory Atlassian BOM @@ -18,6 +20,7 @@ Dependency-Track Diataxis Entra Exploitability +Fedora 389 Directory Server Flashpoint GUIDs HDDs @@ -30,6 +33,7 @@ JWTs Jira KEKs Keycloak +LDAP LDAPS Liquibase Lucene diff --git a/docs/guides/administration/configuring-ldap.md b/docs/guides/administration/configuring-ldap.md index 5fd9aac..0082ec2 100644 --- a/docs/guides/administration/configuring-ldap.md +++ b/docs/guides/administration/configuring-ldap.md @@ -8,152 +8,155 @@ log in with their directory credentials rather than a locally managed password. - A service account in the LDAP directory with read access to users and groups. - Network connectivity from the Dependency-Track API server to the LDAP server. -- If using LDAPS (recommended for production), a valid TLS certificate on the LDAP server. - If the certificate is signed by an internal CA, see [Configuring Internal CA](configuring-internal-ca.md). +- For LDAPS (recommended in production), a valid TLS certificate on the LDAP server. + If an internal CA issued the certificate, see [Configuring internal CA trust](configuring-internal-ca.md). ## Configuration -All LDAP settings are configured via [app properties](../../reference/configuration/properties.md). -The most practical way to supply them in a container deployment is via environment variables. +Configure all LDAP settings via [app properties](../../reference/configuration/properties.md). +The examples below use property names; see [Application configuration](../../reference/configuration/application.md#environment-variable-mapping) +for how property names map to environment variables. ### Minimal configuration -At least, enable LDAP and configure the server connection: - -```ini linenums="1" -DT_LDAP_ENABLED=true -DT_LDAP_SERVER_URL=ldap://ldap.example.com:389 -DT_LDAP_BASEDN=dc=example,dc=com -DT_LDAP_SECURITY_AUTH=simple -DT_LDAP_BIND_USERNAME=cn=dt-service,dc=example,dc=com -DT_LDAP_BIND_PASSWORD=changeme -DT_LDAP_AUTH_USERNAME_FORMAT=uid={0},ou=users,dc=example,dc=com -DT_LDAP_ATTRIBUTE_NAME=cn -DT_LDAP_ATTRIBUTE_MAIL=mail +Enable LDAP and configure the server connection: + +```properties linenums="1" +dt.ldap.enabled=true +dt.ldap.server.url=ldap://ldap.example.com:389 +dt.ldap.basedn=dc=example,dc=com +dt.ldap.security.auth=simple +dt.ldap.bind.username=cn=dt-service,dc=example,dc=com +dt.ldap.bind.password=changeme +dt.ldap.auth.username.format=uid={0},ou=users,dc=example,dc=com +dt.ldap.attribute.name=cn +dt.ldap.attribute.mail=mail ``` -The `{0}` placeholder in `DT_LDAP_AUTH_USERNAME_FORMAT` is substituted with the -username entered at login. +!!! tip + Dependency-Track substitutes the `{0}` placeholder in `dt.ldap.auth.username.format` + with the username entered at login. ### User provisioning -When enabled, accounts are created automatically the first time an LDAP user logs in. -Without provisioning, accounts must be created manually before users can log in. +When enabled, Dependency-Track creates accounts automatically the first time an LDAP +user logs in. Otherwise, an administrator must create each account before its user can +log in. -```ini -DT_LDAP_USER_PROVISIONING=true +```properties +dt.ldap.user.provisioning=true ``` ### Team synchronisation -When enabled, team membership in Dependency-Track is kept in sync with LDAP group -membership. Teams must be mapped to LDAP groups in **Administration → Access Management → Teams**. +When enabled, Dependency-Track keeps team membership in sync with LDAP group membership. +Map teams to LDAP groups under **Administration > Access Management > Teams**. -```ini -DT_LDAP_TEAM_SYNCHRONIZATION=true -DT_LDAP_GROUPS_FILTER=(&(objectClass=groupOfUniqueNames)) -DT_LDAP_USER_GROUPS_FILTER=(&(objectClass=groupOfUniqueNames)(uniqueMember={USER_DN})) -DT_LDAP_GROUPS_SEARCH_FILTER=(&(objectClass=groupOfUniqueNames)(cn=*{SEARCH_TERM}*)) -DT_LDAP_USERS_SEARCH_FILTER=(&(objectClass=inetOrgPerson)(cn=*{SEARCH_TERM}*)) +```properties +dt.ldap.team.synchronization=true +dt.ldap.groups.filter=(&(objectClass=groupOfUniqueNames)) +dt.ldap.user.groups.filter=(&(objectClass=groupOfUniqueNames)(uniqueMember={USER_DN})) +dt.ldap.groups.search.filter=(&(objectClass=groupOfUniqueNames)(cn=*{SEARCH_TERM}*)) +dt.ldap.users.search.filter=(&(objectClass=inetOrgPerson)(cn=*{SEARCH_TERM}*)) ``` -The `{USER_DN}` placeholder is substituted with the authenticated user's distinguished -name. The `{SEARCH_TERM}` placeholder is substituted with search input from the UI. +!!! tip + Dependency-Track substitutes `{USER_DN}` with the authenticated user's distinguished + name, and `{SEARCH_TERM}` with search input from the UI. --- -## Tested Configurations +## Tested configurations -The following configurations have been tested with specific directory implementations. -Adapt values such as base DNs, bind credentials, and attribute names to match your -environment. +The configurations below work with specific directory implementations. Adapt values +such as base DNs, bind credentials, and attribute names to match your environment. ### Microsoft Active Directory Active Directory uses a global catalog port (3268/3269) for forest-wide searches. Users typically authenticate with their User Principal Name (`user@domain.com`). -```ini linenums="1" -DT_LDAP_ENABLED=true -DT_LDAP_SERVER_URL=ldap://ldap.example.com:3268 -DT_LDAP_BASEDN=dc=example,dc=com -DT_LDAP_SECURITY_AUTH=simple -DT_LDAP_BIND_USERNAME=CN=DT Service Account,DC=example,DC=com -DT_LDAP_BIND_PASSWORD=changeme -DT_LDAP_AUTH_USERNAME_FORMAT={0}@example.com -DT_LDAP_ATTRIBUTE_NAME=userPrincipalName -DT_LDAP_ATTRIBUTE_MAIL=mail -DT_LDAP_GROUPS_FILTER=(&(objectClass=group)(objectCategory=Group)) -DT_LDAP_USER_GROUPS_FILTER=(&(objectClass=group)(objectCategory=Group)(member:1.2.840.113556.1.4.1941:={USER_DN})) -DT_LDAP_GROUPS_SEARCH_FILTER=(&(objectClass=group)(objectCategory=Group)(cn=*{SEARCH_TERM}*)) -DT_LDAP_USERS_SEARCH_FILTER=(&(objectClass=user)(objectCategory=Person)(cn=*{SEARCH_TERM}*)) +```properties linenums="1" +dt.ldap.enabled=true +dt.ldap.server.url=ldap://ldap.example.com:3268 +dt.ldap.basedn=dc=example,dc=com +dt.ldap.security.auth=simple +dt.ldap.bind.username=CN=DT Service Account,DC=example,DC=com +dt.ldap.bind.password=changeme +dt.ldap.auth.username.format={0}@example.com +dt.ldap.attribute.name=userPrincipalName +dt.ldap.attribute.mail=mail +dt.ldap.groups.filter=(&(objectClass=group)(objectCategory=Group)) +dt.ldap.user.groups.filter=(&(objectClass=group)(objectCategory=Group)(member:1.2.840.113556.1.4.1941:={USER_DN})) +dt.ldap.groups.search.filter=(&(objectClass=group)(objectCategory=Group)(cn=*{SEARCH_TERM}*)) +dt.ldap.users.search.filter=(&(objectClass=user)(objectCategory=Person)(cn=*{SEARCH_TERM}*)) ``` !!! tip The `member:1.2.840.113556.1.4.1941:=` OID in the user groups filter enables - recursive group membership lookup (LDAP_MATCHING_RULE_IN_CHAIN). This ensures - nested group memberships are resolved correctly. + recursive group membership lookup (LDAP_MATCHING_RULE_IN_CHAIN), so + Dependency-Track resolves nested group memberships correctly. For LDAPS (recommended in production), change the port to `3269` and update the URL: -```ini -DT_LDAP_SERVER_URL=ldaps://ldap.example.com:3269 +```properties +dt.ldap.server.url=ldaps://ldap.example.com:3269 ``` ### ApacheDS -```ini linenums="1" -DT_LDAP_ENABLED=true -DT_LDAP_SERVER_URL=ldap://ldap.example.com:389 -DT_LDAP_BASEDN=dc=example,dc=com -DT_LDAP_SECURITY_AUTH=simple -DT_LDAP_BIND_USERNAME=uid=admin,ou=system -DT_LDAP_BIND_PASSWORD=changeme -DT_LDAP_AUTH_USERNAME_FORMAT=uid={0},ou=users,dc=example,dc=com -DT_LDAP_ATTRIBUTE_NAME=cn -DT_LDAP_ATTRIBUTE_MAIL=mail -DT_LDAP_GROUPS_FILTER=(&(objectClass=groupOfUniqueNames)) -DT_LDAP_USER_GROUPS_FILTER=(&(objectClass=groupOfUniqueNames)(uniqueMember={USER_DN})) -DT_LDAP_GROUPS_SEARCH_FILTER=(&(objectClass=groupOfUniqueNames)(cn=*{SEARCH_TERM}*)) -DT_LDAP_USERS_SEARCH_FILTER=(&(objectClass=inetOrgPerson)(cn=*{SEARCH_TERM}*)) +```properties linenums="1" +dt.ldap.enabled=true +dt.ldap.server.url=ldap://ldap.example.com:389 +dt.ldap.basedn=dc=example,dc=com +dt.ldap.security.auth=simple +dt.ldap.bind.username=uid=admin,ou=system +dt.ldap.bind.password=changeme +dt.ldap.auth.username.format=uid={0},ou=users,dc=example,dc=com +dt.ldap.attribute.name=cn +dt.ldap.attribute.mail=mail +dt.ldap.groups.filter=(&(objectClass=groupOfUniqueNames)) +dt.ldap.user.groups.filter=(&(objectClass=groupOfUniqueNames)(uniqueMember={USER_DN})) +dt.ldap.groups.search.filter=(&(objectClass=groupOfUniqueNames)(cn=*{SEARCH_TERM}*)) +dt.ldap.users.search.filter=(&(objectClass=inetOrgPerson)(cn=*{SEARCH_TERM}*)) ``` ### Fedora 389 Directory Server -```ini linenums="1" -DT_LDAP_ENABLED=true -DT_LDAP_SERVER_URL=ldap://ldap.example.com:389 -DT_LDAP_BASEDN=dc=example,dc=com -DT_LDAP_SECURITY_AUTH=simple -DT_LDAP_BIND_USERNAME=cn=Directory Manager -DT_LDAP_BIND_PASSWORD=changeme -DT_LDAP_AUTH_USERNAME_FORMAT=uid={0},ou=people,dc=example,dc=com -DT_LDAP_ATTRIBUTE_NAME=uid -DT_LDAP_ATTRIBUTE_MAIL=mail -DT_LDAP_GROUPS_FILTER=(&(objectClass=groupOfUniqueNames)) -DT_LDAP_USER_GROUPS_FILTER=(&(objectClass=groupOfUniqueNames)(uniqueMember={USER_DN})) -DT_LDAP_GROUPS_SEARCH_FILTER=(&(objectClass=groupOfUniqueNames)(cn=*{SEARCH_TERM}*)) -DT_LDAP_USERS_SEARCH_FILTER=(&(objectClass=inetOrgPerson)(uid=*{SEARCH_TERM}*)) +```properties linenums="1" +dt.ldap.enabled=true +dt.ldap.server.url=ldap://ldap.example.com:389 +dt.ldap.basedn=dc=example,dc=com +dt.ldap.security.auth=simple +dt.ldap.bind.username=cn=Directory Manager +dt.ldap.bind.password=changeme +dt.ldap.auth.username.format=uid={0},ou=people,dc=example,dc=com +dt.ldap.attribute.name=uid +dt.ldap.attribute.mail=mail +dt.ldap.groups.filter=(&(objectClass=groupOfUniqueNames)) +dt.ldap.user.groups.filter=(&(objectClass=groupOfUniqueNames)(uniqueMember={USER_DN})) +dt.ldap.groups.search.filter=(&(objectClass=groupOfUniqueNames)(cn=*{SEARCH_TERM}*)) +dt.ldap.users.search.filter=(&(objectClass=inetOrgPerson)(uid=*{SEARCH_TERM}*)) ``` ### NetIQ / Novell eDirectory eDirectory typically uses LDAPS on port 636 and an organisation-based DN structure. -```ini linenums="1" -DT_LDAP_ENABLED=true -DT_LDAP_SERVER_URL=ldaps://ldap.example.com:636 -DT_LDAP_BASEDN=o=example -DT_LDAP_SECURITY_AUTH=simple -DT_LDAP_BIND_USERNAME=cn=admin,o=example -DT_LDAP_BIND_PASSWORD=changeme -DT_LDAP_AUTH_USERNAME_FORMAT=uid={0},ou=users,o=example -DT_LDAP_ATTRIBUTE_NAME=uid -DT_LDAP_ATTRIBUTE_MAIL=mail -DT_LDAP_GROUPS_FILTER=(&(objectClass=groupOfUniqueNames)) -DT_LDAP_USER_GROUPS_FILTER=(&(objectClass=groupOfUniqueNames)(uniqueMember={USER_DN})) -DT_LDAP_GROUPS_SEARCH_FILTER=(&(objectClass=groupOfUniqueNames)(cn=*{SEARCH_TERM}*)) -DT_LDAP_USERS_SEARCH_FILTER=(&(objectClass=inetOrgPerson)(uid=*{SEARCH_TERM}*)) +```properties linenums="1" +dt.ldap.enabled=true +dt.ldap.server.url=ldaps://ldap.example.com:636 +dt.ldap.basedn=o=example +dt.ldap.security.auth=simple +dt.ldap.bind.username=cn=admin,o=example +dt.ldap.bind.password=changeme +dt.ldap.auth.username.format=uid={0},ou=users,o=example +dt.ldap.attribute.name=uid +dt.ldap.attribute.mail=mail +dt.ldap.groups.filter=(&(objectClass=groupOfUniqueNames)) +dt.ldap.user.groups.filter=(&(objectClass=groupOfUniqueNames)(uniqueMember={USER_DN})) +dt.ldap.groups.search.filter=(&(objectClass=groupOfUniqueNames)(cn=*{SEARCH_TERM}*)) +dt.ldap.users.search.filter=(&(objectClass=inetOrgPerson)(uid=*{SEARCH_TERM}*)) ``` --- @@ -162,10 +165,10 @@ DT_LDAP_USERS_SEARCH_FILTER=(&(objectClass=inetOrgPerson)(uid=*{SEARCH_TERM}*)) For a full list of LDAP-related configuration properties and their types, defaults, and environment variable equivalents, see the -[configuration reference](../../reference/configuration/properties.md#dtldapenabled). +[configuration reference](../../reference/configuration/properties.md#ldap). ## See also - [Permissions](../../reference/permissions.md): mapping LDAP groups to Dependency-Track teams -- [Configuring OIDC](configuring-oidc.md): alternative to LDAP using OpenID Connect -- [Configuring Internal CA](configuring-internal-ca.md): trust internal TLS certificates for LDAPS +- [Configuring OpenID Connect](configuring-oidc.md): alternative to LDAP using OpenID Connect +- [Configuring internal CA trust](configuring-internal-ca.md): trust internal TLS certificates for LDAPS diff --git a/docs/includes/abbreviations.md b/docs/includes/abbreviations.md index f2f4b5b..62933b8 100644 --- a/docs/includes/abbreviations.md +++ b/docs/includes/abbreviations.md @@ -7,6 +7,7 @@ *[EPSS]: Exploit Prediction Scoring System *[GHSA]: GitHub Security Advisory *[KEK]: Key Encryption Key +*[LDAP]: Lightweight Directory Access Protocol *[NVD]: National Vulnerability Database *[OSV]: Open Source Vulnerabilities *[PURL]: Package URL, a standardized format for identifying software packages