Polishing.
Rename vault-role configuration property to role for a consistent naming. Introduce path and server-name config properties. Eagerly fetch AWS credentials to fail early if credentials cannot be obtained. Fix properties in reference docs. Javadoc, reference docs wording. Add author tags. Re-generate readme. Original pull request: gh-175. See gh-134.
This commit is contained in:
12
README.adoc
12
README.adoc
@@ -11,8 +11,8 @@ Spring Cloud Vault Config provides client-side support for externalized configur
|
||||
|
||||
Specifically for Spring applications:
|
||||
|
||||
* Retrieve secrets from Vault and initialize Spring Environment with remote property sources
|
||||
* Obtain {docs}#vault.config.backends.generic[secrets] secured with SSL
|
||||
* Retrieve secrets from Vault and initialize Spring Environment with remote property sources.
|
||||
* Obtain {docs}#vault.config.backends.generic[secrets] secured with SSL.
|
||||
* Generate credentials for
|
||||
{docs}#vault.config.backends.mysql[MySQL],
|
||||
{docs}#vault.config.backends.postgresql[PostgreSQL],
|
||||
@@ -24,9 +24,11 @@ Specifically for Spring applications:
|
||||
{docs}#vault.config.authentication.appid[AppId],
|
||||
{docs}#vault.config.authentication.approle[AppRole],
|
||||
{docs}#vault.config.authentication.clientcert[Client Certificate],
|
||||
{docs}#vault.config.authentication.cubbyhole[Cubbyhole], and
|
||||
{docs}#vault.config.authentication.awsec2[AWS-EC2] authentication
|
||||
* Bootstrap application context: a parent context for the main application that can be trained to do anything
|
||||
{docs}#vault.config.authentication.cubbyhole[Cubbyhole],
|
||||
{docs}#vault.config.authentication.awsec2[AWS-EC2] authentication, and
|
||||
{docs}#vault.config.authentication.awsiam[AWS-IAM] authentication.
|
||||
|
||||
* Bootstrap application context: a parent context for the main application that can be trained to do anything.
|
||||
|
||||
|
||||
== Quick Start
|
||||
|
||||
@@ -8,8 +8,8 @@ include::intro.adoc[]
|
||||
|
||||
Specifically for Spring applications:
|
||||
|
||||
* Retrieve secrets from Vault and initialize Spring Environment with remote property sources
|
||||
* Obtain {docs}#vault.config.backends.generic[secrets] secured with SSL
|
||||
* Retrieve secrets from Vault and initialize Spring Environment with remote property sources.
|
||||
* Obtain {docs}#vault.config.backends.generic[secrets] secured with SSL.
|
||||
* Generate credentials for
|
||||
{docs}#vault.config.backends.mysql[MySQL],
|
||||
{docs}#vault.config.backends.postgresql[PostgreSQL],
|
||||
@@ -23,9 +23,9 @@ Specifically for Spring applications:
|
||||
{docs}#vault.config.authentication.clientcert[Client Certificate],
|
||||
{docs}#vault.config.authentication.cubbyhole[Cubbyhole],
|
||||
{docs}#vault.config.authentication.awsec2[AWS-EC2] authentication, and
|
||||
{docs}#vault.config.authentication.awsiam[AWS-IAM] authentication
|
||||
{docs}#vault.config.authentication.awsiam[AWS-IAM] authentication.
|
||||
|
||||
* Bootstrap application context: a parent context for the main application that can be trained to do anything
|
||||
* Bootstrap application context: a parent context for the main application that can be trained to do anything.
|
||||
|
||||
|
||||
== Quick Start
|
||||
|
||||
@@ -273,12 +273,12 @@ spring.cloud.vault:
|
||||
|
||||
* `authentication` setting this value to `AWS_EC2` selects the AWS EC2
|
||||
authentication method
|
||||
* `role` sets the role name of the AWS EC2 role definition
|
||||
* `role` sets the name of the role against which the login is being attempted.
|
||||
* `aws-ec2-path` sets the path of the AWS EC2 mount to use
|
||||
* `identity-document` sets URL of the PKCS#7 AWS EC2 identity document
|
||||
* `nonce` used for AWS-EC2 authentication. An empty nonce defaults to nonce generation
|
||||
|
||||
See also: https://www.vaultproject.io/docs/auth/aws-ec2.html[Vault Documentation: Using the aws-ec2 auth backend]
|
||||
See also: https://www.vaultproject.io/docs/auth/aws.html[Vault Documentation: Using the aws auth backend]
|
||||
|
||||
[[vault.config.authentication.awsiam]]
|
||||
=== AWS-IAM authentication
|
||||
@@ -293,14 +293,15 @@ Instead, it treats AWS as a Trusted Third Party and uses the
|
||||
4 pieces of information signed by the caller with their IAM credentials
|
||||
to verify that the caller is indeed using that IAM role.
|
||||
|
||||
The current IAM role the application is running in is automatically calculated. If you are
|
||||
running your application on AWS ECS then the application will use the IAM role assigned
|
||||
to the ECS task of the running container. If you are running your application naked on top of
|
||||
an EC2 instance then the IAM role used will be the one assigned to the EC2 instance.
|
||||
The current IAM role the application is running in is automatically calculated.
|
||||
If you are running your application on AWS ECS then the application
|
||||
will use the IAM role assigned to the ECS task of the running container.
|
||||
If you are running your application naked on top of an EC2 instance then
|
||||
the IAM role used will be the one assigned to the EC2 instance.
|
||||
|
||||
When using the AWS-IAM authentication you must create a role in vault and assign it to your IAM
|
||||
role. If no vault-role value is supplied in the configuration (as below) then the friendly name
|
||||
of the current IAM role will be used as the vault role.
|
||||
When using the AWS-IAM authentication you must create a role in Vault
|
||||
and assign it to your IAM role. An empty `role` defaults to
|
||||
the friendly name the current IAM role.
|
||||
|
||||
.bootstrap.yml with required AWS-IAM Authentication properties
|
||||
====
|
||||
@@ -311,21 +312,27 @@ spring.cloud.vault:
|
||||
----
|
||||
====
|
||||
|
||||
|
||||
.bootstrap.yml with all AWS-IAM Authentication properties
|
||||
====
|
||||
[source,yaml]
|
||||
----
|
||||
spring.cloud.vault:
|
||||
authentication: AWS_IAM
|
||||
vault-role: my-dev-role
|
||||
aws-iam:
|
||||
role: my-dev-role
|
||||
aws-path: aws
|
||||
server-id: some.server.name
|
||||
----
|
||||
====
|
||||
|
||||
* `vault-role` sets the vault-role that is to be logged in to, this should be bound to your IAM role. If one is not
|
||||
supplied then the friendly name of the current IAM user will be used as the vault role.
|
||||
* `role` sets the name of the role against which the login is being attempted. This should be bound to your IAM role. If one is not supplied then the friendly name of the current IAM user will be used as the vault role.
|
||||
* `aws-path` sets the path of the AWS mount to use
|
||||
* `server-id` sets the value to use for the `X-Vault-AWS-IAM-Server-ID` header preventing certain types of replay attacks.
|
||||
|
||||
See also: https://www.vaultproject.io/docs/auth/aws.html[Vault documentation on configuring iam auth]
|
||||
AWS-IAM requires the AWS Java SDK dependency (`com.amazonaws:aws-java-sdk-core`)
|
||||
as the authentication implementation uses AWS SDK types for credentials and request signing.
|
||||
|
||||
See also: https://www.vaultproject.io/docs/auth/aws.html[Vault Documentation: Using the aws auth backend]
|
||||
|
||||
[[vault.config.authentication.clientcert]]
|
||||
=== TLS certificate authentication
|
||||
|
||||
@@ -15,24 +15,46 @@
|
||||
*/
|
||||
package org.springframework.cloud.vault.config;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import com.amazonaws.auth.AWSCredentials;
|
||||
import com.amazonaws.auth.AWSCredentialsProvider;
|
||||
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.cloud.vault.config.VaultProperties.AwsIamProperties;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.vault.authentication.*;
|
||||
import org.springframework.vault.authentication.AppIdAuthentication;
|
||||
import org.springframework.vault.authentication.AppIdAuthenticationOptions;
|
||||
import org.springframework.vault.authentication.AppIdUserIdMechanism;
|
||||
import org.springframework.vault.authentication.AppRoleAuthentication;
|
||||
import org.springframework.vault.authentication.AppRoleAuthenticationOptions;
|
||||
import org.springframework.vault.authentication.AwsEc2Authentication;
|
||||
import org.springframework.vault.authentication.AwsEc2AuthenticationOptions;
|
||||
import org.springframework.vault.authentication.AwsIamAuthentication;
|
||||
import org.springframework.vault.authentication.AwsIamAuthenticationOptions;
|
||||
import org.springframework.vault.authentication.ClientAuthentication;
|
||||
import org.springframework.vault.authentication.ClientCertificateAuthentication;
|
||||
import org.springframework.vault.authentication.CubbyholeAuthentication;
|
||||
import org.springframework.vault.authentication.CubbyholeAuthenticationOptions;
|
||||
import org.springframework.vault.authentication.IpAddressUserId;
|
||||
import org.springframework.vault.authentication.MacAddressUserId;
|
||||
import org.springframework.vault.authentication.StaticUserId;
|
||||
import org.springframework.vault.authentication.TokenAuthentication;
|
||||
import org.springframework.vault.authentication.AwsEc2AuthenticationOptions.Nonce;
|
||||
import org.springframework.vault.authentication.AwsIamAuthenticationOptions.AwsIamAuthenticationOptionsBuilder;
|
||||
import org.springframework.vault.support.VaultToken;
|
||||
import org.springframework.web.client.RestOperations;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* Factory for {@link ClientAuthentication}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Kevin Holditch
|
||||
* @since 1.1
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@@ -45,7 +67,7 @@ class ClientAuthenticationFactory {
|
||||
/**
|
||||
* @return a new {@link ClientAuthentication}.
|
||||
*/
|
||||
public ClientAuthentication createClientAuthentication() {
|
||||
ClientAuthentication createClientAuthentication() {
|
||||
|
||||
switch (vaultProperties.getAuthentication()) {
|
||||
|
||||
@@ -161,18 +183,30 @@ class ClientAuthenticationFactory {
|
||||
|
||||
private ClientAuthentication awsIamAuthentication(VaultProperties vaultProperties) {
|
||||
|
||||
AwsIamAuthenticationOptions.AwsIamAuthenticationOptionsBuilder awsIamAuthenticationOptionsBuilder = AwsIamAuthenticationOptions.builder();
|
||||
AwsIamProperties awsIam = vaultProperties.getAwsIam();
|
||||
|
||||
if (vaultProperties.getAwsIam() != null && vaultProperties.getAwsIam().getVaultRole() != null)
|
||||
awsIamAuthenticationOptionsBuilder.role(vaultProperties.getAwsIam().getVaultRole());
|
||||
AWSCredentialsProvider credentialsProvider = AwsCredentialProvider
|
||||
.getAwsCredentialsProvider();
|
||||
|
||||
AwsIamAuthenticationOptions options = awsIamAuthenticationOptionsBuilder
|
||||
.credentialsProvider(new DefaultAWSCredentialsProviderChain())
|
||||
.build();
|
||||
AwsIamAuthenticationOptionsBuilder builder = AwsIamAuthenticationOptions
|
||||
.builder();
|
||||
|
||||
return new AwsIamAuthentication(options, restOperations);
|
||||
if (StringUtils.hasText(awsIam.getRole())) {
|
||||
builder.role(awsIam.getRole());
|
||||
}
|
||||
|
||||
}
|
||||
if (StringUtils.hasText(awsIam.getServerName())) {
|
||||
builder.serverName(awsIam.getServerName());
|
||||
}
|
||||
|
||||
builder.path(awsIam.getAwsPath()) //
|
||||
.credentialsProvider(credentialsProvider);
|
||||
|
||||
AwsIamAuthenticationOptions options = builder.credentialsProvider(
|
||||
credentialsProvider).build();
|
||||
|
||||
return new AwsIamAuthentication(options, restOperations);
|
||||
}
|
||||
|
||||
private ClientAuthentication cubbyholeAuthentication() {
|
||||
|
||||
@@ -186,4 +220,38 @@ class ClientAuthenticationFactory {
|
||||
|
||||
return new CubbyholeAuthentication(options, restOperations);
|
||||
}
|
||||
|
||||
private static class AwsCredentialProvider {
|
||||
|
||||
private static AWSCredentialsProvider getAwsCredentialsProvider() {
|
||||
|
||||
final DefaultAWSCredentialsProviderChain backingCredentialsProvider = DefaultAWSCredentialsProviderChain
|
||||
.getInstance();
|
||||
|
||||
// Eagerly fetch credentials preventing lag during the first, actual login.
|
||||
final AWSCredentials firstAccess = backingCredentialsProvider
|
||||
.getCredentials();
|
||||
|
||||
final AtomicReference<AWSCredentials> once = new AtomicReference<>(
|
||||
firstAccess);
|
||||
|
||||
return new AWSCredentialsProvider() {
|
||||
|
||||
@Override
|
||||
public AWSCredentials getCredentials() {
|
||||
|
||||
if (once.compareAndSet(firstAccess, null)) {
|
||||
return firstAccess;
|
||||
}
|
||||
|
||||
return backingCredentialsProvider.getCredentials();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
backingCredentialsProvider.refresh();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.springframework.validation.annotation.Validated;
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* @author Mark Paluch
|
||||
* @author Kevin Holditch
|
||||
*/
|
||||
@ConfigurationProperties("spring.cloud.vault")
|
||||
@Data
|
||||
@@ -230,10 +231,23 @@ public class VaultProperties implements EnvironmentAware {
|
||||
|
||||
@Data
|
||||
public static class AwsIamProperties {
|
||||
|
||||
/**
|
||||
* Name of the vault role, optional if not specified then the friendly IAM name will be used.
|
||||
* Mount path of the AWS authentication backend.
|
||||
*/
|
||||
private String vaultRole;
|
||||
@NotEmpty
|
||||
private String awsPath = "aws";
|
||||
|
||||
/**
|
||||
* Name of the role, optional. Defaults to the friendly IAM name if not set.
|
||||
*/
|
||||
private String role = "";
|
||||
|
||||
/**
|
||||
* Name of the server used to set {@code X-Vault-AWS-IAM-Server-ID} header in the
|
||||
* headers of login requests.
|
||||
*/
|
||||
private String serverName;
|
||||
}
|
||||
|
||||
@Data
|
||||
|
||||
Reference in New Issue
Block a user