Files
spring-cloud-static/spring-cloud-vault/3.0.0-M2/reference/html/quickstart.html
2020-05-29 19:31:30 +00:00

513 lines
17 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 1.5.8">
<title>Client Side Usage</title>
<link rel="stylesheet" href="css/spring.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<style>
.hidden {
display: none;
}
.switch {
border-width: 1px 1px 0 1px;
border-style: solid;
border-color: #7a2518;
display: inline-block;
}
.switch--item {
padding: 10px;
background-color: #ffffff;
color: #7a2518;
display: inline-block;
cursor: pointer;
}
.switch--item:not(:first-child) {
border-width: 0 0 0 1px;
border-style: solid;
border-color: #7a2518;
}
.switch--item.selected {
background-color: #7a2519;
color: #ffffff;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
<script type="text/javascript">
function addBlockSwitches() {
$('.primary').each(function() {
primary = $(this);
createSwitchItem(primary, createBlockSwitch(primary)).item.addClass("selected");
primary.children('.title').remove();
});
$('.secondary').each(function(idx, node) {
secondary = $(node);
primary = findPrimary(secondary);
switchItem = createSwitchItem(secondary, primary.children('.switch'));
switchItem.content.addClass('hidden');
findPrimary(secondary).append(switchItem.content);
secondary.remove();
});
}
function createBlockSwitch(primary) {
blockSwitch = $('<div class="switch"></div>');
primary.prepend(blockSwitch);
return blockSwitch;
}
function findPrimary(secondary) {
candidate = secondary.prev();
while (!candidate.is('.primary')) {
candidate = candidate.prev();
}
return candidate;
}
function createSwitchItem(block, blockSwitch) {
blockName = block.children('.title').text();
content = block.children('.content').first().append(block.next('.colist'));
item = $('<div class="switch--item">' + blockName + '</div>');
item.on('click', '', content, function(e) {
$(this).addClass('selected');
$(this).siblings().removeClass('selected');
e.data.siblings('.content').addClass('hidden');
e.data.removeClass('hidden');
});
blockSwitch.append(item);
return {'item': item, 'content': content};
}
function globalSwitch() {
$('.switch--item').each(function() {
$(this).off('click');
$(this).on('click', function() {
selectedText = $(this).text()
selectedIndex = $(this).index()
$(".switch--item").filter(function() { return ($(this).text() === selectedText) }).each(function() {
$(this).addClass('selected');
$(this).siblings().removeClass('selected');
selectedContent = $(this).parent().siblings(".content").eq(selectedIndex)
selectedContent.removeClass('hidden');
selectedContent.siblings().addClass('hidden');
});
});
});
}
$(addBlockSwitches);
$(globalSwitch);
</script>
</head>
<body class="book toc2 toc-left">
<div id="header">
<div id="toc" class="toc2">
<div id="toctitle">Table of Contents</div>
<ul class="sectlevel1">
<li><a href="#_client_side_usage">Client Side Usage</a>
<ul class="sectlevel2">
<li><a href="#_authentication">Authentication</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p><strong>Prerequisites</strong></p>
</div>
<div class="paragraph">
<p>To get started with Vault and this guide you need a *NIX-like operating systems that provides:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>wget</code>, <code>openssl</code> and <code>unzip</code></p>
</li>
<li>
<p>at least Java 8 and a properly configured <code>JAVA_HOME</code> environment variable</p>
</li>
</ul>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
This guide explains Vault setup from a Spring Cloud Vault perspective for integration testing.
You can find a getting started guide directly on the Vault project site: <a href="https://learn.hashicorp.com/vault" class="bare">https://learn.hashicorp.com/vault</a>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p><strong>Install Vault</strong></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-bash hljs" data-lang="bash">$ wget https://releases.hashicorp.com/vault/${vault_version}/vault_${vault_version}_${platform}.zip
$ unzip vault_${vault_version}_${platform}.zip</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
These steps can be achieved by downloading and running <a href="https://github.com/spring-cloud/spring-cloud-vault/blob/master/src/test/bash/install_vault.sh"><code>install_vault.sh</code></a>.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p><strong>Create SSL certificates for Vault</strong></p>
</div>
<div class="paragraph">
<p>Next, you&#8217;r required to generate a set of certificates:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Root CA</p>
</li>
<li>
<p>Vault Certificate (decrypted key <code>work/ca/private/localhost.decrypted.key.pem</code> and certificate <code>work/ca/certs/localhost.cert.pem</code>)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Make sure to import the Root Certificate into a Java-compliant truststore.</p>
</div>
<div class="paragraph">
<p>The easiest way to achieve this is by using OpenSSL.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<a href="https://github.com/spring-cloud/spring-cloud-vault/blob/master/src/test/bash/"><code>create_certificates.sh</code></a> creates certificates in <code>work/ca</code> and a JKS truststore <code>work/keystore.jks</code>.
If you want to run Spring Cloud Vault using this quickstart guide you need to configure the truststore the <code>spring.cloud.vault.ssl.trust-store</code> property to <code>file:work/keystore.jks</code>.
</td>
</tr>
</table>
</div>
<div id="quickstart.vault.start" class="paragraph">
<p><strong>Start Vault server</strong></p>
</div>
<div class="paragraph">
<p>Next create a config file along the lines of:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code>backend "inmem" {
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "work/ca/certs/localhost.cert.pem"
tls_key_file = "work/ca/private/localhost.decrypted.key.pem"
}
disable_mlock = true</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
You can find an example config file at <a href="https://github.com/spring-clod/spring-cloud-vault/blob/master/src/test/bash/vault.conf"><code>vault.conf</code></a>.
</td>
</tr>
</table>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-bash hljs" data-lang="bash">$ vault server -config=vault.conf</code></pre>
</div>
</div>
<div class="paragraph">
<p>Vault is started listening on <code>0.0.0.0:8200</code> using the <code>inmem</code> storage and <code>https</code>.
Vault is sealed and not initialized when starting up.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
If you want to run tests, leave Vault uninitialized.
The tests will initialize Vault and create a root token <code>00000000-0000-0000-0000-000000000000</code>.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>If you want to use Vault for your application or give it a try then you need to initialize it first.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-bash hljs" data-lang="bash">$ export VAULT_ADDR="https://localhost:8200"
$ export VAULT_SKIP_VERIFY=true # Don't do this for production
$ vault init</code></pre>
</div>
</div>
<div class="paragraph">
<p>You should see something like:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-bash hljs" data-lang="bash">Key 1: 7149c6a2e16b8833f6eb1e76df03e47f6113a3288b3093faf5033d44f0e70fe701
Key 2: 901c534c7988c18c20435a85213c683bdcf0efcd82e38e2893779f152978c18c02
Key 3: 03ff3948575b1165a20c20ee7c3e6edf04f4cdbe0e82dbff5be49c63f98bc03a03
Key 4: 216ae5cc3ddaf93ceb8e1d15bb9fc3176653f5b738f5f3d1ee00cd7dccbe926e04
Key 5: b2898fc8130929d569c1677ee69dc5f3be57d7c4b494a6062693ce0b1c4d93d805
Initial Root Token: 19aefa97-cccc-bbbb-aaaa-225940e63d76
Vault initialized with 5 keys and a key threshold of 3. Please
securely distribute the above keys. When the Vault is re-sealed,
restarted, or stopped, you must provide at least 3 of these keys
to unseal it again.
Vault does not store the master key. Without at least 3 keys,
your Vault will remain permanently sealed.</code></pre>
</div>
</div>
<div class="paragraph">
<p>Vault will initialize and return a set of unsealing keys and the root token.
Pick 3 keys and unseal Vault.
Store the Vault token in the <code>VAULT_TOKEN</code>
environment variable.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-bash hljs" data-lang="bash">$ vault unseal (Key 1)
$ vault unseal (Key 2)
$ vault unseal (Key 3)
$ export VAULT_TOKEN=(Root token)
# Required to run Spring Cloud Vault tests after manual initialization
$ vault token-create -id="00000000-0000-0000-0000-000000000000" -policy="root"</code></pre>
</div>
</div>
<div class="paragraph">
<p>Spring Cloud Vault accesses different resources.
By default, the secret backend is enabled which accesses secret config settings via JSON endpoints.</p>
</div>
<div class="paragraph">
<p>The HTTP service has resources in the form:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>/secret/{application}/{profile}
/secret/{application}
/secret/{defaultContext}/{profile}
/secret/{defaultContext}</pre>
</div>
</div>
<div class="paragraph">
<p>where the "application" is injected as the <code>spring.application.name</code> in the
<code>SpringApplication</code> (i.e. what is normally "application" in a regular Spring Boot app), "profile" is an active profile (or comma-separated list of properties).
Properties retrieved from Vault will be used "as-is" without further prefixing of the property names.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_client_side_usage"><a class="link" href="#_client_side_usage">Client Side Usage</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>To use these features in an application, just build it as a Spring Boot application that depends on <code>spring-cloud-vault-config</code> (e.g. see the test cases).
Example Maven configuration:</p>
</div>
<div class="exampleblock">
<div class="title">Example 1. pom.xml</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml">&lt;parent&gt;
&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
&lt;artifactId&gt;spring-boot-starter-parent&lt;/artifactId&gt;
&lt;version&gt;2.0.0.RELEASE&lt;/version&gt;
&lt;relativePath /&gt; &lt;!-- lookup parent from repository --&gt;
&lt;/parent&gt;
&lt;dependencies&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
&lt;artifactId&gt;spring-cloud-starter-vault-config&lt;/artifactId&gt;
&lt;version&gt;3.0.0-M2&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
&lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
&lt;scope&gt;test&lt;/scope&gt;
&lt;/dependency&gt;
&lt;/dependencies&gt;
&lt;build&gt;
&lt;plugins&gt;
&lt;plugin&gt;
&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
&lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;
&lt;/plugin&gt;
&lt;/plugins&gt;
&lt;/build&gt;
&lt;!-- repositories also needed for snapshots and milestones --&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Then you can create a standard Spring Boot application, like this simple HTTP server:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@SpringBootApplication
@RestController
public class Application {
@RequestMapping("/")
public String home() {
return "Hello World!";
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>When it runs it will pick up the external configuration from the default local Vault server on port <code>8200</code> if it is running.
To modify the startup behavior you can change the location of the Vault server using <code>bootstrap.properties</code> (like <code>application.properties</code> but for the bootstrap phase of an application context), e.g.</p>
</div>
<div class="exampleblock">
<div class="title">Example 2. bootstrap.yml</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring.cloud.vault:
host: localhost
port: 8200
scheme: https
uri: https://localhost:8200
connection-timeout: 5000
read-timeout: 15000
config:
order: -10</code></pre>
</div>
</div>
</div>
</div>
<div class="ulist">
<ul>
<li>
<p><code>host</code> sets the hostname of the Vault host.
The host name will be used for SSL certificate validation</p>
</li>
<li>
<p><code>port</code> sets the Vault port</p>
</li>
<li>
<p><code>scheme</code> setting the scheme to <code>http</code> will use plain HTTP.
Supported schemes are <code>http</code> and <code>https</code>.</p>
</li>
<li>
<p><code>uri</code> configure the Vault endpoint with an URI. Takes precedence over host/port/scheme configuration</p>
</li>
<li>
<p><code>connection-timeout</code> sets the connection timeout in milliseconds</p>
</li>
<li>
<p><code>read-timeout</code> sets the read timeout in milliseconds</p>
</li>
<li>
<p><code>config.order</code> sets the order for the property source</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Enabling further integrations requires additional dependencies and configuration.
Depending on how you have set up Vault you might need additional configuration like
<a href="https://cloud.spring.io/spring-cloud-vault/spring-cloud-vault.html#vault.config.ssl">SSL</a> and
<a href="https://cloud.spring.io/spring-cloud-vault/spring-cloud-vault.html#vault.config.authentication">authentication</a>.</p>
</div>
<div class="paragraph">
<p>If the application imports the <code>spring-boot-starter-actuator</code> project, the status of the vault server will be available via the <code>/health</code> endpoint.</p>
</div>
<div class="paragraph">
<p>The vault health indicator can be enabled or disabled through the property <code>management.health.vault.enabled</code> (default to <code>true</code>).</p>
</div>
<div class="sect2">
<h3 id="_authentication"><a class="link" href="#_authentication">Authentication</a></h3>
<div class="paragraph">
<p>Vault requires an <a href="https://www.vaultproject.io/docs/concepts/auth.html">authentication mechanism</a> to <a href="https://www.vaultproject.io/docs/concepts/tokens.html">authorize client requests</a>.</p>
</div>
<div class="paragraph">
<p>Spring Cloud Vault supports multiple <a href="https://cloud.spring.io/spring-cloud-vault/spring-cloud-vault.html#vault.config.authentication">authentication mechanisms</a> to authenticate applications with Vault.</p>
</div>
<div class="paragraph">
<p>For a quickstart, use the root token printed by the <a href="#quickstart.vault.start">Vault initialization</a>.</p>
</div>
<div class="exampleblock">
<div class="title">Example 3. bootstrap.yml</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-yaml hljs" data-lang="yaml">spring.cloud.vault:
token: 19aefa97-cccc-bbbb-aaaa-225940e63d76</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<i class="fa icon-warning" title="Warning"></i>
</td>
<td class="content">
Consider carefully your security requirements.
Static token authentication is fine if you want quickly get started with Vault, but a static token is not protected any further.
Any disclosure to unintended parties allows Vault use with the associated token roles.
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="js/tocbot/tocbot.min.js"></script>
<script type="text/javascript" src="js/toc.js"></script>
<link rel="stylesheet" href="js/highlight/styles/github.min.css">
<script src="js/highlight/highlight.min.js"></script>
<script>hljs.initHighlighting()</script>
</body>
</html>