Secure access to AD-joined Windows with Boundary just-in-time dynamic credentials

Ravi Panchal
HashiCorp Solutions Engineering Blog
14 min readApr 8, 2024

--

This document assumes a foundational understanding of HCP Boundary and HCP Vault. For additional details on each product, kindly refer to the Boundary and Vault pages, respectively.

Background

In today’s digital landscape, remote access to environments has become increasingly essential for organizations worldwide. With the widespread adoption of remote work policies, IT operators and vendors often need to access systems and infrastructure remotely to perform their duties. The shift towards cloud computing has also contributed to the increase in remote access. With infrastructure and services hosted in the cloud, IT operators and vendors must access these resources remotely to manage and maintain them.

Challenge

While remote access offers flexibility and convenience, it also introduces security challenges:

  1. Authentication and authorization: Verifying the identity of remote users and ensuring they have the appropriate permissions to access remote hosts securely.
  2. Secrets managements: Long-lived secrets often lack regular rotation mechanisms, increasing the likelihood of exposure and compromise. Without periodic rotation, compromised secrets can remain valid for extended periods, amplifying the risk of unauthorized access. Managing static and long-lived secrets manually can be cumbersome and error-prone. It requires tracking and updating of credentials across various systems, leading to operational inefficiencies and potential security lapses.
  3. Data encryption: Protecting data transmitted between remote users and host systems to prevent interception and unauthorized access.
  4. Auditability and compliance: Maintaining visibility into remote access activities and ensuring compliance with regulatory requirements and industry standards.

This document seeks to outline the operational and security advantages that organizations can gain by utilizing HCP Boundary and HCP Vault to secure remote desktop protocol (RDP) access to Windows machines joined to Active Directory (AD). This integration provides authenticated and authorized users with dynamic, just-in-time, short-lived AD credentials for secure RDP access to Windows machines.

Solution overview

The solution leverages HashiCorp Boundary and Vault to secure user access to remote targets with time-bound dynamic credentials.

  • HCP Boundary controller authenticates users and grants access to target systems based on role-based access control policies.
  • HCP Vault generates time-bound dynamic credentials for authorized users to access the remote target system.
  • HCP Boundary worker functions as an ingress worker that is accessible by user.
  • The self-managed Boundary worker resides within a private network and functions as an egress worker capable of accessing the target. It establishes a reverse proxy connection to the HCP worker.
  • The arrows in the diagram illustrate the direction in which network communication is initiated. Users initiate connections to the HCP worker to access the target system. Inbound connection requests from users are directed to the self-managed egress worker via reverse proxy connection with the HCP Boundary worker. The self-managed egress worker establishes a connection to the remote target system.

This setup addresses the challenge faced by organizations that prohibit inbound network traffic into private networks.

Deployed architecture

The diagram below illustrates my configuration aimed at showcasing the functionalities of Boundary and Vault for securing RDP access using ephemeral Active Directory credentials.

The setup utilizes fully-managed, cloud-based HCP Boundary and HCP Vault, enabling quick deployment. The target infrastructure resides in AWS within a single region, featuring a single VPC and a single public and private subnet.

Network security

The Windows domain controller and the target Windows machine, which we aim to access remotely, are hosted in the private subnet. No inbound connections are allowed into the private subnet.

Boundary enables secure connections to private endpoints via self-managed Boundary workers.

  • The Boundary worker is deployed in the same private subnet, acting as a TCP proxy to both the Windows target in the private subnet and HCP Vault’s private endpoint (via VPC peering).
  • The Boundary worker is linked to the upstream HCP Boundary workers through a reverse-proxy connection.
  • The security group assigned to a Windows target machine allows inbound RDP/TCP access solely from the self-managed Boundary worker ensuring that access is restricted to only authorized connections originating from the Boundary worker.

Boundary also provides the flexibility to deploy multiple self-managed workers, which can be chained together to enable multi-hop sessions. This capability is particularly valuable for organizations having complex network topologies requiring inbound traffic to route through multiple network enclaves in order to reach the target system.

