Skip to main content

LDAP

Styra Load's support for pulling in data from any LDAP server makes it possible to have all your user and groups data managed in directory services available for policy evaluations in Styra Load.

Example Configuration

The LDAP integration is provided via the data plugin, and needs to be enabled in Load's configuration.

load-conf.yaml (minimal)

plugins:
data:
ldap.users:
type: ldap
urls:
- ldap://internal.ldapd:1389
base_dn: ou=users,dc=example,dc=org

With this minimal configuration, Styra Load will pull in all attributes of all objects found under the base DN ou=users,dc=example,dc=org every 30 seconds.

All of this, and various other search- and TLS-related settings, can be configured using an advanced configuration:

load-conf-advanced.yaml

plugins:
data:
ldap.users:
type: ldap
urls:
- ldap://internal.ldapd:1389
base_dn: ou=users,dc=example,dc=org
filter: (objectClass=inetOrgPerson)
attributes: # only pull in certain attributes
- cn
- sn
- uid
scope: base-object # one of "base-object", "single-level", "whole-subtree" (default)
deref: always # one of "never" (default), "searching", "finding", "always"
polling_interval: 10m # default: 30s, minimum 10s

username: alice # bind username
password: wordpass # bind password

tls_skip_verification: true
tls_client_cert: cert.pem
tls_ca_cert: ca.pem
tls_client_private_key: key.pem # key, file path or PEM contents

With a config like this, Styra Load will periodically perform an LDAP search according to the configured parameters, and provide the retrieved data in the configured subtree, e.g. data.ldap.users.

note

Since LDAP objects can have multiple values for each key, the pulled-in data contains array values for all attributes.

See the example below for details.

Example Call

If your LDAP service contains two users, cn=user01,ou=users,dc=example,dc=org and cn=user02,ou=users,dc=example,dc=org, as returned by an ldapsearch query:

$  ldapsearch -x -h 127.0.0.1:1389 -b 'ou=users,dc=example,dc=org' '(objectClass=inetOrgPerson)' sn cn uid
# extended LDIF
#
# LDAPv3
# base <ou=users,dc=example,dc=org> with scope subtree
# filter: (objectClass=inetOrgPerson)
# requesting: sn cn
#

# user01, users, example.org
dn: cn=user01,ou=users,dc=example,dc=org
cn: User1
cn: user01
uid: user01
sn: Bar1

# user02, users, example.org
dn: cn=user02,ou=users,dc=example,dc=org
cn: User2
cn: user02
uid: user02
sn: Bar2

# search result
search: 2
result: 0 Success

# numResponses: 3
# numEntries: 2

and you've configured your Styra Load instance as above, you will be able to see the entities appear in your data.ldap.users tree:

$ curl 'http://127.0.0.1:8181/v1/data/ldap/users?pretty'
{
"result": [
{
"cn": [
"User1",
"user01"
],
"dn": {
"_raw": "cn=user01,ou=users,dc=example,dc=org",
"cn": [
"user01"
],
"dc": [
"example",
"org"
],
"ou": [
"users"
]
},
"sn": [
"Bar1"
],
"uid": [
"user01"
]
},
{
"cn": [
"User2",
"user02"
],
"dn": {
"_raw": "cn=user02,ou=users,dc=example,dc=org",
"cn": [
"user02"
],
"dc": [
"example",
"org"
],
"ou": [
"users"
]
},
"sn": [
"Bar2"
],
"uid": [
"user02"
]
}
]
}

As mentioned above, all values are arrays. This needs to be taken into account when writing policies against that data.

For example, to match input.user against this data retrieved from LDAP, you'd write

import future.keywords.if
import future.keywords.in

allow if matches_user(input.user)

matches_user(user) if {
some entry in data.ldap.users
user in entry.uid # NOT entry.uid == user
}
note

The key below data in the configuration (git.users in the example) can be anything you want, and determines where the retrieved document will be found in Styra Load's data hierarchy.