Document how to externalize login credentials.

Fixes gh-26.
This commit is contained in:
Mark Paluch
2016-10-27 15:53:59 +02:00
parent 799ab8f8dd
commit 67f7119d22
5 changed files with 159 additions and 0 deletions

View File

@@ -0,0 +1,109 @@
/*
* Copyright 2016 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
*
* http://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.vault.demo;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.vault.annotation.VaultPropertySource;
import org.springframework.vault.authentication.ClientAuthentication;
import org.springframework.vault.authentication.TokenAuthentication;
import org.springframework.vault.core.VaultIntegrationTestConfiguration;
import org.springframework.vault.core.VaultOperations;
import org.springframework.vault.util.PrepareVault;
import org.springframework.vault.util.VaultRule;
/**
* This application uses {@link PropertySources} to define static config files and
* {@link VaultPropertySource} to retrieve properties from Vault.
* <p>
* {@code secure-introduction.properties} externalizes Vault login credentials to keep
* authentication details outside the code.
* <p>
* {@code other.properties} references a Vault property to illustrate possible integration
* with Spring Vault's property source support.
*
* @author Mark Paluch
*/
public class SecurePropertyUsage {
public static void main(String[] args) {
VaultRule vaultRule = new VaultRule();
vaultRule.before();
PrepareVault prepareVault = vaultRule.prepare();
VaultOperations vaultOperations = prepareVault.getVaultOperations();
Map<String, String> data = new HashMap<String, String>();
data.put("encrypted", "Much secret. Very confidential. Wow.");
vaultOperations.write("secret/secure-introduction", data);
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
Config.class);
System.out.println(context.getEnvironment().getProperty(
"my-property-that-references-vault"));
System.out.println(context.getEnvironment().getProperty("encrypted"));
System.out.println(context.getBean(Client.class).myValue);
context.stop();
}
@PropertySources({
@PropertySource("classpath:/org/springframework/vault/demo/secure-introduction.properties"),
@PropertySource("classpath:/org/springframework/vault/demo/other.properties") })
@VaultPropertySource({ "secret/secure-introduction" })
@Configuration
@ComponentScan
static class Config extends VaultIntegrationTestConfiguration implements
ApplicationContextAware {
private Environment environment;
@Override
public ClientAuthentication clientAuthentication() {
return new TokenAuthentication(environment.getProperty("vault.token"));
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
environment = applicationContext.getEnvironment();
}
}
@Component
static class Client {
@Value("${encrypted}")
String myValue;
}
}

View File

@@ -0,0 +1 @@
my-property-that-references-vault=Value: ${encrypted}

View File

@@ -0,0 +1 @@
vault.token=00000000-0000-0000-0000-000000000000

View File

@@ -5,6 +5,49 @@ Different organizations have different requirements for security
and authentication. Vault reflects that need by shipping multiple authentication
methods. Spring Vault supports multiple authentications mechanisms.
== Externalizing login credentials
Obtaining first-time access to a secured system is known as secure introduction.
Any client requires ephemeral or permanent credentials to access Vault. Externalizing credentials
is a good pattern to keep code maintainability high but comes at a risk of increased disclosure.
Disclosure of login credentials to any party allows login to Vault and access secrets that
are permitted by the underlying role. Picking the appropriate client authentication and
injecting credentials into the application is subject to risk evaluation.
Spring's http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/beans.html#beans-property-source-abstraction[PropertySource abstraction] is a natural fit
to keep configuration outside the application code. You can use system properties, environment
variables or property files to store login credentials. Each approach comes with its own properties.
Keep in mind that the command line and environment properties can be introspected with appropriate
OS access levels.
.Externalizing `vault.token` to a properties file
====
----
@PropertySource("configuration.properties"),
@Configuration
static class Config extends VaultIntegrationTestConfiguration implements
ApplicationContextAware {
private Environment environment;
@Override
public ClientAuthentication clientAuthentication() {
return new TokenAuthentication(environment.getProperty("vault.token"));
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
environment = applicationContext.getEnvironment();
}
}
----
====
See https://github.com/spring-projects/spring-vault/blob/master/spring-vault-core/src/test/java/org/springframework/vault/demo/SecurePropertyUsage.java[`SecurePropertyUsage.java`]
for a sample on referencing properties in components and other property sources.
== Token authentication
Tokens are the core method for authentication within Vault.

View File

@@ -299,6 +299,11 @@ Vault can be used in many different ways. One specific use-case is using
Vault to store encrypted properties. Spring Vault supports Vault as property
source to obtain configuration properties using Spring's http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/beans.html#beans-property-source-abstraction[PropertySource abstraction].
NOTE: You can reference properties stored inside Vault in other property sources or use value injection with `@Value(…)`. Special attention is required when bootstrapping beans that require data stored inside of Vault. A `VaultPropertySource` must be initialized at that time to retrieve properties from Vault.
NOTE: Spring Boot/Spring Cloud users can benefit from https://github.com/spring-cloud-incubator/spring-cloud-vault-config[Spring Cloud Vault]'s
configuration integration that initializes various property sources during application startup.
=== Registering `VaultPropertySource`
Spring Vault provides a `VaultPropertySource` to be used with Vault to obtain