Code repository

All HashiCorp products are designed with an API-first approach and also come with Terraform providers, enabling automation workflows and streamlined resource provisioning. Using Terraform, the resources required for a Boundary deployment can be easily set up and scaled. The environment described above can be entirely deployed using the Terraform code provided in this repo.

Please note the code in this repository is not reflective of HashiCorp’s recommended approach for setting up a production-like environment. Rather, it aims to demonstrate the workflow facilitated by HCP Boundary and HCP Vault without imposing the complexities of configuring production-ready secured infrastructure.

Securing remote access using dynamic AD credentials

The integration of Boundary and Vault enables the generation of dynamic AD credentials. Vault’s LDAP secret engine facilitates the dynamic creation of these credentials, supporting integration with implementations of the LDAP v3 protocol such as OpenLDAP and AD. The traffic flow for a user attempting to access a remote Windows host using dynamic AD credentials follows the diagram below:

The process begins when a user needs to connect to a remote Windows host. It’s assumed that the user has already authenticated with Boundary and has been granted authorization to access the target machine. In order to keep it simple, our simulated environment is configured with a password-based authentication method. Boundary offers the flexibility to also integrate LDAP or OIDC-based identity providers for user authentication and authorization.

  1. When authenticated and authorized users request access to the Windows target, the Boundary Controller triggers a request to HCP Vault to generate dynamic AD credentials. The connection to the HCP Vault private endpoint is facilitated by the self-managed Boundary worker over VPC-peered private network.
  2. Subsequently, Vault’s LDAP secrets engine communicates with the AD in the Windows Domain Controller to generate the dynamic AD credentials. Once again, the connection to the AD server occurs over the VPC-peered private network.
  3. The Boundary Controller retrieves the AD credentials from Vault and presents them to the user. Despite being presented to the end user, it’s important to emphasize that these credentials are ephemeral, have a short time-to-live (TTL), and do not need to be stored on local machines. Vault associates each dynamic secret with a lease and automatically destroys the credentials when the lease expires.
  4. Finally, the user utilizes the dynamic, time-bound AD credentials to establish a just-in-time secure connection to the remote Windows target via the self-managed Boundary worker.

Role-based access control

Boundary, together with Vault, facilitates fine-grained access control to remote hosts. In our environment, we have configured two users, admin and support, both of whom require remote access to the same Windows host.

The dynamic AD credentials presented to these users grant different privileges based on their roles. For example, in our scenario, the supportuser does not have access to the Windows Control Panel, whereas the adminuser is permitted access. This role-based access control ensures that users only have access to the resources and functionalities that are relevant to their roles and responsibilities.

Deploying environment with Terraform

As previously mentioned, our environment is fully configured using Terraform. In our scenario, we have utilized Terraform providers for HCP, Boundary, Vault, and AWS to automate the provisioning of HCP Boundary, HCP Vault, target infrastructure in AWS (self-managed Boundary worker, Windows Domain Controller server, Windows client machine joined to domain) and other necessary resources.

We will not cover the configuration of AWS networking, security groups, and EC2 resources as these aspects are typically known to most users and are already documented in my Github repo. Instead, we’ll focus on configuring HCP Boundary and HCP Vault resources specific to securing RDP access using role-based dynamic AD credentials.

Creating HCP Boundary and HCP Vault Clusters

The HashiCorp Cloud Platform (HCP) simplifies the deployment of HashiCorp products with options for one-click deployment or using Terraform. To begin, you’ll need an HCP account, which can be set up easily. Below is the Terraform code to create HCP Boundary.

resource "hcp_boundary_cluster" "this" {
cluster_id = var.hcp_boundary_cluster_id
username = var.hcp_boundary_admin
password = var.hcp_boundary_password
tier = var.hcp_boundary_tier
}

HCP Vault requires deploying a HashiCorp Virtual Network (HVN) first, within which the Vault cluster will be hosted . HVN also enables establishing connections to resources within your cloud infrastructure via VPC peering or transit gateways. The example below shows Terraform configuration to create HVN and establish peering connection with the AWS VPC.

