Set up SonarQube to authenticate users against Active Directory using LDAP. Configure automatic user provisioning, group synchronization, and role-based access control for enterprise environments with centralized authentication.
Prerequisites
- SonarQube 9.x or higher installed
- Active Directory server accessible
- LDAP service account with read permissions
- Administrator access to SonarQube
What this solves
SonarQube LDAP authentication integrates your code quality platform with Active Directory, eliminating the need for separate user accounts. This enables centralized user management, automatic group synchronization, and role-based access control based on AD group memberships.
Prerequisites and requirements
Before configuring LDAP authentication, ensure you have the following information from your Active Directory administrator:
- LDAP server URL and port (typically 389 for LDAP, 636 for LDAPS)
- Service account credentials for LDAP binding
- Base DN for users and groups
- Group distinguished names for SonarQube permissions
Step-by-step configuration
Stop SonarQube service
Stop SonarQube before making configuration changes to ensure settings are properly loaded.
sudo systemctl stop sonarqube
Configure LDAP connection settings
Edit the SonarQube configuration file to add LDAP server connection parameters.
# Enable LDAP authentication
sonar.security.realm=LDAP
LDAP server configuration
ldap.url=ldap://ad.example.com:389
ldap.bindDn=CN=sonarqube-svc,OU=Service Accounts,DC=example,DC=com
ldap.bindPassword=YourServiceAccountPassword
Connection settings
ldap.authentication=simple
ldap.followReferrals=true
ldap.connectTimeout=5000
ldap.responseTimeout=10000
Configure user authentication mapping
Define how SonarQube maps LDAP user attributes to internal user properties.
# User configuration
ldap.user.baseDn=OU=Users,DC=example,DC=com
ldap.user.request=(&(objectClass=user)(sAMAccountName={login}))
ldap.user.realNameAttribute=displayName
ldap.user.emailAttribute=mail
Optional: Map additional user attributes
ldap.user.firstNameAttribute=givenName
ldap.user.lastNameAttribute=sn
Configure group mapping and synchronization
Set up automatic group synchronization to map Active Directory groups to SonarQube permissions.
# Group configuration
ldap.group.baseDn=OU=Groups,DC=example,DC=com
ldap.group.request=(&(objectClass=group)(member={dn}))
ldap.group.idAttribute=sAMAccountName
Group mapping for role-based access
sonar.security.localUsers=admin
Map specific AD groups to SonarQube groups
ldap.group.mapping.administrators=CN=SonarQube-Admins,OU=Groups,DC=example,DC=com
ldap.group.mapping.users=CN=SonarQube-Users,OU=Groups,DC=example,DC=com
ldap.group.mapping.developers=CN=Development-Team,OU=Groups,DC=example,DC=com
Configure SSL encryption for LDAPS
For production environments, configure SSL/TLS encryption for secure LDAP communication.
# LDAPS configuration (recommended for production)
ldap.url=ldaps://ad.example.com:636
SSL certificate validation
ldap.StartTLS=false
Trust store configuration (if using custom certificates)
sonar.web.javaOpts=-Djavax.net.ssl.trustStore=/path/to/truststore.jks -Djavax.net.ssl.trustStorePassword=password
Set file ownership and permissions
Ensure the SonarQube user can read the configuration file while keeping sensitive credentials secure.
sudo chown sonarqube:sonarqube /opt/sonarqube/conf/sonar.properties
sudo chmod 640 /opt/sonarqube/conf/sonar.properties
Start SonarQube and verify configuration
Start the service and monitor logs for any LDAP connection issues.
sudo systemctl start sonarqube
sudo systemctl status sonarqube
sudo tail -f /opt/sonarqube/logs/sonar.log
Configure role-based access control
Access SonarQube web interface
Log into SonarQube using the admin account to configure group permissions.
https://sonarqube.example.com:9000
Configure group permissions
Navigate to Administration > Security > Global Permissions to assign permissions to LDAP groups.
| Group | Permissions | Purpose |
|---|---|---|
| SonarQube-Admins | Administer System, Administer Quality Gates | Full administrative access |
| Development-Team | Browse, Create Projects, Provision Projects | Developers can create and analyze projects |
| SonarQube-Users | Browse | Read-only access to view analysis results |
Test LDAP authentication
Test login with an Active Directory account to verify LDAP integration.
- Log out of the admin account
- Attempt login with an AD username and password
- Verify user profile shows correct name and email from LDAP
- Check that group memberships are correctly synchronized
Advanced LDAP configuration
Configure multiple LDAP servers
For high availability, configure multiple domain controllers for failover.
# Multiple LDAP servers for redundancy
ldap.url=ldap://dc1.example.com:389 ldap://dc2.example.com:389
Connection pooling
ldap.connectionPooling=true
Configure nested group support
Enable nested group resolution for complex Active Directory structures.
# Nested groups configuration
ldap.group.request=(&(objectClass=group)(|(member={dn})(member:1.2.840.113556.1.4.1941:={dn})))
Configure user synchronization scheduling
Set up automatic user and group synchronization intervals.
# Synchronization settings
sonar.security.ldap.sync.userGroups=true
sonar.security.ldap.sync.interval=3600
Verify your setup
Confirm LDAP authentication is working correctly with these verification steps:
# Check SonarQube is running and responding
curl -I http://localhost:9000
Verify LDAP connectivity from SonarQube server
ldapsearch -x -H ldap://ad.example.com:389 -D "CN=sonarqube-svc,OU=Service Accounts,DC=example,DC=com" -w "password" -b "DC=example,DC=com" "(objectClass=user)" | head -20
Check SonarQube logs for LDAP authentication attempts
sudo tail -50 /opt/sonarqube/logs/sonar.log | grep -i ldap
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| LDAP bind failed | Incorrect service account credentials | Verify ldap.bindDn and ldap.bindPassword with AD admin |
| Users not found | Wrong user base DN or search filter | Test LDAP search manually: ldapsearch -x -H ldap://server -D binddn -w pass -b userdn |
| Groups not synchronized | Group mapping configuration error | Check ldap.group.baseDn and verify group membership in AD |
| SSL connection failed | Certificate validation issues | Import AD certificate to Java truststore or configure custom truststore |
| Slow authentication | Network latency or large directory | Tune ldap.connectTimeout and ldap.responseTimeout values |
| Permission denied on config | Wrong file ownership | sudo chown sonarqube:sonarqube /opt/sonarqube/conf/sonar.properties |
Next steps
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Global variables
SCRIPT_NAME=$(basename "$0")
SONAR_USER="sonarqube"
SONAR_CONFIG="/opt/sonarqube/conf/sonar.properties"
BACKUP_CONFIG="/opt/sonarqube/conf/sonar.properties.backup"
LOG_FILE="/var/log/sonarqube-ldap-setup.log"
# Print colored output
print_status() {
echo -e "${BLUE}[INFO]${NC} $1" | tee -a "$LOG_FILE"
}
print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1" | tee -a "$LOG_FILE"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1" | tee -a "$LOG_FILE"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1" | tee -a "$LOG_FILE"
}
# Usage message
usage() {
echo "Usage: $SCRIPT_NAME [OPTIONS]"
echo "Configure SonarQube LDAP authentication with Active Directory"
echo ""
echo "Options:"
echo " -d, --domain DOMAIN Active Directory domain (e.g., example.com)"
echo " -s, --server SERVER LDAP server hostname or IP"
echo " -u, --user USER LDAP service account username"
echo " -p, --password PASS LDAP service account password"
echo " --ssl Use LDAPS (SSL/TLS encryption)"
echo " -h, --help Show this help message"
echo ""
echo "Example:"
echo " $SCRIPT_NAME -d example.com -s ad.example.com -u sonarqube-svc -p 'MyPassword'"
}
# Error handler for cleanup
cleanup() {
print_error "Script failed. Performing cleanup..."
if [[ -f "$BACKUP_CONFIG" ]] && [[ -f "$SONAR_CONFIG" ]]; then
print_status "Restoring original configuration..."
cp "$BACKUP_CONFIG" "$SONAR_CONFIG"
chown "$SONAR_USER:$SONAR_USER" "$SONAR_CONFIG"
chmod 640 "$SONAR_CONFIG"
fi
if command -v systemctl &> /dev/null && systemctl is-enabled sonarqube &> /dev/null; then
systemctl start sonarqube || true
fi
exit 1
}
trap cleanup ERR
# Check prerequisites
check_prerequisites() {
print_status "[1/8] Checking prerequisites..."
# Check if running as root or with sudo
if [[ $EUID -ne 0 ]]; then
print_error "This script must be run as root or with sudo"
exit 1
fi
# Check if SonarQube is installed
if [[ ! -d "/opt/sonarqube" ]]; then
print_error "SonarQube not found in /opt/sonarqube. Please install SonarQube first."
exit 1
fi
if [[ ! -f "$SONAR_CONFIG" ]]; then
print_error "SonarQube configuration file not found: $SONAR_CONFIG"
exit 1
fi
print_success "Prerequisites check completed"
}
# Detect OS and package manager
detect_os() {
print_status "[2/8] Detecting operating system..."
if [[ ! -f /etc/os-release ]]; then
print_error "Cannot detect OS. /etc/os-release not found."
exit 1
fi
# Source the os-release file
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
PKG_UPDATE="apt update"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf update -y"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
PKG_UPDATE="yum update -y"
;;
*)
print_error "Unsupported distribution: $ID"
exit 1
;;
esac
print_success "Detected $PRETTY_NAME using $PKG_MGR"
}
# Parse command line arguments
parse_arguments() {
if [[ $# -eq 0 ]]; then
usage
exit 1
fi
while [[ $# -gt 0 ]]; do
case $1 in
-d|--domain)
AD_DOMAIN="$2"
shift 2
;;
-s|--server)
LDAP_SERVER="$2"
shift 2
;;
-u|--user)
LDAP_USER="$2"
shift 2
;;
-p|--password)
LDAP_PASSWORD="$2"
shift 2
;;
--ssl)
USE_SSL=true
shift
;;
-h|--help)
usage
exit 0
;;
*)
print_error "Unknown option: $1"
usage
exit 1
;;
esac
done
# Validate required arguments
if [[ -z "${AD_DOMAIN:-}" ]] || [[ -z "${LDAP_SERVER:-}" ]] || [[ -z "${LDAP_USER:-}" ]] || [[ -z "${LDAP_PASSWORD:-}" ]]; then
print_error "Missing required arguments. Use -h for help."
exit 1
fi
# Set defaults
USE_SSL=${USE_SSL:-false}
LDAP_PORT=${LDAP_PORT:-389}
if [[ "$USE_SSL" == true ]]; then
LDAP_PORT=636
LDAP_URL="ldaps://$LDAP_SERVER:$LDAP_PORT"
else
LDAP_URL="ldap://$LDAP_SERVER:$LDAP_PORT"
fi
}
# Stop SonarQube service
stop_sonarqube() {
print_status "[3/8] Stopping SonarQube service..."
if command -v systemctl &> /dev/null; then
if systemctl is-active --quiet sonarqube; then
systemctl stop sonarqube
print_success "SonarQube service stopped"
else
print_warning "SonarQube service was not running"
fi
else
print_warning "systemctl not found, skipping service stop"
fi
}
# Backup configuration
backup_configuration() {
print_status "[4/8] Backing up current configuration..."
cp "$SONAR_CONFIG" "$BACKUP_CONFIG"
chown "$SONAR_USER:$SONAR_USER" "$BACKUP_CONFIG"
chmod 640 "$BACKUP_CONFIG"
print_success "Configuration backed up to $BACKUP_CONFIG"
}
# Configure LDAP settings
configure_ldap() {
print_status "[5/8] Configuring LDAP authentication..."
# Build domain components for DN
IFS='.' read -ra DOMAIN_PARTS <<< "$AD_DOMAIN"
DOMAIN_DN=""
for part in "${DOMAIN_PARTS[@]}"; do
if [[ -n "$DOMAIN_DN" ]]; then
DOMAIN_DN="${DOMAIN_DN},DC=${part}"
else
DOMAIN_DN="DC=${part}"
fi
done
# Remove existing LDAP configuration if present
sed -i '/^sonar\.security\.realm=/d' "$SONAR_CONFIG"
sed -i '/^ldap\./d' "$SONAR_CONFIG"
# Add LDAP configuration
cat >> "$SONAR_CONFIG" << EOF
# LDAP Authentication Configuration
sonar.security.realm=LDAP
# LDAP server configuration
ldap.url=$LDAP_URL
ldap.bindDn=CN=$LDAP_USER,OU=Service Accounts,$DOMAIN_DN
ldap.bindPassword=$LDAP_PASSWORD
# Connection settings
ldap.authentication=simple
ldap.followReferrals=true
ldap.connectTimeout=5000
ldap.responseTimeout=10000
# User configuration
ldap.user.baseDn=OU=Users,$DOMAIN_DN
ldap.user.request=(&(objectClass=user)(sAMAccountName={login}))
ldap.user.realNameAttribute=displayName
ldap.user.emailAttribute=mail
ldap.user.firstNameAttribute=givenName
ldap.user.lastNameAttribute=sn
# Group configuration
ldap.group.baseDn=OU=Groups,$DOMAIN_DN
ldap.group.request=(&(objectClass=group)(member={dn}))
ldap.group.idAttribute=sAMAccountName
# Keep local admin user
sonar.security.localUsers=admin
EOF
print_success "LDAP configuration added"
}
# Set proper permissions
set_permissions() {
print_status "[6/8] Setting file permissions..."
# Ensure sonarqube user exists
if ! id "$SONAR_USER" &> /dev/null; then
print_error "User $SONAR_USER does not exist"
exit 1
fi
# Set ownership and permissions
chown "$SONAR_USER:$SONAR_USER" "$SONAR_CONFIG"
chmod 640 "$SONAR_CONFIG"
print_success "File permissions set correctly"
}
# Start SonarQube service
start_sonarqube() {
print_status "[7/8] Starting SonarQube service..."
if command -v systemctl &> /dev/null; then
systemctl start sonarqube
sleep 5
if systemctl is-active --quiet sonarqube; then
print_success "SonarQube service started successfully"
else
print_error "Failed to start SonarQube service"
print_status "Checking logs..."
journalctl -u sonarqube --no-pager -n 20
exit 1
fi
else
print_warning "systemctl not found, cannot start service automatically"
fi
}
# Verify configuration
verify_configuration() {
print_status "[8/8] Verifying configuration..."
# Check if config file exists and has correct permissions
if [[ -f "$SONAR_CONFIG" ]]; then
local perms=$(stat -c "%a" "$SONAR_CONFIG")
local owner=$(stat -c "%U:%G" "$SONAR_CONFIG")
if [[ "$perms" == "640" ]] && [[ "$owner" == "$SONAR_USER:$SONAR_USER" ]]; then
print_success "Configuration file permissions verified"
else
print_warning "Configuration file permissions: $perms, owner: $owner"
fi
fi
# Check if LDAP configuration exists
if grep -q "sonar.security.realm=LDAP" "$SONAR_CONFIG"; then
print_success "LDAP authentication enabled in configuration"
else
print_error "LDAP configuration not found"
exit 1
fi
# Check service status
if command -v systemctl &> /dev/null && systemctl is-active --quiet sonarqube; then
print_success "SonarQube service is running"
fi
print_success "Configuration verification completed"
print_status ""
print_status "LDAP authentication has been configured successfully!"
print_status "You can now:"
print_status "1. Access SonarQube web interface and log in as admin"
print_status "2. Configure group permissions under Administration > Security > Global Permissions"
print_status "3. Test LDAP authentication with your AD credentials"
print_status ""
print_warning "Remember to configure group mappings in the SonarQube web interface"
}
# Main function
main() {
echo "SonarQube LDAP Authentication Configuration Script"
echo "================================================="
# Initialize log file
touch "$LOG_FILE"
chmod 644 "$LOG_FILE"
parse_arguments "$@"
check_prerequisites
detect_os
stop_sonarqube
backup_configuration
configure_ldap
set_permissions
start_sonarqube
verify_configuration
}
# Run main function with all arguments
main "$@"
Review the script before running. Execute with: bash install.sh