# LDAP

The Datasentinel frontend is stored as a Grafana plugin and utilizes the Grafana authentication method for streamlined user access and secure login.

To configure LDAP authentication, the Grafana configuration files must be modified accordingly. [See Grafana documentation](https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/ldap/)

{% hint style="info" %}
Although LDAP authentication can be used with any version of Datasentinel, it is much more integrated starting from version 2023.03, which was released in March 2023.
{% endhint %}

{% hint style="warning" %}
Only authentication is managed by a LDAP server.&#x20;

The management of profiles, privileges, and role-based access continues to be handled through the [Datasentinel Interface](https://docs.datasentinel.io/manual/implementation/platform-usage/configuration/users-and-roles) or [API](https://docs.datasentinel.io/manual/implementation/platform-usage/api-reference/user)
{% endhint %}

## Enable LDAP Authentication

Edit main config file

```bash
/datasentinel/soft/grafana/src/github.com/grafana/grafana/conf/defaults.ini
```

Enable ldap authentication in the **auth.ldap** section.

```bash
#################################### Auth LDAP ###########################
[auth.ldap]
# Enable LDAP
enabled = true
# Configuration file
config_file = /datasentinel/soft/ldap.toml
allow_sign_up = true

# LDAP backround sync (Enterprise only)
# At 1 am every day
sync_cron = "0 0 1 * * *"
#
# IMPORTANT: deactivates ldap synchronization
active_sync_enabled = false
```

## Configure LDAP Access

Edit configuration file&#x20;

```bash
/datasentinel/soft/ldap.toml
```

### [OpenLDAP](https://www.openldap.org/)&#x20;

```bash
# To troubleshoot and get more log info enable ldap debug logging in grafana.ini
# [log]
# filters = ldap:debug

[[servers]]
# Ldap server host (specify multiple hosts space separated)
host = "51.158.110.62"
# Default port is 389 or 636 if use_ssl = true
port = 389

# Set to true if ldap server supports TLS
use_ssl = false
# Set to true if connect ldap server with STARTTLS pattern (create connection in insecure, then upgrade to secure connection with TLS)
start_tls = false
# set to true if you want to skip ssl cert validation
ssl_skip_verify = false
# set to the path to your root CA certificate or leave unset to use system defaults
# root_ca_cert = "/path/to/certificate.crt"
# Authentication against LDAP servers requiring client certificates
# client_cert = "/path/to/client.crt"
# client_key = "/path/to/client.key"

#
# Search user bind dn
#
# User bind DN" typically refers to the Distinguished Name (DN) of a user account that is used to authenticate and bind to a directory service such as LDAP or Active Directory.
#
# Example
bind_dn = "cn=admin,dc=datasentinel,dc=io"
#
# Search user bind password
# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
bind_password = 'adminpassword'

# User search filter, for example "(cn=%s)" or "(sAMAccountName=%s)" or "(uid=%s)"
search_filter = "(cn=%s)"

# An array of base dns to search through
#
# Example
search_base_dns = ["dc=datasentinel,dc=io"]

## For Posix or LDAP setups that does not support member_of attribute you can define the below settings
## Please check grafana LDAP docs for examples
# group_search_filter = "(&(objectClass=posixGroup)(memberUid=%s))"
# group_search_base_dns = ["ou=groups,dc=grafana,dc=org"]
# group_search_filter_user_attribute = "uid"

# Specify names of the ldap attributes your ldap uses
[servers.attributes]
name = "givenName"
surname = "sn"
username = "cn"
member_of = "memberOf"
email =  "email"

# All groups are assigned the role of Viewer and the organization ID 2, which corresponds to datasentinel.
# Do not modify
[[servers.group_mappings]]
group_dn = "*"
org_role = "Viewer"
org_id = 2
```

### [Microsoft active directory](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-R2-and-2012/hh831484\(v=ws.11\)?redirectedfrom=MSDN)

```bash
# To troubleshoot and get more log info enable ldap debug logging in grafana.ini
# [log]
# filters = ldap:debug

[[servers]]
# Ldap server host (specify multiple hosts space separated)
host = "51.158.110.62"
# Default port is 389 or 636 if use_ssl = true
port = 636

# Set to true if ldap server supports TLS
use_ssl = true
# Set to true if connect ldap server with STARTTLS pattern (create connection in insecure, then upgrade to secure connection with TLS)
start_tls = false
# set to true if you want to skip ssl cert validation
ssl_skip_verify = true
# set to the path to your root CA certificate or leave unset to use system defaults
# root_ca_cert = "/path/to/certificate.crt"
# Authentication against LDAP servers requiring client certificates
# client_cert = "/path/to/client.crt"
# client_key = "/path/to/client.key"

#
# Search user bind dn
#
# User bind DN" typically refers to the Distinguished Name (DN) of a user account that is used to authenticate and bind to a directory service such as LDAP or Active Directory.
#
# Example
bind_dn = "CORP\\%s"
# Search user bind password
# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
bind_password = 'adminpassword'

# User search filter, for example "(cn=%s)" or "(sAMAccountName=%s)" or "(uid=%s)"
search_filter = "(sAMAccountName=%s)"

# An array of base dns to search through
#
# Example
search_base_dns = ["dc=corp,dc=local"]

## For Posix or LDAP setups that does not support member_of attribute you can define the below settings
## Please check grafana LDAP docs for examples
# group_search_filter = "(&(objectClass=posixGroup)(memberUid=%s))"
# group_search_base_dns = ["ou=groups,dc=grafana,dc=org"]
# group_search_filter_user_attribute = "uid"

# Specify names of the ldap attributes your ldap uses
[servers.attributes]
name = "givenName"
surname = "sn"
username = "sAMAccountName"
member_of = "memberOf"
email =  "email"

# All groups are assigned the role of Viewer and the organization ID 2, which corresponds to datasentinel.
# Do not modify
[[servers.group_mappings]]
group_dn = "*"
org_role = "Viewer"
org_id = 2
```

## Restart Grafana

```
systemctl restart datasentinel_grafana
```

## Verify

You can now connect to Datasentinel with a ldap user.

View logs

```bash
journalctl -xefu datasentinel_grafana
```

Output example

```
Mar 09 17:32:00 pg-datasentinel-3509 grafana-server[4067]: t=2023-03-09T17:32:00+0100 lvl=info msg="LDAP enabled, reading config file" logger=ldap file=/datasentinel/soft/ldap.toml
Mar 09 17:32:00 pg-datasentinel-3509 grafana-server[4067]: t=2023-03-09T17:32:00+0100 lvl=eror msg="Invalid username or password" logger=context userId=0 orgId=0 uname= error="Invalid Username or Password"
Mar 09 17:32:00 pg-datasentinel-3509 grafana-server[4067]: t=2023-03-09T17:32:00+0100 lvl=info msg="Request Completed" logger=context userId=0 orgId=0 uname= method=POST path=/login status=401 remote_addr=127.0.0.1 time_ms=65 size=42 referer=https://51.15.226.239/login
Mar 09 17:32:11 pg-datasentinel-3509 grafana-server[4067]: t=2023-03-09T17:32:11+0100 lvl=eror msg="Cannot bind user cn=user02,ou=users,dc=datasentinel,dc=io with LDAP" logger=ldap error="Invalid Username or Password"
Mar 09 17:32:11 pg-datasentinel-3509 grafana-server[4067]: t=2023-03-09T17:32:11+0100 lvl=eror msg="Invalid username or password" logger=context userId=0 orgId=0 uname= error="Invalid Username or Password"
Mar 09 17:32:11 pg-datasentinel-3509 grafana-server[4067]: t=2023-03-09T17:32:11+0100 lvl=info msg="Request Completed" logger=context userId=0 orgId=0 uname= method=POST path=/login status=401 remote_addr=127.0.0.1 time_ms=29 size=42 referer=https://51.15.226.239/login
Mar 09 17:32:15 pg-datasentinel-3509 grafana-server[4067]: t=2023-03-09T17:32:15+0100 lvl=info msg="Successful Login" logger=http.server User=User2
```

{% hint style="info" %}
You can also directly edit the log file located at `/datasentinel/log/grafana.log`
{% endhint %}