resource "hcp_hvn" "this" {
hvn_id = var.hvn_id
cloud_provider = "aws"
region = var.region
}

data "aws_arn" "peer" {
arn = module.vpc.vpc_arn
}

resource "hcp_aws_network_peering" "peer" {
hvn_id = var.hvn.hvn_id
peering_id = "${var.deployment_id}-peering"
peer_vpc_id = module.vpc.vpc_id
peer_account_id = module.vpc.vpc_owner_id
peer_vpc_region = data.aws_arn.peer.region
}

resource "hcp_hvn_route" "peer_route" {
hvn_link = var.hvn.self_link
hvn_route_id = "${var.deployment_id}-route"
destination_cidr = var.vpc_cidr
target_link = hcp_aws_network_peering.peer.self_link
}

resource "aws_vpc_peering_connection_accepter" "peer" {
vpc_peering_connection_id = hcp_aws_network_peering.peer.provider_peering_id
auto_accept = true
}

HCP Vault cluster can be created once HVN is deployed.

resource "hcp_vault_cluster" "this" {
hvn_id = hcp_hvn.this.hvn_id
cluster_id = var.hcp_vault_cluster_id
tier = var.hcp_vault_tier
public_endpoint = true
}

resource "hcp_vault_cluster_admin_token" "this" {
cluster_id = hcp_vault_cluster.this.cluster_id
}

Configuring Vault with LDAP secrets engine

Vault offers support for dynamic secrets across a diverse range of systems and can be readily extended with plugins. In our setup, Vault is configured with an LDAP secrets engine specifically for managing dynamic AD credentials. We have set up two LDAP secret backend roles to generate role-based dynamic AD credentials, each associated with a different set of permissions.

resource "vault_ldap_secret_backend" "config" {
path = "ldap"
binddn = "CN=Administrator,CN=Users,DC=${split(".", var.ad_domain)[0]},DC=${split(".", var.ad_domain)[1]}"
bindpass = rsadecrypt(aws_instance.windows.password_data, tls_private_key.ssh.private_key_pem)
url = "ldaps://${aws_instance.windows.private_ip}"
insecure_tls = "true"
certificate = tls_self_signed_cert.ca_cert.cert_pem
schema = "ad"
}

#Vault dynamic role to create AD credentials for "admin" role
#User account management is provided through LDIF entries
resource "vault_ldap_secret_backend_dynamic_role" "privileged" {
mount = vault_ldap_secret_backend.config.path
creation_ldif = templatefile("${path.module}/config/creation.tpl.ldif", {
domain_prefix = split(".", var.ad_domain)[0]
domain_suffix = split(".", var.ad_domain)[1]
})
deletion_ldif = templatefile("${path.module}/config/deletion.tpl.ldif", {
domain_prefix = split(".", var.ad_domain)[0]
domain_suffix = split(".", var.ad_domain)[1]
})
username_template = "v_{{.RoleName}}_{{random 5}}"
role_name = local.vault_ldap_privileged_rolename
default_ttl = 600
max_ttl = 1200
}

#Vault dynamic role to create AD credentials for "support" role
resource "vault_ldap_secret_backend_dynamic_role" "support" {
mount = vault_ldap_secret_backend.config.path
creation_ldif = templatefile("${path.module}/config/creation_restricted.tpl.ldif", {
domain_prefix = split(".", var.ad_domain)[0]
domain_suffix = split(".", var.ad_domain)[1]
ad_group_name = local.ad_group_name
})
deletion_ldif = templatefile("${path.module}/config/deletion.tpl.ldif", {
domain_prefix = split(".", var.ad_domain)[0]
domain_suffix = split(".", var.ad_domain)[1]
})
username_template = "v_{{.RoleName}}_{{random 5}}"
role_name = local.vault_ldap_support_rolename
default_ttl = 600
max_ttl = 1200
}

Integrating HCP Boundary with HCP Vault

