Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions docs/modules/ROOT/pages/secret-backends.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,78 @@ spring.cloud.vault:

See also: https://www.vaultproject.io/docs/secrets/rabbitmq/index.html[Vault Documentation: Setting up RabbitMQ with Vault]

[[vault.config.backends.ldap]]
== LDAP

Spring Cloud Vault can obtain credentials for LDAP.

The LDAP integration requires the `spring-cloud-vault-config-ldap`
dependency.

.pom.xml
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
----
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-vault-config-ldap</artifactId>
<version>{project-version}</version>
</dependency>
</dependencies>
----

The integration can be enabled by setting
`spring.cloud.vault.ldap.enabled=true` (default `false`) and providing the role name with `spring.cloud.vault.ldap.role=…`.

Vault's LDAP secret engine supports both dynamic and static roles:

* **Dynamic roles** generate temporary credentials on-demand
* **Static roles** manage the rotation of existing LDAP user credentials

To use a static role, set `spring.cloud.vault.ldap.static-role=true` (default `false`).

Username and password are stored in `spring.ldap.username`
and `spring.ldap.password` so applications using Spring LDAP will pick up the generated credentials without further configuration.
You can configure the property names by setting `spring.cloud.vault.ldap.username-property` and
`spring.cloud.vault.ldap.password-property`.

Example: Dynamic Role

[source,yaml]
----
spring.cloud.vault:
ldap:
enabled: true
role: my-dynamic-role
static-role: false
backend: ldap
username-property: spring.ldap.username
password-property: spring.ldap.password
----

Example: Static Role

[source,yaml]
----
spring.cloud.vault:
ldap:
enabled: true
role: my-static-role
static-role: true
backend: ldap
username-property: spring.ldap.username
password-property: spring.ldap.password
----

* `enabled` setting this value to `true` enables the LDAP backend config usage
* `role` sets the role name of the LDAP role definition
* `static-role` setting this value to `true` uses static role credentials instead of dynamic
* `backend` sets the path of the LDAP mount to use
* `username-property` sets the property name in which the LDAP username is stored
* `password-property` sets the property name in which the LDAP password is stored

See also: https://www.vaultproject.io/docs/secrets/ldap/index.html[Vault Documentation: Setting up LDAP with Vault]

[[vault.config.backends.aws]]
== AWS

Expand Down
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
<module>spring-cloud-vault-config-consul</module>
<module>spring-cloud-vault-config-rabbitmq</module>
<module>spring-cloud-vault-config-aws</module>
<module>spring-cloud-vault-config-ldap</module>
<module>spring-cloud-starter-vault-config</module>
<module>docs</module>
</modules>
Expand Down
60 changes: 60 additions & 0 deletions spring-cloud-vault-config-ldap/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-vault-parent</artifactId>
<version>5.0.1-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>

<artifactId>spring-cloud-vault-config-ldap</artifactId>
<name>Spring Cloud Vault Config LDAP support</name>
<description>Spring Cloud Vault Config LDAP support</description>

<dependencies>
<!-- Compile -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-vault-config</artifactId>
</dependency>

<!-- Annotation processing -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure-processor</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>

<!-- Test -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-vault-config</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.unboundid</groupId>
<artifactId>unboundid-ldapsdk</artifactId>
<scope>test</scope>
</dependency>

</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
* Copyright 2016-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.cloud.vault.config.ldap;

import java.util.HashMap;
import java.util.Map;

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.vault.config.PropertyNameTransformer;
import org.springframework.cloud.vault.config.SecretBackendMetadata;
import org.springframework.cloud.vault.config.SecretBackendMetadataFactory;
import org.springframework.cloud.vault.config.VaultSecretBackendDescriptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.util.Assert;
import org.springframework.vault.core.util.PropertyTransformer;

