Boundary
LDAP authentication
Lightweight Directory Access Protocol (LDAP) is a standards-based protocol that sits on top of TCP/IP and allows clients to perform a variety of operations in a directory server, including storing and retrieving data, searching for data matching a given set of criteria, authenticating clients, and more. LDAP is an open, vendor-neutral application protocol for accessing and maintaining that directory data.
Boundary now includes an LDAP auth method which allows Boundary to delegate authentication to an LDAP directory. The first time a user successfully authenticates using an LDAP auth method, a new LDAP account is created using the user’s account login name. If groups are enabled for an LDAP auth method, then each time a user authenticates their account’s group memberships are updated in Boundary. LDAP managed groups allow administrators to assign roles within Boundary based on an LDAP account’s group memberships.
This tutorial provides an example of setting up LDAP as an authentication method for Boundary using HCP Boundary or Boundary's dev mode.
LDAP authentication method overview
- Get setup
- LDAP setup
- Create an auth method
- Authentication states
- Authenticate a user
- Define a managed group
Prerequisites
A Boundary binary greater than 0.14.0 in your
PATH
This tutorial assumes you can connect to an HCP Boundary cluster or launch Boundary in dev mode.
git
is required for cloning repositories used in the scenario.Installing Terraform 0.13.0 or greater provides an optional workflow for this tutorial. The binary must be available in your
PATH
.Access to the online LDAP test server
OR
A Windows environment with Active Directory. This scenario uses the community based Vagrant environment for a Windows Server based Active Directory project.
Vagrant 2.2 or newer is required if you choose to use the Vagrant environment for an Active Directory Server. This scenario was last tested with version 2.3.7.
VirtualBox 6.1.34 or newer is also needed if using the Vagrant environment for an Active Directory Server.
If you follow along on a Linux based host, you will need
xdg-open
. Sometimes this utility is part of an xdg-utils meta-package that you can install with your OS package manager. Check your distribution specific documentation for details on how to installxdg-open
.
Note
If you use the Vagrant environment for Windows paired with HCP Boundary, a free ngrok account is also required to create a publicly routable address. Instructions for installing and configuring ngrok are provided later on.
Get setup
In this tutorial, you will test the LDAP auth method using HCP Boundary or by running a Boundary controller locally using dev mode.
Start Boundary in dev mode:
$ boundary dev
==> Boundary server configuration:
[Bsr] AEAD Key Bytes: Y2Qkr9cXlX+e16tuGh60rCj9D7pTZ6qi
[Controller] AEAD Key Bytes: CL643Nlmlu3DufHZSfpRJMiR7i/Be4PD
[Recovery] AEAD Key Bytes: 1jlRWVEBmsL05139sQcyq4uJTdrHFtiM
[Worker-Auth] AEAD Key Bytes: B9pPVoojYCb2ADdu5V3GxEolYjS31mxU
[Bsr] AEAD Type: aes-gcm
[Recovery] AEAD Type: aes-gcm
[Root] AEAD Type: aes-gcm
[Worker-Auth-Storage] AEAD Type: aes-gcm
[Worker-Auth] AEAD Type: aes-gcm
Cgo: disabled
Controller Public Cluster Addr: 127.0.0.1:9201
Dev Database Container: beautiful_curran
Dev Database Url: postgres://postgres:password@localhost:55000/boundary?sslmode=disable
Generated Admin Login Name: admin
Generated Admin Password: password
Generated Host Catalog Id: hcst_1234567890
Generated Host Id: hst_1234567890
Generated Host Set Id: hsst_1234567890
Generated Ldap Auth Method Base Search DNs: users="ou=people,dc=example,dc=org" groups="ou=groups,dc=example,dc=org"
Generated Ldap Auth Method Host:Port: 127.0.0.1:63165 (does not have a root DSE; use simple bind)
Generated Ldap Auth Method Id: amldap_1234567890
Generated Oidc Auth Method Id: amoidc_1234567890
Generated Org Scope Id: o_1234567890
Generated Password Auth Method Id: ampw_1234567890
Generated Project Scope Id: p_1234567890
Generated Target With Address Id: ttcp_1234567890
Generated Target With Host Source Id: ttcp_0987654321
Generated Unprivileged Login Name: user
Generated Unprivileged Password: password
Listener 1: tcp (addr: "127.0.0.1:9200", cors_allowed_headers: "[]", cors_allowed_origins: "[*]", cors_enabled: "true", max_request_duration: "1m30s", purpose: "api")
Listener 2: tcp (addr: "127.0.0.1:9201", max_request_duration: "1m30s", purpose: "cluster")
Listener 3: tcp (addr: "127.0.0.1:9203", max_request_duration: "1m30s", purpose: "ops")
Listener 4: tcp (addr: "127.0.0.1:9202", max_request_duration: "1m30s", purpose: "proxy")
Log Level: info
Mlock: supported: false, enabled: false
Version: Boundary v0.14.2
Version Sha: a86ee182c2853913f019c2559f1451d926235707
Worker Auth Current Key Id: surrender-flaky-exemption-phrasing-skillet-huskiness-president-fit
Worker Auth Storage Path: (in-memory)
Worker Public Proxy Addr: 127.0.0.1:9202
==> Boundary server started! Log data will stream in below:
{
"id": "mM9ggiN06v",
"source": "https://hashicorp.com/boundary/robinbeck-C02DRAWTMD6R/controller+worker",
"specversion": "1.0",
"type": "system",
"data": {
"version": "v0.1",
"op": "github.com/hashicorp/boundary/internal/event.(*HclogLoggerAdapter).writeEvent",
"data": {
"@original-log-level": "none",
"@original-log-name": "aws",
"msg": "configuring client automatic mTLS"
}
},
...
... More log output ...
...
Leave dev mode running in the current session, and open a new terminal window or tab.
Authenticate to the local Boundary dev server. Enter the password password
when prompted.
$ boundary authenticate
Please enter the login name (it will be hidden):
Please enter the password (it will be hidden):
Authentication information:
Account ID: acctpw_AnOiGVNB62
Auth Method ID: ampw_7c7W19uiez
Expiration Time: Tue, 10 Oct 2023 18:14:50 MDT
User ID: u_PtOpf9SyEk
The token was successfully stored in the chosen keyring and is not displayed here.
Take note of the Auth Method ID from the output. Export it as the
ADMIN_AUTH_METHOD_ID
variable for use later on.
$ export ADMIN_AUTH_METHOD_ID=ampw_1234567890
LDAP setup
To enable an LDAP auth method an administrator must first configure their LDAP server, and then Boundary.
If you do not want to set up an LDAP server, this tutorial provides a workflow using an online LDAP test server.
Alternatively, you can use Vagrant to set up Active Directory by selecting the Active Directory tab below. For HCP Boundary, ngrok is also required to expose the local LDAP server to Boundary.
Note
Be aware that using ngrok creates a publicly routable address for the postgres container. If you do not wish to use ngrok, consider using the online LDAP test server, or running Boundary in dev mode.
If you want to use your own development LDAP server, you will need the appropriate configuration information about the LDAP server you wish to use. For an exhaustive list of configuration parameters, refer to: LDAP auth method attributes.
Select a workflow to continue the tutorial.
You can use an online LDAP test
server provided
by forumsys.com to complete this tutorial without setting up an LDAP
server. To deploy an LDAP server using Active Directory instead, select the
Active Directory
tab.
The online LDAP server at ldap.forumsys.com is a public, read-only test server.
In this public server, all user passwords are password
. You may also bind to
individual Users (uid
).
The following group is also provided, and will be used to test Boundary's managed group access:
ou=scientists,dc=example,dc=com
Auth method creation
To enable an LDAP auth method, an administrator must configure Boundary with parameters which specify how to connect, bind, and search the directory for a user and their associated groups. Care has been taken to use the same parameters used for configuring Vault's LDAP auth methods.
The LDAP auth method configuration options are categorized and detailed below.
Tip
Detailed knowledge of LDAP is not required to proceed with the tutorial. To skip to the next section, visit Create the auth method for the provider.
Connection parameters:
These values are used to establish a connection between Boundary and the directory server. That connection can be either insecure, TLS or mTLS.
urls
(string, required) - A set of LDAP URLs that specifies a set of LDAP servers to connect to. Examples:ldap://ldap.myorg.com
,ldaps://ldap.myorg.com:636
. If there's more than one URL configured, the directories will be tried in order if there are errors during the connection process. The URL scheme must be eitherldap
orldaps
. The port is optional. If you don't specify a port, then a default of389
is used for ldap and a default of689
is used for ldaps.start_tls
(bool, optional) - Iftrue
, issues a StartTLS command after establishing an unencrypted connection.insecure_tls
(bool, optional) - Iftrue
, skips LDAP server SSL certificate verification.certificates
(string, optional) - CA certificate to use when verifying LDAP server certificate, must be x509 PEM encoded.client_certificate
(string, optional) - Client certificate to provide to the LDAP server for mTLS connections, must be x509 PEM encoded.client_certificate_key
(string, optional) - Client certificate private key used with the ClientTLSCert for mTLS connections to the LDAP server, must be x509 PEM encoded.
Bind parameters
Before authenticating an end user, Boundary must first find the end user’s entry in the directory. There are two alternate methods of resolving the user entry Boundary uses to authenticate the end user: Search or User Principal Name. When you use Search, the bind can be either anonymous or authenticated. User Principal Name is a method of specifying users supported by Active Directory. More information on UPN can be found here.
Binding - Authenticated search
These parameters allow Boundary to bind (aka authenticate) using the credentials provided when searching for the user entry used to authenticate the end user:
bind_dn
(string, optional) - Distinguished name of entry to bind when performing user and group search. Example:cn=vault,ou=Users,dc=example,dc=com
bind_password
(string, optional) - Password to use along withbinddn
when performing user search.
Binding - Anonymous search
These parameters allow Boundary to bind anonymously to the directory when searching for the user entry used to authenticate the end user:
discover_dn
(bool, optional) - Iftrue
, use anonymous bind to discover the bind DN of a user.anon_group_search
(bool, optional) - Use anonymous binds when performing LDAP group searches. Defaults tofalse
.
Binding - User principal name (AD)
Active Directory uses UPNs (userPrincipalNames) as a user’s logon name. The following parameter allows Boundary to construct a user’s UPN from the username provided during authentication:
upn_domain
(string, optional) - userPrincipalDomain used to construct the UPN string for the authenticating user. The constructed UPN will appear as [username]@UPNDomain Example: example.com, which will cause Boundary to bind as username@example.com when authenticating the user.
Search parameters: user entries
Before authenticating an end user, Boundary must first find the end user’s entry in the directory. The following parameters are used when searching for the user’s entry:
user_dn
(string, optional) - Base DN under which to perform user search. Example:ou=Users,dc=example,dc=com
user_attr
(string, optional) - Attribute on user attribute entry matching the username passed when authenticating. Examples:cn
,uid
user_filter
(string, optional) - Go template used to construct a LDAP user search filter. The template can access the following context variables: [UserAttr, Username]. The default userfilter is({{.UserAttr}}={{.Username}})
or(userPrincipalName={{.Username}}@UPNDomain)
if the upndomain parameter is set. The user search filter can be used to restrict what user can attempt to log in. For example, to limit login to users that are not contractors, you could write(&(objectClass=user)({{.UserAttr}}={{.Username}})(!(employeeType=Contractor)))
Search parameters: group entries
Once a user has been authenticated, the LDAP auth method must know how to resolve which groups the user is a member of. The configuration for this can vary depending on your LDAP server and your directory schema.
There are two main strategies when resolving group membership - the first is searching for the authenticated user object and following an attribute to groups it is a member of. The second is to search for group objects of which the authenticated user is a member of. Both methods are supported.
group_filter
(string, optional) - Go template used when constructing the group membership query. The template can access the following context variables:[UserDN, Username]
. The default is(|(memberUid={{.Username}})(member={{.UserDN}})(uniqueMember={{.UserDN}}))
, which is compatible with several common directory schemas. To support nested group resolution for Active Directory, instead use the following query:(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={{.UserDN}}))
.group_dn
(string, required) - LDAP search base to use for group membership search. This can be the root containing either groups or users. Example:ou=Groups,dc=example,dc=com
.group_attr
(string, optional) - LDAP attribute to follow on objects returned by GroupFilter in order to enumerate user group membership. Examples: for GroupFilter queries returning group objects, use:cn
. For queries returning user objects, use:memberOf
. The default iscn
.
Create auth method for the provider
To set up a new auth method for your provider you need the appropriate connection, binding, and search parameters for your LDAP server.
You can create auth methods using the Admin Console, CLI, or Terraform.
The Boundary Admin Console provides a UI for creating and managing LDAP resources, including auth methods and managed groups.
Open the Admin Console UI by entering the Dev Controller URL of
http://localhost:9200
into a browser.
Enter the admin username admin
and password password
and click
Authenticate.
Start by navigating to the Auth Methods settings view using the menu on the left side of the Admin Console. Select New and click LDAP.
Fill out the form details using the settings gathered from the LDAP server.
Add the following:
- Name:
LDAP-test-auth
- Description:
Test server LDAP auth method
Connection
- Server address:
ldap://ldap.forumsys.com
Authenticated search
- Bind DN
cn=read-only-admin,dc=example,dc=com
- Bind Password
password
User entries
- User DN
dc=example,dc=com
- User Attribute
uid
Group entries
- Group DN
dc=example,dc=com
Toggle the switch beside Enable Groups.
Once the form is completed, click Save.
The new authentication method has now been created. To the right of the new auth method's details, notice the state is set to Inactive. Before you can use it, the new auth method must be switched to an active state.
Next we will review the available authentication states and activate the new LDAP auth method.
Authentication states
An LDAP auth method can be in one of several different states. The current state of an auth method affects how endpoints respond to requests and, in some cases, whether access to an endpoint requires authentication.
State change operations
- MakeInactive transitions an auth method from either the Active Private or the Active Public state into the Inactive state.
- MakePrivate transitions an auth method from either the Inactive or the Active Public state into the Active Private state. If transitioning from the Inactive state, the transition will only succeed if the configuration is valid.
- MakePublic transitions an auth method from either the Inactive or the Active Private state into the Active Public state. If transitioning from the Inactive state, the transition will only succeed if the configuration is valid.
Three different states exist for an authentication method:
inactive
users can not authenticate with inactive auth methods and the inactive auth methods are not listed for unauthenticated users.active-private
users can authenticate with active-private auth methods and active-private auth methods are not listed for unauthenticated users.active-public
users can authenticate active-public auth methods and active-public auth methods are listed for unauthenticated users.
If a change is made from active-public or active-private to inactive, all in-flight authentications will succeed unless the auth method’s configuration is modified while the request is in-flight.
Activate the LDAP auth method
Now that a new LDAP auth method has been created, you can activate it and assign it as the default login type for the global scope.
Auth methods can be activated using the CLI, Admin Console, or using Terraform.
Currently the login type is set as inactive, and won't allow authentication.
$ boundary authenticate ldap -auth-method-id $BOUNDARY_AUTH_METHOD_ID -login-name einstein
Please enter the password (it will be hidden):
Error from controller when performing authentication
Error information:
Kind: Unauthenticated
Message: Unable to authenticate.
Status: 401
context: Error from controller when performing authentication
You must set the new auth method to an active state before it will be allowed.
Under the settings for the new auth method, select Inactive from the menu in the upper-right side of the page and change its state by clicking Public.
The login type is now allowed.
Set LDAP as primary login
Global and organization scopes may have auth methods in Boundary, and each scope has one primary auth-method ID. Boundary automatically creates a user upon first successful authentication via the scope’s primary auth method, which will be used by scopes with only one auth method available.
When migrating the database, Boundary will produce a log of any auth methods which resulted in no primary auth method being set for the scope.
Set the new LDAP auth method as the primary auth method for the global scope.
Under the settings for the new auth method, select Manage from the menu in the upper-right side of the page.
A confirmation window will be displayed to inform you that new users that sign in via LDAP will automatically be added to the new auth method. Click OK to continue.
Authenticate using LDAP
With the LDAP auth method set to active-public, Boundary users can authenticate via the CLI, Admin Console, or Boundary Desktop app. Boundary administrators will usually follow a CLI or Admin Console workflow, while clients and end-users can use the CLI or the Boundary Desktop app.
The Boundary Desktop app is currently available for MacOS and Windows users.
Ensure that the latest version of the Boundary Desktop app is installed from the releases page before attempting to login with OIDC. The minimum version of the app allowing LDAP login is 1.7.0.
Launch the Boundary Desktop app and enter the Boundary Cluster URL.
Launch the Boundary Desktop app and enter
http://localhost:9200
as the Cluster URL, then click Submit.Select LDAP.
Enter the following LDAP credentials:
- Login Name:
einstein
- Password :
password
Click Sign in.
- Login Name:
The Boundary Desktop App provides a view of Targets and Sessions.
To continue learning about assigning LDAP accounts to a managed group to control permissions grants, ensure you can also log in using the Admin Console or CLI.
Define a managed group
In Boundary, the managed group resource represents a collection of accounts. A collection is automatically maintained by evaluating a filter defined in the managed group's configuration against the information returned by auth method's identity provider (IdP).
You can associate accounts with zero or more managed groups within the same auth method, and you can associate grants with a managed group when they are used as a principal within a role.
Membership in a managed group is defined when an LDAP auth method is used for authentication. Membership is determined by matching the LDAP group names against an LDAP account's associated groups, and every authentication updates the group membership comparison.
According to the Online LDAP Test Server, two groups exist for testing LDAP:
The scientists
group contains the following users:
Verify LDAP account details
Earlier, you authenticated with the einstein
user account. First, check that
this account is associated with the LDAP auth method.
Log back into Boundary as the admin user.
Select the einstein user menu in the top-right corner of the page and click Sign Out.
From the Sign In page, select the password auth method.
Enter the admin user account details, then click Sign In.
Next, select the new auth method called LDAP-test-auth.
Navigate to the Auth Methods page in the Global scope. Select the
LDAP-test-auth
auth method.Select the Accounts tab.
Notice the new account with the following details:
- Dn:
uid=einstein,dc=example,dc=com
- Group Names:
Scientists
- Dn:
This information is populated by the LDAP server for any accounts that have authenticated using LDAP.
Create the managed group
We know that the einstein
user belongs to the Scientists
LDAP group.
Create a new Boundary managed group, specifying the Scientists
group name to
define the managed group membership.
Navigate to the Auth Methods page in the Global scope. Select the
LDAP-test-auth
auth method.Select the Managed Groups tab.
Click Create Managed Group.
Fill in the form details with the following:
- Name:
science-group
- Group Names:
Scientists
Click Add, then Save.
- Name:
With the managed group configured, the next time our user authenticates it will belong to the managed group.
Create a role
With the managed group created and automatically managing group membership, the next step is to apply permissions to the group by creating a role.
After you create a role, the managed group is added as a role principal and grants are assigned to the role. To learn more about group principals, check out the Manage Users and Groups tutorial. To understand how permissions are granted, check out the Manage Roles tutorial.
First, create a new role in the global
scope.
Navigate to the Roles page in the Global scope.
Click New Role. Fill in the following role details:
- Name:
read-roles
Click Save.
- Name:
On the Settings page, Click Edit Form. Select a scope underneath Global, such as Generated org scope, quick-start-org, or any other org you have created.
Click Save.
Assign grants to roles
Use the grant ids=*;type=role;actions=list,read
, which selects any role ID
and allows you to perform list and read actions.
Include the grant ids=*;type=scope;actions=list,read
, which selects any scope
and allows you to perform list and read actions. To learn more about
setting permission grants, check out the Permission Grant Formats
documentation.
Select the Grants tab.
In the New Grant field, enter the following:
Click Add.
In the New Grant field, enter the following:
Click Add, then Save.
Add managed group as a role principle
Next, add the new managed group as a role principal so the group will inherit any grants associated with the role.
From the
read-roles
role page, select the Principals tab.Add the managed group as a role principal.
Click + Add Principals.
Check the box beside the
science-group
managed group.Click the Add Principals button.
With the grants in place the LDAP user should automatically be allowed to list and read roles upon authentication.
Test managed group membership
Test that the LDAP user belongs to the managed group, and has inherited the defined role principals.
Log back in using the LDAP auth method.
Select the admin user menu in the top-right corner of the page and click Sign Out.
Authenticate using the new auth method.
Select the auth method called LDAP-test-auth.
Enter the following LDAP credentials:
- Login Name:
einstein
- Password :
password
Click Sign In.
- Login Name:
After successful authentication you are automatically redirected to the Admin Console. Select global scope.
Check that you are now able to view the Roles page.
You have now finished configuring an LDAP auth method and a role with an associated managed group principal.
Cleanup and teardown
Stop Boundary dev mode
Locate the shell where
boundary dev
was run and enterctrl+c
to stop dev mode.^C==> Boundary dev environment shutdown triggered [INFO] worker: status ticking shutting down [INFO] controller: terminating completed sessions ticking shutting down [INFO] controller: closing expired pending tokens ticking shutting down [INFO] controller: status ticking shutting down [INFO] controller: recovery nonce ticking shutting down
If following the Active Directory workflow, clean up Vagrant by destroying the Windows virtual machine.
$ vagrant destroy
Next steps
This tutorial demonstrated the steps to add an LDAP authentication method and define role principals using a managed group.
You set up an LDAP auth method with Boundary, and verified that you can authenticate using an LDAP account. After that, you created a managed group that determined membership based on the LDAP groups associated with user accounts. Finally, you verified that users belonging the managed group inherited grants assigned by a role principal.
To learn more about the basics of managing user accounts, check out the Manage Users and Groups and Manage Roles tutorials.