The native integration between Boundary and Vault enables Boundary to provide authorized users with just-in-time, dynamic credentials for accessing remote targets. Below is an example Terraform code illustrating the configuration of a Vault credential store in Boundary:

resource "boundary_credential_store_vault" "cred_store" {
name = "vault-cred-store"
description = "Vault credential store!"
address = var.vault_cluster_url
token = vault_token.boundary.client_token
scope_id = boundary_scope.project.id
namespace = local.vault_namespace
worker_filter = "\"egress\" in \"/tags/type\""
}

resource "boundary_credential_library_vault" "windows_restricted" {
name = "windows-dynamic-creds-restricted"
description = "Dynamic AD user creds for the support role"
credential_store_id = boundary_credential_store_vault.cred_store.id
path = "ldap/creds/${local.vault_ldap_support_rolename}"
http_method = "GET"
credential_type = "username_password"
}

resource "boundary_credential_library_vault" "windows_privileged" {
name = "windows-dynamic-creds-privileged"
description = "Dynamic AD user creds for the admin role"
credential_store_id = boundary_credential_store_vault.cred_store.id
path = "ldap/creds/${local.vault_ldap_privileged_rolename}"
http_method = "GET"
credential_type = "username_password"
}

Configuring Boundary target

A Boundary target is a logical resource that combines the remote host endpoint (i.e. IP address, port, and protocol) and the credentials required to access the host. The access to Boundary targets is governed by fine-grained role-based access permissions.

In our environment, we have set up two Boundary targets, both pointing to the same remote Windows host but associated with different sets of credentials. Below is the table highlighting the Boundary targets configured, along with their associated credentials and the users allowed to access these targets:

This configuration ensures that users are granted access to resources based on their roles and permissions, promoting security and adherence to organizational policies.

Boundary provides flexibility by allowing users to directly specify the IP address and port number as part of the target configuration or leverage the dynamic host catalog feature for automated discovery of target hosts and services. The dynamic host catalog eliminates the need for manual configuration of targets, particularly for dynamic, cloud-based infrastructure.

Below is the Terraform code that configures the two Boundary targets directly with the remote private IP address and RDP port, given that we only have a single Windows host in our environment.

resource "boundary_target" "windows_privileged" {
type = "tcp"
name = "windows_privileged"
description = "Windows host access using dynamic creds for the default user role. This role should have access to Windows Control Panel"
scope_id = boundary_scope.project.id
session_connection_limit = -1
default_port = 3389
egress_worker_filter = "\"egress\" in \"/tags/type\""
address = aws_instance.windows_client.private_ip

# Dynamic AD credentials to be generated for each user session
brokered_credential_source_ids = [boundary_credential_library_vault.windows_privileged.id]
}

resource "boundary_target" "windows_restricted" {
type = "tcp"
name = "windows_restricted"
description = "Windows host access using dynamic creds for the support role. This role should not have access to Windows Control Panel"
scope_id = boundary_scope.project.id
session_connection_limit = -1
default_port = 3389
egress_worker_filter = "\"egress\" in \"/tags/type\""
address = aws_instance.windows_client.private_ip

# Dynamic AD credentials to be generated for each user session
brokered_credential_source_ids = [boundary_credential_library_vault.windows_restricted.id]
}

Testing the workflow

All the configurations up to this point were aimed at enabling authenticated and authorized users to securely connect to remote targets. Finally, we can now establish a secure connection to the remote private Windows host using dynamic AD credentials. We will test the workflow with the two users that were configured earlier to demonstrate the role-based remote access workflow.

Testing the workflow for “support” user

We will first test the workflow as the support user.

Login to Boundary Desktop client
We will log in to the Boundary Desktop client using the HCP Boundary cluster URL, which can be retrieved from the terraform output. Log in as the support user and verify the Boundary targets accessible by this user. The password for this user can be retrieved from the terraform output. As per RBAC policies configured, this user has access to the windows_restrictedtarget only.