/**
* Bootstrap configuration providing support for the LDAP secret engine.
*
* @author Drew Mullen
* @since 5.0.1
*/
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(VaultLdapProperties.class)
@Order(Ordered.LOWEST_PRECEDENCE - 15)
public class VaultConfigLdapBootstrapConfiguration {

@Bean
@ConditionalOnMissingBean
public LdapSecretBackendMetadataFactory ldapSecretBackendMetadataFactory() {
return new LdapSecretBackendMetadataFactory();
}

/**
* {@link SecretBackendMetadataFactory} for LDAP integration using
* {@link VaultLdapProperties}.
*/
public static class LdapSecretBackendMetadataFactory implements SecretBackendMetadataFactory<VaultLdapProperties> {

/**
* Creates a {@link SecretBackendMetadata} for the LDAP secret engine using
* {@link VaultLdapProperties}. This accessor transforms Vault's username/password
* property names to names provided with
* {@link VaultLdapProperties#getUsernameProperty()} and
* {@link VaultLdapProperties#getPasswordProperty()}.
* @param properties must not be {@literal null}.
* @return the {@link SecretBackendMetadata}
*/
static SecretBackendMetadata forLdap(final VaultLdapProperties properties) {

Assert.notNull(properties, "VaultLdapProperties must not be null");

PropertyNameTransformer transformer = new PropertyNameTransformer();
transformer.addKeyTransformation("username", properties.getUsernameProperty());
transformer.addKeyTransformation("password", properties.getPasswordProperty());

return new SecretBackendMetadata() {

private final String credPath = properties.isStaticRole() ? "static-cred" : "creds";

@Override
public String getName() {
return String.format("%s with Role %s", properties.getBackend(), properties.getRole());
}

@Override
public String getPath() {
return String.format("%s/%s/%s", properties.getBackend(), this.credPath, properties.getRole());
}

@Override
public PropertyTransformer getPropertyTransformer() {
return transformer;
}

@Override
public Map<String, String> getVariables() {

Map<String, String> variables = new HashMap<>();
variables.put("backend", properties.getBackend());
variables.put("key", String.format("%s/%s", this.credPath, properties.getRole()));
return variables;
}
};
}

@Override
public SecretBackendMetadata createMetadata(VaultLdapProperties backendDescriptor) {
return forLdap(backendDescriptor);
}

@Override
public boolean supports(VaultSecretBackendDescriptor backendDescriptor) {
return backendDescriptor instanceof VaultLdapProperties;
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
* Copyright 2016-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.cloud.vault.config.ldap;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.vault.config.VaultSecretBackendDescriptor;
import org.springframework.lang.Nullable;

/**
* Configuration properties for Vault using the LDAP secret engine.
*
* @author Drew Mullen
* @since 5.0.1
*/
@ConfigurationProperties("spring.cloud.vault.ldap")
public class VaultLdapProperties implements VaultSecretBackendDescriptor {

/**
* Enable LDAP secret engine usage.
*/
private boolean enabled = false;

/**
* Role name for credentials.
*/
@Nullable
private String role;

/**
* Enable static role usage.
*/
private boolean staticRole = false;

/**
* LDAP secret engine backend path.
*/
private String backend = "ldap";

/**
* Target property for the obtained username.
*/
private String usernameProperty = "spring.ldap.username";

/**
* Target property for the obtained password.
*/
private String passwordProperty = "spring.ldap.password";

@Override
public boolean isEnabled() {
return this.enabled;
}

public void setEnabled(boolean enabled) {
this.enabled = enabled;
}

@Nullable
public String getRole() {
return this.role;
}

public void setRole(@Nullable String role) {
this.role = role;
}

public boolean isStaticRole() {
return this.staticRole;
}

public void setStaticRole(boolean staticRole) {
this.staticRole = staticRole;
}

@Override
public String getBackend() {
return this.backend;
}

public void setBackend(String backend) {
this.backend = backend;
}

public String getUsernameProperty() {
return this.usernameProperty;
}

public void setUsernameProperty(String usernameProperty) {
this.usernameProperty = usernameProperty;
}

public String getPasswordProperty() {
return this.passwordProperty;
}

public void setPasswordProperty(String passwordProperty) {
this.passwordProperty = passwordProperty;
}

}
Loading
Loading