Retrieve dynamic AD credentials
Next, click on the “Connect” button to retrieve the time-bound, dynamic AD credentials for accessing the windows_restricted target. At this stage, the HCP Boundary Controller will request HCP Vault, via the self-managed Boundary worker, to generate the credentials. Please note that the username part of the dynamic credentials starts with v_restricted, as per the Vault dynamic secret backend role configured for this target.

Connect to the remote target
We now have all the details as shown below to connect to the remote Windows host as the support user. Please note that the destination address is 127.0.0.1:57136, as the Boundary client establishes a secure connection from the user’s local machine to the Boundary worker. Additionally, the Windows domain name in my terraform configuration is set as hashidemo.com. The domain name is also available as part of the distinguished_names field in the dynamic credentials output as shown above.

Destination Address: 127.0.0.1:57136
Username: hashidemo.com\v_restricted_<random>
Password: <dynamic_user_password>

Finally, we will configure the Microsoft Remote Desktop client with the details provided from the Boundary Desktop output to connect to the remote target.

Once logged in to the Windows machine, you can open the command prompt and run whoami to confirm that the logged-in user is indeed the dynamically generated user account.

Finally, let’s verify if the support user has access to the Control Panel. As expected, the dynamic AD credential presented to the support user does not allow access to the Windows Control Panel.

Now, let’s quickly test the same workflow for the admin user.

Testing the workflow for “admin” user

Login to Boundary Desktop client
This time, we will log in to the Boundary Desktop client as the admin user using the HCP Boundary admin credentials that we configured for creating HCP Boundary cluster. As expected, the admin user should have access to both the Boundary targets.

Retrieve dynamic AD credentials
Next, click on the “Connect” button to retrieve the time-bound, dynamic AD credentials for accessing the windows_privileged target. Please note that the username part of the dynamic credentials starts with v_privileged, as per the Vault dynamic secret backend role configured for this target.

Connect to the remote target
Let us now connect to the remote Windows host as an admin user using the dynamic credentials.

Once logged in to the Windows machine, run whoami to confirm that the logged-in user is using the dynamically generated privileged account credentials.

Finally, let’s verify that the admin user has access to the Windows Control Panel, as expected.

The integration of HashiCorp Boundary and Vault offers several operational and security benefits.

Operational and security benefits

  • Dynamic credential provisioning: With Boundary’s integration with Vault, organizations can automate the provisioning of dynamic Windows AD credentials. This eliminates the need for manual credential management, streamlining the process and reducing administrative overhead.
  • Just-in-time access: Boundary provides users with just-in-time access to Windows machines, granting temporary credentials only when needed. This approach minimizes the exposure window and reduces the risk of unauthorized access.
  • Short-lived credentials: Leveraging Vault’s capabilities, Boundary issues short-lived credentials for RDP access to Windows machines. These credentials expire after a predefined period, reducing the risk of credential theft and misuse. Short-lived credentials also minimize the attack surface. Attackers have limited time to exploit compromised credentials, mitigating the risk of lateral movement and data breaches.
  • Role-based access control (RBAC): Fine-grained access policies allow organizations to define granular access controls based on user roles and permissions. This enables organizations to enforce least privilege principles and restrict access to only those resources and actions necessary for users to perform their jobs.
  • Improved compliance: The use of dynamic, short-lived credentials aligns with regulatory compliance requirements, such as those outlined in PCI DSS and GDPR. By enforcing stricter access controls and reducing the exposure window, organizations can demonstrate compliance with data protection regulations.
  • Auditing and accountability: Boundary and Vault provide comprehensive auditing and logging capabilities, allowing organizations to track and monitor RDP access to Windows machines. This enables real-time visibility into user activities, facilitating incident response and forensic analysis.

Summary

Traditional methods relying on static credentials pose security risks and operational inefficiencies. We have seen that the integration of HCP Boundary and HCP Vault offers a robust solution for organizations seeking to enhance operational efficiency and bolster security measures for remote RDP access to AD-joined Windows machines. By leveraging dynamic, just-in-time credentials, organizations can mitigate security risks associated with static credentials while streamlining administrative tasks and ensuring compliance with regulatory requirements.

References

--

--