website: adding drivers section

This commit is contained in:
Armon Dadgar 2015-09-19 12:18:08 -07:00
parent 5cd47f54d7
commit 201cfc4be1
13 changed files with 19 additions and 3199 deletions

View file

@ -1,332 +0,0 @@
---
layout: "docs"
page_title: "Secret Backend: Cassandra"
sidebar_current: "docs-secrets-cassandra"
description: |-
The Cassandra secret backend for Nomad generates database credentials to access Cassandra.
---
# Cassandra Secret Backend
Name: `cassandra`
The Cassandra secret backend for Nomad generates database credentials
dynamically based on configured roles. This means that services that need
to access a database no longer need to hardcode credentials: they can request
them from Nomad, and use Nomad's leasing mechanism to more easily roll keys.
Additionally, it introduces a new ability: with every service accessing
the database with unique credentials, it makes auditing much easier when
questionable data access is discovered: you can track it down to the specific
instance of a service based on the Cassandra username.
This page will show a quick start for this backend. For detailed documentation
on every path, use `vault path-help` after mounting the backend.
## Quick Start
The first step to using the Cassandra backend is to mount it.
Unlike the `generic` backend, the `cassandra` backend is not mounted by default.
```text
$ vault mount cassandra
Successfully mounted 'cassandra' at 'cassandra'!
```
Next, Nomad must be configured to connect to Cassandra. This is done by
writing one or more hosts, a username, and a password:
```text
$ vault write cassandra/config/connection \
hosts=localhost username=cassandra password=cassandra
```
In this case, we've configured Nomad with the user "cassandra" and password "cassandra",
It is important that the Nomad user is a superuser, in order to manage other user accounts.
The next step is to configure a role. A role is a logical name that maps
to a policy used to generated those credentials. For example, lets create
a "readonly" role:
```text
$ vault write cassandra/roles/readonly \
creation_cql="CREATE USER '{{username}}' WITH PASSWORD '{{password}}' NOSUPERUSER; \
GRANT SELECT ON ALL KEYSPACES TO {{username}};"
Success! Data written to: cassandra/roles/readonly
```
By writing to the `roles/readonly` path we are defining the `readonly` role.
This role will be created by evaluating the given `creation_cql` statements. By
default, the `{{username}}` and `{{password}}` fields will be populated by
Nomad with dynamically generated values. This CQL statement is creating
the named user, and then granting it `SELECT` or read-only privileges
to keyspaces. More complex `GRANT` queries can be used to
customize the privileges of the role. See the [CQL Reference Manual](http://docs.datastax.com/en/cql/3.1/cql/cql_reference/grant_r.html)
for more information.
To generate a new set of credentials, we simply read from that role:
Nomad is now configured to create and manage credentials for Cassandra!
```text
$ vault read cassandra/creds/readonly
Key Value
lease_id cassandra/creds/test/7a23e890-3a26-531d-529b-92d18d1fa63f
lease_duration 3600
lease_renewable true
password dfa80eea-ccbe-b228-ebf7-e2f62b245e71
username vault-root-1434647667-9313
```
By reading from the `creds/readonly` path, Nomad has generated a new
set of credentials using the `readonly` role configuration. Here we
see the dynamically generated username and password, along with a one
hour lease.
Using ACLs, it is possible to restrict using the `cassandra` backend such
that trusted operators can manage the role definitions, and both
users and applications are restricted in the credentials they are
allowed to read.
If you get stuck at any time, simply run `vault path-help cassandra` or with a
subpath for interactive help output.
## API
### /cassandra/config/connection
#### POST
<dl class="api">
<dt>Description</dt>
<dd>
Configures the connection information used to communicate with Cassandra.
TLS works as follows:<br /><br />
<ul>
<li>
• If `tls` is set to true, the connection will use TLS; this happens automatically if `pem_bundle`, `pem_json`, or `insecure_tls` is set
</li>
<li>
• If `insecure_tls` is set to true, the connection will not perform verification of the server certificate; this also sets `tls` to true
</li>
<li>
• If only `issuing_ca` is set in `pem_json`, or the only certificate in `pem_bundle` is a CA certificate, the given CA certificate will be used for server certificate verification; otherwise the system CA certificates will be used
</li>
<li>
• If `certificate` and `private_key` are set in `pem_bundle` or `pem_json`, client auth will be turned on for the connection
</li>
</ul>
`pem_bundle` should be a PEM-concatenated bundle of a private key + client certificate, an issuing CA certificate, or both. `pem_json` should contain the same information; for convenience, the JSON format is the same as that output by the issue command from the PKI backend.<br /><br />
This is a root protected endpoint.
</dd>
<dt>Method</dt>
<dd>POST</dd>
<dt>URL</dt>
<dd>`/cassandra/config/connection`</dd>
<dt>Parameters</dt>
<dd>
<ul>
<li>
<span class="param">hosts</span>
<span class="param-flags">required</span>
A set of comma-deliniated Cassandra hosts to connect to.
</li>
<li>
<span class="param">username</span>
<span class="param-flags">required</span>
The username to use for superuser access.
</li>
<li>
<span class="param">password</span>
<span class="param-flags">required</span>
The password corresponding to the given username.
</li>
<li>
<span class="param">tls</span>
<span class="param-flags">optional</span>
Whether to use TLS when connecting to Cassandra.
</li>
<li>
<span class="param">insecure_tls</span>
<span class="param-flags">optional</span>
Whether to skip verification of the server certificate when using TLS.
</li>
<li>
<span class="param">pem_bundle</span>
<span class="param-flags">optional</span>
Concatenated PEM blocks containing a certificate and private key;
a certificate, private key, and issuing CA certificate; or just a CA
certificate.
</li>
<li>
<span class="param">pem_json</span>
<span class="param-flags">optional</span>
JSON containing a certificate and private key;
a certificate, private key, and issuing CA certificate; or just a CA
certificate. For convenience format is the same as the output of the
`issue` command from the `pki` backend; see [the pki documentation](https://vaultproject.io/docs/secrets/pki/index.html).
</li>
</ul>
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
</dl>
### /cassandra/roles/
#### POST
<dl class="api">
<dt>Description</dt>
<dd>
Creates or updates the role definition.
</dd>
<dt>Method</dt>
<dd>POST</dd>
<dt>URL</dt>
<dd>`/cassandra/roles/<name>`</dd>
<dt>Parameters</dt>
<dd>
<ul>
<li>
<span class="param">creation_cql</span>
<span class="param-flags">optional</span>
The CQL statements executed to create and configure the new user.
Must be semi-colon separated. The '{{username}}' and '{{password}}'
values will be substituted; it is required that these parameters are
in single quotes. The default creates a non-superuser user with
no authorization grants.
</li>
<li>
<span class="param">rollback_cql</span>
<span class="param-flags">optional</span>
The CQL statements executed to attempt a rollback if an error is
encountered during user creation. The default is to delete the user.
Must be semi-colon separated. The '{{username}}' and '{{password}}'
values will be substituted; it is required that these parameters are
in single quotes.
</li>
<li>
<span class="param">lease</span>
<span class="param-flags">optional</span>
The lease value provided as a string duration
with time suffix. Hour is the largest suffix.
</li>
<li>
<span class="param">lease_grace_period</span>
<span class="param-flags">optional</span>
The lease grace period (time before revocation after the lease has
expired) provided as a string duration with time suffix. Hour is the
largest suffix.
</li>
</ul>
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
</dl>
#### GET
<dl class="api">
<dt>Description</dt>
<dd>
Queries the role definition.
</dd>
<dt>Method</dt>
<dd>GET</dd>
<dt>URL</dt>
<dd>`/cassandra/roles/<name>`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
```javascript
{
"data": {
"creation_cql": "CREATE USER...",
"revocation_cql": "DROP USER...",
"lease": "12h",
"lease_grace_period": "1h"
}
}
```
</dd>
</dl>
#### DELETE
<dl class="api">
<dt>Description</dt>
<dd>
Deletes the role definition.
</dd>
<dt>Method</dt>
<dd>DELETE</dd>
<dt>URL</dt>
<dd>`/cassandra/roles/<name>`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
</dl>
### /cassandra/creds/
#### GET
<dl class="api">
<dt>Description</dt>
<dd>
Generates a new set of dynamic credentials based on the named role.
</dd>
<dt>Method</dt>
<dd>GET</dd>
<dt>URL</dt>
<dd>`/cassandra/creds/<name>`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
```javascript
{
"data": {
"username": "vault-root-1430158508-126",
"password": "132ae3ef-5a64-7499-351e-bfe59f3a2a21"
}
}
```
</dd>
</dl>

View file

@ -1,252 +0,0 @@
---
layout: "docs"
page_title: "Secret Backend: Consul"
sidebar_current: "docs-secrets-consul"
description: |-
The Consul secret backend for Nomad generates tokens for Consul dynamically.
---
# Consul Secret Backend
Name: `consul`
The Consul secret backend for Nomad generates
[Consul](http://consul.io)
API tokens dynamically based on Consul ACL policies.
This page will show a quick start for this backend. For detailed documentation
on every path, use `vault path-help` after mounting the backend.
## Quick Start
The first step to using the consul backend is to mount it.
Unlike the `generic` backend, the `consul` backend is not mounted by default.
```
$ vault mount consul
Successfully mounted 'consul' at 'consul'!
```
Next, we must configure Nomad to know how to contact Consul.
This is done by writing the access information:
```
$ vault write consul/config/access address=127.0.0.1:8500 token=root
Success! Data written to: consul/config/access
```
In this case, we've configured Nomad to connect to Consul
on the default port with the loopback address. We've also provided
an ACL token to use with the `token` parameter. Nomad must have a management
type token so that it can create and revoke ACL tokens.
The next step is to configure a role. A role is a logical name that maps
to a role used to generated those credentials. For example, lets create
a "readonly" role:
```
POLICY='key "" { policy = "read" }'
$ echo $POLICY | base64 | vault write consul/roles/readonly policy=-
Success! Data written to: consul/roles/readonly
```
The backend expects the policy to be base64 encoded, so we need to encode
it properly before writing. The policy language is
[documented by Consul](https://consul.io/docs/internals/acl.html), but we've defined a read-only policy.
To generate a new set Consul ACL token, we simply read from that role:
```
$ vault read consul/creds/readonly
Key Value
lease_id consul/creds/readonly/c7a3bd77-e9af-cfc4-9cba-377f0ef10e6c
lease_duration 3600
token 973a31ea-1ec4-c2de-0f63-623f477c2510
```
Here we can see that Nomad has generated a new Consul ACL token for us.
We can test this token out, and verify that it is read-only:
```
$ curl 127.0.0.1:8500/v1/kv/foo?token=973a31ea-1ec4-c2de-0f63-623f477c25100
[{"CreateIndex":12,"ModifyIndex":53,"LockIndex":4,"Key":"foo","Flags":3304740253564472344,"Value":"YmF6"}]
$ curl -X PUT -d 'test' 127.0.0.1:8500/v1/kv/foo?token=973a31ea-1ec4-c2de-0f63-623f477c2510
Permission denied
```
## API
### /consul/config/access
#### POST
<dl class="api">
<dt>Description</dt>
<dd>
Configures the access information for Consul.
This is a root protected endpoint.
</dd>
<dt>Method</dt>
<dd>POST</dd>
<dt>URL</dt>
<dd>`/consul/config/access`</dd>
<dt>Parameters</dt>
<dd>
<ul>
<li>
<span class="param">address</span>
<span class="param-flags">required</span>
The address of the Consul instance, provided as host:port
</li>
<li>
<span class="param">scheme</span>
<span class="param-flags">optional</span>
The URL scheme to use. Defaults to HTTP, as Consul does not expose HTTPS by default.
</li>
<li>
<span class="param">token</span>
<span class="param-flags">required</span>
The Consul ACL token to use. Must be a management type token.
</li>
</ul>
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
</dl>
### /consul/roles/
#### POST
<dl class="api">
<dt>Description</dt>
<dd>
Creates or updates the Consul role definition.
</dd>
<dt>Method</dt>
<dd>POST</dd>
<dt>URL</dt>
<dd>`/consul/roles/<name>`</dd>
<dt>Parameters</dt>
<dd>
<ul>
<li>
<span class="param">policy</span>
<span class="param-flags">required</span>
The base64 encoded Consul ACL policy. This is documented in [more detail here](https://consul.io/docs/internals/acl.html).
</li>
<li>
<span class="param">lease</span>
<span class="param-flags">optional</span>
The lease value provided as a string duration with time suffix. Hour is the largest suffix.
</li>
</ul>
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
</dl>
#### GET
<dl class="api">
<dt>Description</dt>
<dd>
Queries a Consul role definition.
</dd>
<dt>Method</dt>
<dd>GET</dd>
<dt>URL</dt>
<dd>`/consul/roles/<name>`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
```javascript
{
"data": {
"policy": "abcdef="
}
}
```
</dd>
</dl>
#### Delete
<dl class="api">
<dt>Description</dt>
<dd>
Deletes a Consul role definition.
</dd>
<dt>Method</dt>
<dd>DELETE</dd>
<dt>URL</dt>
<dd>`/consul/roles/<name>`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
</dl>
### /consul/creds/
#### GET
<dl class="api">
<dt>Description</dt>
<dd>
Generates a dynamic Consul token based on the role definition.
</dd>
<dt>Method</dt>
<dd>GET</dd>
<dt>URL</dt>
<dd>`/consul/creds/<name>`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
```javascript
{
"data": {
"token": "973a31ea-1ec4-c2de-0f63-623f477c2510"
}
}
```
</dd>
</dl>

View file

@ -1,12 +1,12 @@
---
layout: "docs"
page_title: "Secret Backend: Custom"
sidebar_current: "docs-secrets-custom"
page_title: "Drivers: Custom"
sidebar_current: "docs-drivers-custom"
description: |-
Create custom secret backends for Nomad.
---
# Custom Secret Backends
# Custom Drivers
Nomad doesn't currently support the creation of custom secret backends.
The primary reason is because we want to ensure the core of Nomad is

View file

@ -1,12 +1,12 @@
---
layout: "docs"
page_title: "Secret Backend: AWS"
sidebar_current: "docs-secrets-aws"
page_title: "Drivers: Docker"
sidebar_current: "docs-drivers-docker"
description: |-
The AWS secret backend for Nomad generates access keys dynamically based on IAM policies.
---
# AWS Secret Backend
# Docker Driver
Name: `aws`

View file

@ -1,50 +0,0 @@
---
layout: "docs"
page_title: "Secret Backend: Generic"
sidebar_current: "docs-secrets-generic"
description: |-
The generic secret backend can store arbitrary secrets.
---
# Generic Secret Backend
Name: `generic`
The generic secret backend is used to store arbitrary secrets within
the configured physical storage for Nomad. If you followed along with
the getting started guide, you interacted with a generic secret backend
via the `secret/` prefix that Nomad mounts by default.
Writing to a key in the `secret/` backend will replace the old value,
the sub-fields are not merged together.
## Quick Start
The generic backend allows for writing keys with arbitrary values. The
only value that is special is the `lease` key, which can be provided with
any key to restrict the lease time of the secret. This is useful to ensure
clients periodically renew so that key rolling can be time bounded.
As an example, we can write a new key "foo" to the generic backend
mounted at "secret/" by default:
```
$ vault write secret/foo zip=zap lease=1h
Success! Data written to: secret/foo
```
This writes the key with the "zip" field set to "zap" and a one hour lease. We can test
this by doing a read:
```
$ vault read secret/foo
Key Value
lease_id secret/foo/e4514713-d5d9-fb14-4177-97a7f7f64518
lease_duration 3600
lease 1h
zip zap
```
As expected, we get the value previously set back as well as our custom lease.
The lease_duration has been set to 3600 seconds, or one hour as specified.

View file

@ -1,12 +1,12 @@
---
layout: "docs"
page_title: "Secret Backends"
sidebar_current: "docs-secrets"
page_title: "Drivers"
sidebar_current: "docs-drivers"
description: |-
Secret backends are mountable backends that store or generate secrets in Nomad.
---
# Secret Backends
# Drivers
Secret backends are the components in Nomad which store and generate
secrets.

View file

@ -1,259 +0,0 @@
# JWT Secret Backend
Name: `jwt`
The JWT secret backend for Nomad generates JSON Web Tokens dynamically based on configured roles. This means services can get tokens needed for authentication without going through the usual manual process of generating a private key and signing the token and maintaining the private key's security. Nomad's built-in authentication and authorization mechanisms provide the verification functionality.
This page will show a quick start for this backend. For detailed documentation on every path, use `vault path-help` after mounting the backend.
The JWT secret backend acts like the `transit` backend, it does not store any information.
## Algorithms
### RSA
* RS256
* RS384
* RS512
These require a RSA private/public keypair for signing and verification.
### ECDSA
* EC256
* EC384
* EC512
These require an ECDSA private/public keypair for signing and verification.
### HMAC
* HS256
* HS384
* HS512
These require a shared secret for signing and verification.
## Roles
Roles are defined with the signing algorithm, the secret key or private key to be used, as well as allowing for default but optional JWT Token claims. Once you write a private key or a secret to the role, it CANNOT be read back out.
## Quick Start
The first step to using the jwt backend is to mount it.
Unlike the `generic` backend, the `jwt` backend is not mounted by default.
```text
$ vault mount jwt
Successfully mounted 'jwt' at 'jwt'!
```
The next step is to configure a role. A role is a logical name that maps
to a few settings used to generated the tokens. For example, lets create
a "webauth" role:
```text
$ vault write jwt/roles/webauth \
algorithm=RS256 \
key=@/path/to/private.key
```
Each role requires a secret or a private key to be associated against it.
Generating a token requires passing of additional information so we use the
"jwt/issue/ROLE" path.
```text
$ vault write jwt/issue/webauth \
issuer="Nomad" \
audience="Nomad Client" \
expiration="1538096292" \
claims=@extra.json
```
## API
### /jwt/roles/
#### POST
<dl class="api">
<dt>Description</dt>
<dd>
Creates or updates a named role.
</dd>
<dt>Method</dt>
<dd>POST</dd>
<dt>URL</dt>
<dd>`/jwt/roles/<name>`</dd>
<dt>Parameters</dt>
<dd>
<ul>
<li>
<span class="param">algorithm</span>
<span class="param-flags">required</span>
The algorithm used by JWT to sign the token.
</li>
<li>
<span class="param">key</span>
<span class="param-flags">required</span>
The private key or string used to sign the token.
</li>
<li>
<span class="param">default_issuer</span>
<span class="param-flags">required</span>
The default issuer claim for the role, can be overridden at issue time.
</li>
<li>
<span class="param">default_subject</span>
<span class="param-flags">required</span>
The default subject claim for the role, can be overridden at issue time.
</li>
<li>
<span class="param">default_audience</span>
<span class="param-flags">required</span>
The default audience claim for the role, can be overridden at issue time.
</li>
</ul>
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
</dl>
#### GET
<dl class="api">
<dt>Description</dt>
<dd>
Queries a named role.
</dd>
<dt>Method</dt>
<dd>GET</dd>
<dt>URL</dt>
<dd>`/jwt/roles/<name>`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
```javascript
{
"data": {
"algorithm": "..."
}
}
```
</dd>
</dl>
#### DELETE
<dl class="api">
<dt>Description</dt>
<dd>
Deletes a named role.
</dd>
<dt>Method</dt>
<dd>DELETE</dd>
<dt>URL</dt>
<dd>`/jwt/roles/<name>`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
</dl>
### /jwt/issue/
#### POST
<dl class="api">
<dt>Description</dt>
<dd>
Generates a JWT token based on the named role.
</dd>
<dt>Method</dt>
<dd>GET</dd>
<dt>URL</dt>
<dd>`/jwt/issue/<role>`</dd>
<dt>Parameters</dt>
<dd>
<ul>
<li>
<span class="param">issuer</span>
<span class="param-flags">optional</span>
The Issuer of the token.
</li>
<li>
<span class="param">audience</span>
<span class="param-flags">optional</span>
The Audience of the token.
</li>
<li>
<span class="param">subject</span>
<span class="param-flags">optional</span>
The Subject of the token.
</li>
<li>
<span class="param">expiration</span>
<span class="param-flags">optional</span>
The expiration of the token, expressed in seconds (unix time).
</li>
<li>
<span class="param">issued_at</span>
<span class="param-flags">optional</span>
The issued at time of the token, expressed in seconds (unix time). (Default: current time)
</li>
<li>
<span class="param">not_before</span>
<span class="param-flags">optional</span>
Not Before: the time at which the token is not useful before. Expressed as seconds, unix time. (Default: current time)
</li>
<li>
<span class="param">jti</span>
<span class="param-flags">optional</span>
JSONWebToken Identifier. Unique ID useful for preventing replay attacks. (Default: Random UUID)
</li>
<li>
<span class="param">claims</span>
<span class="param-flags">optional</span>
Should be a JSON Object of additional key/values you want in the token.
</li>
</ul>
</dd>
<dt>Returns</dt>
<dd>
```javascript
{
"data": {
"jti": "...",
"token": "..."
}
}
```
</dd>
</dl>

View file

@ -1,307 +0,0 @@
---
layout: "docs"
page_title: "Secret Backend: MySQL"
sidebar_current: "docs-secrets-mysql"
description: |-
The MySQL secret backend for Nomad generates database credentials to access MySQL.
---
# MySQL Secret Backend
Name: `mysql`
The MySQL secret backend for Nomad generates database credentials
dynamically based on configured roles. This means that services that need
to access a database no longer need to hardcode credentials: they can request
them from Nomad, and use Nomad's leasing mechanism to more easily roll keys.
Additionally, it introduces a new ability: with every service accessing
the database with unique credentials, it makes auditing much easier when
questionable data access is discovered: you can track it down to the specific
instance of a service based on the SQL username.
Nomad makes use of its own internal revocation system to ensure that users
become invalid within a reasonable time of the lease expiring.
This page will show a quick start for this backend. For detailed documentation
on every path, use `vault path-help` after mounting the backend.
## Quick Start
The first step to using the mysql backend is to mount it.
Unlike the `generic` backend, the `mysql` backend is not mounted by default.
```
$ vault mount mysql
Successfully mounted 'mysql' at 'mysql'!
```
Next, we must configure Nomad to know how to connect to the MySQL
instance. This is done by providing a DSN (Data Source Name):
```
$ vault write mysql/config/connection value="root:root@tcp(192.168.33.10:3306)/"
Success! Data written to: mysql/config/connection
```
In this case, we've configured Nomad with the user "root" and password "root,
connecting to an instance at "192.168.33.10" on port 3306. It is not necessary
that Nomad has the root user, but the user must have privileges to create
other users, namely the `GRANT OPTION` privilege.
Optionally, we can configure the lease settings for credentials generated
by Nomad. This is done by writing to the `config/lease` key:
```
$ vault write mysql/config/lease lease=1h lease_max=24h
Success! Data written to: mysql/config/lease
```
This restricts each credential to being valid or leased for 1 hour
at a time, with a maximum use period of 24 hours. This forces an
application to renew their credentials at least hourly, and to recycle
them once per day.
The next step is to configure a role. A role is a logical name that maps
to a policy used to generated those credentials. For example, lets create
a "readonly" role:
```
$ vault write mysql/roles/readonly sql="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT ON *.* TO '{{name}}'@'%';"
Success! Data written to: mysql/roles/readonly
```
By writing to the `roles/readonly` path we are defining the `readonly` role.
This role will be created by evaluating the given `sql` statements. By
default, the `{{name}}` and `{{password}}` fields will be populated by
Nomad with dynamically generated values. This SQL statement is creating
the named user, and then granting it `SELECT` or read-only privileges
to tables in the database. More complex `GRANT` queries can be used to
customize the privileges of the role. See the [MySQL manual](https://dev.mysql.com/doc/refman/5.7/en/grant.html)
for more information.
To generate a new set of credentials, we simply read from that role:
```
$ vault read mysql/creds/readonly
Key Value
lease_id mysql/creds/readonly/bd404e98-0f35-b378-269a-b7770ef01897
lease_duration 3600
password 132ae3ef-5a64-7499-351e-bfe59f3a2a21
username root-aefa635a-18
```
By reading from the `creds/readonly` path, Nomad has generated a new
set of credentials using the `readonly` role configuration. Here we
see the dynamically generated username and password, along with a one
hour lease.
Using ACLs, it is possible to restrict using the mysql backend such
that trusted operators can manage the role definitions, and both
users and applications are restricted in the credentials they are
allowed to read.
## API
### /mysql/config/connection
#### POST
<dl class="api">
<dt>Description</dt>
<dd>
Configures the connection DSN used to communicate with MySQL.
This is a root protected endpoint.
</dd>
<dt>Method</dt>
<dd>POST</dd>
<dt>URL</dt>
<dd>`/mysql/config/connection`</dd>
<dt>Parameters</dt>
<dd>
<ul>
<li>
<span class="param">value</span>
<span class="param-flags">required</span>
The MySQL DSN
</li>
</ul>
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
</dl>
### /mysql/config/lease
#### POST
<dl class="api">
<dt>Description</dt>
<dd>
Configures the lease settings for generated credentials.
If not configured, leases default to 1 hour. This is a root
protected endpoint.
</dd>
<dt>Method</dt>
<dd>POST</dd>
<dt>URL</dt>
<dd>`/mysql/config/lease`</dd>
<dt>Parameters</dt>
<dd>
<ul>
<li>
<span class="param">lease</span>
<span class="param-flags">required</span>
The lease value provided as a string duration
with time suffix. Hour is the largest suffix.
</li>
<li>
<span class="param">lease_max</span>
<span class="param-flags">required</span>
The maximum lease value provided as a string duration
with time suffix. Hour is the largest suffix.
</li>
</ul>
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
</dl>
### /mysql/roles/
#### POST
<dl class="api">
<dt>Description</dt>
<dd>
Creates or updates the role definition.
</dd>
<dt>Method</dt>
<dd>POST</dd>
<dt>URL</dt>
<dd>`/mysql/roles/<name>`</dd>
<dt>Parameters</dt>
<dd>
<ul>
<li>
<span class="param">sql</span>
<span class="param-flags">required</span>
The SQL statements executed to create and configure the role.
Must be semi-colon separated. The '{{name}}' and '{{password}}'
values will be substituted.
</li>
</ul>
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
</dl>
#### GET
<dl class="api">
<dt>Description</dt>
<dd>
Queries the role definition.
</dd>
<dt>Method</dt>
<dd>GET</dd>
<dt>URL</dt>
<dd>`/mysql/roles/<name>`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
```javascript
{
"data": {
"sql": "CREATE USER..."
}
}
```
</dd>
</dl>
#### DELETE
<dl class="api">
<dt>Description</dt>
<dd>
Deletes the role definition.
</dd>
<dt>Method</dt>
<dd>DELETE</dd>
<dt>URL</dt>
<dd>`/mysql/roles/<name>`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
</dl>
### /mysql/creds/
#### GET
<dl class="api">
<dt>Description</dt>
<dd>
Generates a new set of dynamic credentials based on the named role.
</dd>
<dt>Method</dt>
<dd>GET</dd>
<dt>URL</dt>
<dd>`/mysql/creds/<name>`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
```javascript
{
"data": {
"username": "root-aefa635a-18",
"password": "132ae3ef-5a64-7499-351e-bfe59f3a2a21"
}
}
```
</dd>
</dl>

View file

@ -1,649 +0,0 @@
---
layout: "docs"
page_title: "Secret Backend: PKI"
sidebar_current: "docs-secrets-pki"
description: |-
The PKI secret backend for Nomad generates TLS certificates.
---
# PKI Secret Backend
Name: `pki`
The PKI secret backend for Nomad generates X.509 certificates dynamically based on configured roles. This means services can get certificates needed for both client and server authentication without going through the usual manual process of generating a private key and CSR, submitting to a CA, and waiting for a verification and signing process to complete. Nomad's built-in authentication and authorization mechanisms provide the verification functionality.
By keeping leases relatively short, revocations are less likely to be needed, keeping CRLs short and helping the backend scale to large workloads. This in turn allows each instance of a running application to have a unique certificate, eliminating sharing and the accompanying pain of revocation and rollover.
In addition, by allowing revocation to mostly be forgone, this backend allows for ephemeral certificates; certificates can be fetched and stored in memory upon application startup and discarded upon shutdown, without ever being written to disk.
This page will show a quick start for this backend. For detailed documentation on every path, use `vault path-help` after mounting the backend.
## Considerations
To successfully deploy this backend, there are a number of important considerations to be aware of, as well as some preparatory steps that should be undertaken. You should read all of these *before* using this backend or generating the CA to use with this backend.
### Never use root CAs
Nomad storage is secure, but not as secure as a piece of paper in a bank vault. It is, after all, networked software. Your long-lived self-signed root CA's private key should instead be used to issue a shorter-lived intermediate CA certificate, and this is what you should put into Nomad. This aligns with industry best practices.
### One CA Certificate, One Backend
In order to vastly simplify both the configuration and codebase of the PKI backend, only one CA certificate is allowed per backend. If you want to issue certificates from multiple CAs, mount the PKI backend at multiple mount points with separate CA certificates in each.
This also provides a convenient method of switching to a new CA certificate while keeping CRLs valid from the old CA certificate; simply mount a new backend and issue from there.
### Keep certificate lifetimes short, for CRL's sake
This backend aligns with Nomad's philosophy of short-lived secrets. As such it is not expected that CRLs will grow large; the only place a private key is ever returned is to the requesting client (this backend does *not* store generated private keys). In most cases, if the key is lost, the certificate can simply be ignored, as it will expire shortly.
If a certificate must truly be revoked, the normal Nomad revocation function can be used; alternately a root token can be used to revoke the certificate using the certificate's serial number. Any revocation action will cause the CRL to be regenerated. When the CRL is regenerated, any expired certificates are removed from the CRL (and any revoked, expired certificate are removed from backend storage).
This backend does not support multiple CRL endpoints with sliding date windows; often such mechanisms will have the transition point a few days apart, but this gets into the expected realm of the actual certificate validity periods issued from this backend. A good rule of thumb for this backend would be to simply not issue certificates with a validity period greater than your maximum comfortable CRL lifetime. Alternately, you can control CRL caching behavior on the client to ensure that checks happen more often.
Often multiple endpoints are used in case a single CRL endpoint is down so that clients don't have to figure out what to do with a lack of response. Run Nomad in HA mode, and the CRL endpoint should be available even if a particular node is down.
### You must configure CRL information *in advance*
This backend serves CRLs from a predictable location. That location must be encoded into your CA certificate if you want to allow applications to use the CRL endpoint encoded in certificates to find the CRL. Instructions for doing so are below. If you need to adjust this later, you will have to generate a new CA certificate using the same private key if you want to keep validity for already-issued certificates.
### No OCSP support, yet
Nomad's architecture does not currently allow for a binary protocol such as OCSP to be supported by a backend. As such, you should configure your software to use CRLs for revocation information, with a caching lifetime that feels good to you. Since you are following the advice above about keeping lifetimes short (right?), CRLs should not grow too large.
## Quick Start
### CA certificate
In order for this backend to serve CRL information at the expected location, you will need to generate your CA certificate with this information. For OpenSSL, this means putting a value in the CA section with the appropriate URL; in this example the PKI backend is mounted at `pki`:
```text
crlDistributionPoints = URI:https://vault.example.com:8200/v1/pki/crl
```
Adjust the URI as appropriate.
### Nomad
The first step to using the PKI backend is to mount it. Unlike the `generic` backend, the `pki` backend is not mounted by default.
```text
$ vault mount pki
Successfully mounted 'pki' at 'pki'!
```
Next, Nomad must be configured with a root certificate and associated private key. This is done by writing the contents of a file or *stdin*:
```text
$ vault write pki/config/ca pem_bundle="@ca_bundle.pem"
Success! Data written to: pki/config/ca
```
or
```
$ cat bundle.pem | vault write pki/config/ca pem_bundle="-"
Success! Data written to: pki/config/ca
```
Although in this example the value being piped into *stdin* could be passed directly into the Nomad CLI command, a more complex usage might be to use [Ansible](http://www.ansible.com) to securely store the certificate and private key in an `ansible-vault` file, then have an `ansible-playbook` command decrypt this value and pass it in to Nomad.
The next step is to configure a role. A role is a logical name that maps to a policy used to generated those credentials. For example, let's create an "example-dot-com" role:
```text
$ vault write pki/roles/example-dot-com \
allowed_base_domain="example.com" \
allow_subdomains="true" lease_max="72h"
Success! Data written to: pki/roles/example-dot-com
```
By writing to the `roles/example-dot-com` path we are defining the `example-dot-com` role. To generate a new set of credentials, we simply write to the `issue` endpoint with that role name: Nomad is now configured to create and manage certificates!
```text
$ vault write pki/issue/example-dot-com common_name=blah.example.com
Key Value
lease_id pki/issue/example-dot-com/819393b5-e1a1-9efd-b72f-4dc3a1972e31
lease_duration 259200
lease_renewable false
certificate -----BEGIN CERTIFICATE-----
MIIECDCCAvKgAwIBAgIUXmLrLkTdBIOOIYg2/BXO7docKfUwCwYJKoZIhvcNAQEL
...
az3gfwlOqVTdgi/ZVAtIzhSEJ0OY136bq4NOaw==
-----END CERTIFICATE-----
issuing_ca -----BEGIN CERTIFICATE-----
MIIDUTCCAjmgAwIBAgIJAKM+z4MSfw2mMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV
...
-----END CERTIFICATE-----
private_key -----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA0cczc7Y2yIu7aD/IaDi23Io+tvvDS9XaXXDUFW1kqd58P83r
...
3xhCNnZ3CMQaM2I48sloVK/XoikMLb5MZwOUQn/V+TrhWP4Lu7qD
-----END RSA PRIVATE KEY-----
serial 5e:62:eb:2e:44:dd:04:83:8e:21:88:36:fc:15:ce:ed:da:1c:29:f5
```
Note that this is a write, not a read, to allow values to be passed in at request time.
Nomad has now generated a new set of credentials using the `example-dot-com` role configuration. Here we see the dynamically generated private key and certificate. The issuing CA certificate is returned as well.
Using ACLs, it is possible to restrict using the pki backend such that trusted operators can manage the role definitions, and both users and applications are restricted in the credentials they are allowed to read.
If you get stuck at any time, simply run `vault path-help pki` or with a subpath for interactive help output.
## API
### /pki/ca(/pem)
#### GET
<dl class="api">
<dt>Description</dt>
<dd>
Retrieves the CA certificate *in raw DER-encoded form*.
This is a bare endpoint that does not return a
standard Nomad data structure. If `/pem` is added to the
endpoint, the CA certificate is returned in PEM format.
<br /><br />This is an unauthenticated endpoint.
</dd>
<dt>Method</dt>
<dd>GET</dd>
<dt>URL</dt>
<dd>`/pki/ca(/pem)`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
```
<binary DER-encoded certficiate>
```
</dd>
</dl>
### /pki/cert/
#### GET
<dl class="api">
<dt>Description</dt>
<dd>
Retrieves one of a selection of certificates. Valid values: `ca`
for the CA certificate, `crl` for the current CRL, or a serial
number in either hyphen-separated or colon-separated octal format.
This endpoint returns the certificate in PEM formatting in the
`certificate` key of the JSON object.
<br /><br />This is an unauthenticated endpoint.
</dd>
<dt>Method</dt>
<dd>GET</dd>
<dt>URL</dt>
<dd>`/pki/cert/<serial>`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
```javascript
{
"data": {
"certificate": "-----BEGIN CERTIFICATE-----\nMIIGmDCCBYCgAwIBAgIHBzEB3fTzhTANBgkqhkiG9w0BAQsFADCBjDELMAkGA1UE\n..."
}
}
...
```
</dd>
</dl>
### /pki/config/ca
#### POST
<dl class="api">
<dt>Description</dt>
<dd>
A PEM file containing the issuing CA certificate
and its private key, concatenated.
<br /><br />This is a root-protected endpoint.
<br /><br />The information can be provided from a file via a `curl`
command similar to the following:<br/>
```text
curl -X POST --data "@cabundle.json" http://127.0.0.1:8200/v1/pki/config/ca -H X-Nomad-Token:06b9d...
```
Note that if you provide the data through the HTTP API it must be
JSON-formatted, with newlines replaced with `\n`, like so:
```text
{ "pem_bundle": "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END CERTIFICATE-----" }
```
</dd>
<dt>Method</dt>
<dd>POST</dd>
<dt>URL</dt>
<dd>`/pki/config/ca`</dd>
<dt>Parameters</dt>
<dd>
<ul>
<li>
<span class="param">pem_bundle</span>
<span class="param-flags">required</span>
The key and certificate concatenated in PEM format.
</li>
</ul>
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
</dl>
### /pki/crl(/pem)
#### GET
<dl class="api">
<dt>Description</dt>
<dd>
Retrieves the current CRL *in raw DER-encoded form*. This endpoint
is suitable for usage in the CRL Distribution Points extension in a
CA certificate. This is a bare endpoint that does not return a
standard Nomad data structure. If `/pem` is added to the endpoint,
the CRL is returned in PEM format.
<br /><br />This is an unauthenticated endpoint.
</dd>
<dt>Method</dt>
<dd>GET</dd>
<dt>URL</dt>
<dd>`/pki/crl(/pem)`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
```
<binary DER-encoded CRL>
```
</dd>
</dl>
### /pki/crl/rotate
#### GET
<dl class="api">
<dt>Description</dt>
<dd>
This endpoint forces a rotation of the CRL. This can be used
by administrators to cut the size of the CRL if it contains
a number of certificates that have now expired, but has
not been rotated due to no further certificates being revoked.
<br /><br />This is a root-protected endpoint.
</dd>
<dt>Method</dt>
<dd>GET</dd>
<dt>URL</dt>
<dd>`/pki/crl/rotate`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
```javascript
{
"data": {
"success": true
}
}
```
</dd>
</dl>
### /pki/issue/
#### POST
<dl class="api">
<dt>Description</dt>
<dd>
Generates a new set of credentials (private key and
certificate) based on the named role. The issuing CA
certificate is returned as well, so that only the root CA
need be in a client's trust store.
<br /><br />*The private key is _not_ stored.
If you do not save the private key, you will need to
request a new certificate.*
</dd>
<dt>Method</dt>
<dd>POST</dd>
<dt>URL</dt>
<dd>`/pki/issue/<name>`</dd>
<dt>Parameters</dt>
<dd>
<ul>
<li>
<span class="param">common_name</span>
<span class="param-flags">required</span>
The requested CN for the certificate. If the CN is allowed
by role policy, it will be issued.
</li>
<li>
<span class="param">alt_names</span>
<span class="param-flags">optional</span>
Requested Subject Alternative Names, in a comma-delimited
list. If any requested names do not match role policy,
the entire request will be denied.
</li>
<li>
<span class="param">ip_sans</span>
<span class="param-flags">optional</span>
Requested IP Subject Alternative Names, in a comma-delimited
list. Only valid if the role allows IP SANs (which is the
default).
</li>
<li>
<span class="param">lease</span>
<span class="param-flags">optional</span>
Requested lease time. Cannot be greater than the role's
`lease_max` parameter. If not provided, the role's `lease`
value will be used.
</li>
</ul>
</dd>
<dt>Returns</dt>
<dd>
```javascript
{
"lease_id": "pki/issue/test/7ad6cfa5-f04f-c62a-d477-f33210475d05",
"renewable": false,
"lease_duration": 21600,
"data": {
"certificate": "-----BEGIN CERTIFICATE-----\nMIIDzDCCAragAwIBAgIUOd0ukLcjH43TfTHFG9qE0FtlMVgwCwYJKoZIhvcNAQEL\n...\numkqeYeO30g1uYvDuWLXVA==\n-----END CERTIFICATE-----\n",
"issuing_ca": "-----BEGIN CERTIFICATE-----\nMIIDUTCCAjmgAwIBAgIJAKM+z4MSfw2mMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV\n...\nG/7g4koczXLoUM3OQXd5Aq2cs4SS1vODrYmgbioFsQ3eDHd1fg==\n-----END CERTIFICATE-----\n",
"private_key": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAnVHfwoKsUG1GDVyWB1AFroaKl2ImMBO8EnvGLRrmobIkQvh+\n...\nQN351pgTphi6nlCkGPzkDuwvtxSxiCWXQcaxrHAL7MiJpPzkIBq1\n-----END RSA PRIVATE KEY-----\n",
"serial": "39:dd:2e:90:b7:23:1f:8d:d3:7d:31:c5:1b:da:84:d0:5b:65:31:58"
},
"auth": null
}
```
</dd>
</dl>
### /pki/revoke
#### POST
<dl class="api">
<dt>Description</dt>
<dd>
Revokes a certificate using its serial number. This is an
alternative option to the standard method of revoking
using Nomad lease IDs. A successful revocation will
rotate the CRL.
<br /><br />This is a root-protected endpoint.
</dd>
<dt>Method</dt>
<dd>POST</dd>
<dt>URL</dt>
<dd>`/pki/revoke`</dd>
<dt>Parameters</dt>
<dd>
<ul>
<li>
<span class="param">serial_number</span>
<span class="param-flags">required</span>
The serial number of the certificate to revoke, in
hyphen-separated or colon-separated octal.
</li>
</ul>
</dd>
<dt>Returns</dt>
<dd>
```javascript
{
"data": {
"revocation_time": 1433269787
}
}
```
</dd>
</dl>
### /pki/roles/
#### POST
<dl class="api">
<dt>Description</dt>
<dd>
Creates or updates the role definition. Note that
the `allowed_base_domain`, `allow_token_displayname`,
`allow_subdomains`, and `allow_any_name` attributes
are additive; between them nearly and across multiple
roles nearly any issuing policy can be accommodated.
`server_flag`, `client_flag`, and `code_signing_flag`
are additive as well. If a client requests a
certificate that is not allowed by the CN policy in
the role, the request is denied.
</dd>
<dt>Method</dt>
<dd>POST</dd>
<dt>URL</dt>
<dd>`/pki/roles/<name>`</dd>
<dt>Parameters</dt>
<dd>
<ul>
<li>
<span class="param">lease</span>
<span class="param-flags">optional</span>
The lease value provided as a string duration
with time suffix. Hour is the largest suffix.
If not set, uses the value of `lease_max`.
</li>
<li>
<span class="param">lease_max</span>
<span class="param-flags">required</span>
The maximum lease value provided as a string duration
with time suffix. Hour is the largest suffix.
</li>
<li>
<span class="param">allow_localhost</span>
<span class="param-flags">optional</span>
If set, clients can request certificates for `localhost`
as one of the requested common names. This is useful
for testing and to allow clients on a single host to
talk securely.
Defaults to true.
</li>
<li>
<span class="param">allowed_base_domain</span>
<span class="param-flags">optional</span>
If set, clients can request certificates for subdomains
directly off of this base domain. _This includes the
wildcard subdomain._ For instance, a base_domain of
`example.com` allows clients to request certificates for
`foo.example.com` and `*.example.com`. To allow further
levels of subdomains, enable the `allow_subdomains` option.
There is no default.
</li>
<li>
<span class="param">allow_token_displayname</span>
<span class="param-flags">optional</span>
If set, clients can request certificates matching
the value of Display Name from the requesting token.
Remember, this stacks with the other CN options,
including `allowed_base_domain`. Defaults to `false`.
</li>
<li>
<span class="param">allow_subdomains</span>
<span class="param-flags">optional</span>
If set, clients can request certificates with CNs that
are subdomains of the CNs allowed by the other role
options. _This includes wildcard subdomains._ This is
redundant when using the `allow_any_name` option.
Defaults to `false`.
</li>
<li>
<span class="param">allow_any_name</span>
<span class="param-flags">optional</span>
If set, clients can request any CN. Useful in some
circumstances, but make sure you understand whether it
is appropriate for your installation before enabling it.
Defaults to `false`.
</li>
<li>
<span class="param">allow_ip_sans</span>
<span class="param-flags">optional</span>
If set, clients can request IP Subject Alternative
Names. Unlike CNs, no authorization checking is
performed except to verify that the given values
are valid IP addresses. Defaults to `true`.
<li>
<span class="param">server_flag</span>
<span class="param-flags">optional</span>
If set, certificates are flagged for server use.
Defaults to `true`.
</li>
<li>
<span class="param">client_flag</span>
<span class="param-flags">optional</span>
If set, certificates are flagged for client use.
Defaults to `true`.
</li>
<li>
<span class="param">code_signing_flag</span>
<span class="param-flags">optional</span>
If set, certificates are flagged for code signing
use. Defaults to `false`.
</li>
<li>
<span class="param">key_type</span>
<span class="param-flags">optional</span>
The type of key to generate for generated private
keys. Currently, `rsa` and `ec` are supported.
Defaults to `rsa`.
</li>
<li>
<span class="param">key_bits</span>
<span class="param-flags">optional</span>
The number of bits to use for the generated keys.
Defaults to `2048`; this will need to be changed for
`ec` keys. See https://golang.org/pkg/crypto/elliptic/#Curve
for an overview of allowed bit lengths for `ec`.
</li>
</ul>
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
</dl>
#### GET
<dl class="api">
<dt>Description</dt>
<dd>
Queries the role definition.
</dd>
<dt>Method</dt>
<dd>GET</dd>
<dt>URL</dt>
<dd>`/pki/roles/<name>`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
```javascript
{
"data": {
"allow_any_name": false,
"allow_ip_sans": true,
"allow_localhost": true,
"allow_subdomains": false,
"allow_token_displayname": false,
"allowed_base_domain": "example.com",
"client_flag": true,
"code_signing_flag": false,
"key_bits": 2048,
"key_type": "rsa",
"lease": "6h",
"lease_max": "12h",
"server_flag": true
}
}
```
</dd>
</dl>
#### DELETE
<dl class="api">
<dt>Description</dt>
<dd>
Deletes the role definition. Deleting a role does <b>not</b> revoke
certificates previously issued under this role.
</dd>
<dt>Method</dt>
<dd>DELETE</dd>
<dt>URL</dt>
<dd>`/pki/roles/<name>`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
</dl>

View file

@ -1,313 +0,0 @@
---
layout: "docs"
page_title: "Secret Backend: PostgreSQL"
sidebar_current: "docs-secrets-postgresql"
description: |-
The PostgreSQL secret backend for Nomad generates database credentials to access PostgreSQL.
---
# PostgreSQL Secret Backend
Name: `postgresql`
The PostgreSQL secret backend for Nomad generates database credentials
dynamically based on configured roles. This means that services that need
to access a database no longer need to hardcode credentials: they can request
them from Nomad, and use Nomad's leasing mechanism to more easily roll keys.
Additionally, it introduces a new ability: with every service accessing
the database with unique credentials, it makes auditing much easier when
questionable data access is discovered: you can track it down to the specific
instance of a service based on the SQL username.
Nomad makes use both of its own internal revocation system as well as the
`VALID UNTIL` setting when creating PostgreSQL users to ensure that users
become invalid within a reasonable time of the lease expiring.
This page will show a quick start for this backend. For detailed documentation
on every path, use `vault path-help` after mounting the backend.
## Quick Start
The first step to using the PostgreSQL backend is to mount it.
Unlike the `generic` backend, the `postgresql` backend is not mounted by default.
```text
$ vault mount postgresql
Successfully mounted 'postgresql' at 'postgresql'!
```
Next, Nomad must be configured to connect to the PostgreSQL. This is done by
writing either a PostgreSQL URL or PG connection string:
```text
$ vault write postgresql/config/connection \
value="postgresql://root:vaulttest@vaulttest.ciuvljjni7uo.us-west-1.rds.amazonaws.com:5432/postgres"
```
In this case, we've configured Nomad with the user "root" and password "vaulttest",
connecting to a PostgreSQL instance in AWS RDS. The "postgres" database name is being used.
It is important that the Nomad user have the `GRANT OPTION` privilege to manage users.
Optionally, we can configure the lease settings for credentials generated
by Nomad. This is done by writing to the `config/lease` key:
```
$ vault write postgresql/config/lease lease=1h lease_max=24h
Success! Data written to: postgresql/config/lease
```
This restricts each credential to being valid or leased for 1 hour
at a time, with a maximum use period of 24 hours. This forces an
application to renew their credentials at least hourly, and to recycle
them once per day.
The next step is to configure a role. A role is a logical name that maps
to a policy used to generated those credentials. For example, lets create
a "readonly" role:
```text
$ vault write postgresql/roles/readonly \
sql="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}';
GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";"
Success! Data written to: postgresql/roles/readonly
```
By writing to the `roles/readonly` path we are defining the `readonly` role.
This role will be created by evaluating the given `sql` statements. By
default, the `{{name}}`, `{{password}}` and `{{expiration}}` fields will be populated by
Nomad with dynamically generated values. This SQL statement is creating
the named user, and then granting it `SELECT` or read-only privileges
to tables in the database. More complex `GRANT` queries can be used to
customize the privileges of the role. See the [PostgreSQL manual](http://www.postgresql.org/docs/9.4/static/sql-grant.html)
for more information.
To generate a new set of credentials, we simply read from that role:
Nomad is now configured to create and manage credentials for Postgres!
```text
$ vault read postgresql/creds/readonly
Key Value
lease_id postgresql/creds/readonly/c888a097-b0e2-26a8-b306-fc7c84b98f07
lease_duration 3600
password 34205e88-0de1-68b7-6267-72d8e32c5d3d
username vault-root-1430162075-7887
```
By reading from the `creds/readonly` path, Nomad has generated a new
set of credentials using the `readonly` role configuration. Here we
see the dynamically generated username and password, along with a one
hour lease.
Using ACLs, it is possible to restrict using the postgresql backend such
that trusted operators can manage the role definitions, and both
users and applications are restricted in the credentials they are
allowed to read.
If you get stuck at any time, simply run `vault path-help postgresql` or with a
subpath for interactive help output.
## API
### /postgresql/config/connection
#### POST
<dl class="api">
<dt>Description</dt>
<dd>
Configures the connection string used to communicate with PostgreSQL.
This is a root protected endpoint.
</dd>
<dt>Method</dt>
<dd>POST</dd>
<dt>URL</dt>
<dd>`/postgresql/config/connection`</dd>
<dt>Parameters</dt>
<dd>
<ul>
<li>
<span class="param">value</span>
<span class="param-flags">required</span>
The PostgreSQL connection URL or PG style string. e.g. "user=foo host=bar"
</li>
</ul>
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
</dl>
### /postgresql/config/lease
#### POST
<dl class="api">
<dt>Description</dt>
<dd>
Configures the lease settings for generated credentials.
If not configured, leases default to 1 hour. This is a root
protected endpoint.
</dd>
<dt>Method</dt>
<dd>POST</dd>
<dt>URL</dt>
<dd>`/postgresql/config/lease`</dd>
<dt>Parameters</dt>
<dd>
<ul>
<li>
<span class="param">lease</span>
<span class="param-flags">required</span>
The lease value provided as a string duration
with time suffix. Hour is the largest suffix.
</li>
<li>
<span class="param">lease_max</span>
<span class="param-flags">required</span>
The maximum lease value provided as a string duration
with time suffix. Hour is the largest suffix.
</li>
</ul>
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
</dl>
### /postgresql/roles/
#### POST
<dl class="api">
<dt>Description</dt>
<dd>
Creates or updates the role definition.
</dd>
<dt>Method</dt>
<dd>POST</dd>
<dt>URL</dt>
<dd>`/postgresql/roles/<name>`</dd>
<dt>Parameters</dt>
<dd>
<ul>
<li>
<span class="param">sql</span>
<span class="param-flags">required</span>
The SQL statements executed to create and configure the role.
Must be semi-colon separated. The '{{name}}', '{{password}}' and
'{{expiration}}' values will be substituted.
</li>
</ul>
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
</dl>
#### GET
<dl class="api">
<dt>Description</dt>
<dd>
Queries the role definition.
</dd>
<dt>Method</dt>
<dd>GET</dd>
<dt>URL</dt>
<dd>`/postgresql/roles/<name>`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
```javascript
{
"data": {
"sql": "CREATE USER..."
}
}
```
</dd>
</dl>
#### DELETE
<dl class="api">
<dt>Description</dt>
<dd>
Deletes the role definition.
</dd>
<dt>Method</dt>
<dd>DELETE</dd>
<dt>URL</dt>
<dd>`/postgresql/roles/<name>`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
</dl>
### /postgresql/creds/
#### GET
<dl class="api">
<dt>Description</dt>
<dd>
Generates a new set of dynamic credentials based on the named role.
</dd>
<dt>Method</dt>
<dd>GET</dd>
<dt>URL</dt>
<dd>`/postgresql/creds/<name>`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
```javascript
{
"data": {
"username": "vault-root-1430158508-126",
"password": "132ae3ef-5a64-7499-351e-bfe59f3a2a21"
}
}
```
</dd>
</dl>

View file

@ -1,656 +0,0 @@
---
layout: "docs"
page_title: "Secret Backend: SSH"
sidebar_current: "docs-secrets-ssh"
description: |-
The SSH secret backend for Nomad generates dynamic SSH keys or One-Time-Passwords.
---
# SSH Secret Backend
Name: `ssh`
Nomad SSH backend generates SSH credentials for remote hosts dynamically. This
backend increases the security by removing the need to share the private key to
everyone who needs access to infrastructures. It also solves the problem of
management and distribution of keys belonging to remote hosts.
This backend supports two types of credential creation: Dynamic and OTP. Both of
them addresses the problems in different ways.
Read and carefully understand both of them and choose the one which best suits
your needs.
This page will show a quick start for this backend. For detailed documentation
on every path, use `vault path-help` after mounting the backend.
----------------------------------------------------
## I. Dynamic Type
Register the shared secret key (having super user privileges) with Nomad and let
Nomad take care of issuing a dynamic secret key every time a client wants to SSH
into the remote host.
When a Nomad authenticated client requests for a dynamic credential, Nomad server
creates a key-pair, uses the previously shared secret key to login to the remote
host and appends the newly generated public key to `~/.ssh/authorized_keys` file for
the desired username. Nomad uses an install script (configurable) to achieve this.
To run this script in super user mode without password prompts, `NOPASSWD` option
for sudoers should be enabled at all remote hosts.
File: `/etc/sudoers`
```hcl
%sudo ALL=(ALL)NOPASSWD: ALL
```
The private key returned to the user will be leased and can be renewed if desired.
Once the key is given to the user, Nomad will not know when it gets used or how many
time it gets used. Therefore, Nomad **WILL NOT** and cannot audit the SSH session
establishments. An alternative is to use OTP type, which audits every SSH request
(see below).
### Mounting SSH
`ssh` backend is not mounted by default. So, the first step in using the SSH backend
is to mount it.
```shell
$ vault mount ssh
Successfully mounted 'ssh' at 'ssh'!
```
Next, we must register infrastructures with Nomad. This is done by writing the role
information. The type of credentials created are determined by the `key_type` option.
To do this, first create a named key and then create a role.
### Registering shared secret key
Create a named key, say `dev_key`, which represents a registered shared private key.
Remember that this key should be of admin user with super user privileges.
```shell
$ vault write ssh/keys/dev_key key=@dev_shared_key.pem
```
### Create a Role
Create a role, say `dynamic_key_role`. All the machines represented by CIDR block
should be accessible through `dev_key` with root privileges.
```shell
$ vault write ssh/roles/dynamic_key_role key_type=dynamic key=dev_key admin_user=username default_user=username cidr_list=x.x.x.x/y
Success! Data written to: ssh/roles/dynamic_key_role
```
Use the `install_script` option to provide an install script if hosts does not
resemble typical Linux machine. The default script is compiled into the binary.
It is straight forward and is shown below. The script takes three arguments which
are explained in the comments.
```shell
# This script file installs or uninstalls an RSA public key to/from authoried_keys
# file in a typical linux machine. This script should be registered with vault
# server while creating a role for key type 'dynamic'.
# $1: "install" or "uninstall"
#
# $2: File name containing public key to be installed. Nomad server uses UUID
# as file name to avoid collisions with public keys generated for requests.
#
# $3: Absolute path of the authorized_keys file.
if [ $1 != "install" && $1 != "uninstall" ]; then
exit 1
fi
# If the key being installed is already present in the authorized_keys file, it is
# removed and the result is stored in a temporary file.
grep -vFf $2 $3 > temp_$2
# Contents of temporary file will be the contents of authorized_keys file.
cat temp_$2 | sudo tee $3
if [ $1 == "install" ]; then
# New public key is appended to authorized_keys file
cat $2 | sudo tee --append $3
fi
# Auxiliary files are deleted
rm -f $2 temp_$2
```
### Create a credential
Create a dynamic key for an IP that belongs to `dynamic_key_role`.
```shell
$ vault write ssh/creds/dynamic_key_role ip=x.x.x.x
Key Value
lease_id ssh/creds/dynamic_key_role/8c4d2042-23bc-d6a8-42c2-6ff01cb83cf8
lease_duration 600
lease_renewable true
ip x.x.x.x
key -----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA5V/Y95qfGaUXRPkKNK9jgDHXPD2n5Ein+QTNnLSGrHtJUH7+
pgs/5Hc4//124P9qHNmjIYQVyvcLreFgSrQCq4K8193hmypBYtsvCgvpc+jEwaGA
zK0QV7uc1z8KL7FuRAxpHJwB6+nubOzzqM03xsViHRhaWhYVHw2Vl4oputSHE7R9
ugaTRg67wge4Nyi5RRL0RQcmW15/Vop8B6HpBSmZQy3enjg+32KbOWCMMTAPuF9/
DgxSgZQaFMjGN4RjDreZI8Vv5zIiFJzZ3KVOWy8piI0PblLnDpU4Q0QSQ9A+Vr7b
JS22Lbet1Zbapl/n947/r1wGObLCc5Lilu//1QIDAQABAoIBAHWLfdO9sETjHp6h
BULkkpgScpuTeSN6vGHXvUrOFKn1cCfJPNR4tWBuXI6LJM2+9nEccwXs+4IMwjZ0
ZfVCdI/SKtZxBXmP2PxBGMUMP7G/mn0kN64sDlD3ezOvQZgZVEmZFpCrvixYsG+v
qlpZ+HhrlJEWds7tvBsyyfNjwWjVIpm08zBmteFj4zu7OEcmGXEHDoxDXxyVP2BG
eLU/fM5JA2UEjfCQ1MIZ3rBtPePdz4LRpb+ajklqrUj1OHoiDrXa8EAf0/wDP9re
c1iH4bn7ZjYK0+IhZ+Pmw6gUftzZNWSC2kOLnZLdN/K7hgh0l0r0K/1eeXt43upB
WALNuiECgYEA8PM2Ob3XXKALF86PUewne4fCz9iixr/cIpvrEGrh9lyQRO8X5Jxb
ug38jEql4a574C6TSXfzxURza4P6lnfa0LvymmW0bhxZ5nev9kcAVnLKvpOUArTR
32k9bKXd6zp8Q9ZyVNwHRxcVs4YgwfJlcx8geC4o6YRiIjvcBQ9RVHkCgYEA87OK
lZDFBeEY/HVOxAQNXS5fgTd4U4DbwEJLv7SPk02v9oDkGHkpgMs4PcsIpCzsTpJ0
oXMfLSxZ1lmZiuUvAupKj/7RjJ0XyjSMfm1Zs81epWj+boVfM4amZNHVLIWgddmM
XzXEZKByvi1gs7qFcjQz2DEbZltWO6dX14O4Fz0CgYEAlWSWyHJWZ02r0xT1c7vS
NxtTxH7zXftzR9oYgtNiStfVc4gy7kGr9c3aOjnGZAlFMRhvpevDrxnj3lO0OTsS
5rzBjM1mc6cMboLjDPW01eTSpBroeE0Ym0arGQQ2djSK+5yowsixknhTsj2FbfsW
v6wa+6jTIQY9ujAXGOQIbzECgYAYuXlw7SwgCZNYYappFqQodQD5giAyEJu66L74
px/96N7WWoNJvFkqmPOOyV+KEIi0/ATbMGvUUHCY36RFRDU9zXldHJQz+Ogl+qja
VsvIAyj8DSfrHJrpBlsxVVyUVMZPzo+ARVs0flbF1qK9+Ul6qbMs1uaZvuCD0tmF
ovZ1XQKBgQDB0s7SDmAMgVjG8UBZgUru9vsDrxERT2BloptnnAjSiarLF5M+qeZO
7L4NLyVP39Z83eerEonzDAHHbvhPyi6n2YmnYhGjeP+lPZIVqGF9cpZD3q48YHZc
3ePn2/oLZrXKWOMyMwp2Uj+0SArCW+xMnoNp50sYNVR/JK3BPIdkag==
-----END RSA PRIVATE KEY-----
key_type dynamic
port 22
username username
```
### Establish an SSH session
Save the key to a file, say `dyn_key.pem`, and then use it to establish an SSH session.
```shell
$ ssh -i dyn_key.pem username@ip
username@ip:~$
```
### Automate it!
Creation of new key, saving it in a file and establishing an SSH session will all be done
via a single Nomad CLI.
```shell
$ vault ssh -role dynamic_key_role username@ip
username@ip:~$
```
----------------------------------------------------
## II. One-Time-Password (OTP) Type
Install Nomad SSH Agent in remote hosts and let Nomad server issue an OTP every time
a client wants to SSH into remote hosts.
Nomad authenticated clients request for a credential from Nomad server and get an OTP
issued. When clients try to establish SSH connection with the remote host, OTP typed
in at the password prompt will be received by the Nomad agent and gets validated
by the Nomad server. Nomad server deletes the OTP after validating it once (hence one-time).
Since Nomad server is contacted for every successful connection establishment, unlike
Dynamic type, every login attempt **WILL** be audited.
See [Nomad-SSH-Agent](https://github.com/hashicorp/vault-ssh-agent) for details
on how to configure the agent.
### Mounting SSH
`ssh` backend is not mounted by default and needs to be explicitly mounted. This is
a common step for both OTP and Dynamic types.
```shell
$ vault mount ssh
Successfully mounted 'ssh' at 'ssh'!
```
### Creating a Role
Create a role, say `otp_key_role` for key type `otp`. All the machines represented
by CIDR block should have agent installed in them and have their SSH configuration
modified to support Nomad SSH Agent client authentication.
```shell
$ vault write ssh/roles/otp_key_role key_type=otp default_user=username cidr_list=x.x.x.x/y,m.m.m.m/n
Success! Data written to: ssh/roles/otp_key_role
```
### Create a Credential
Create an OTP credential for an IP that belongs to `otp_key_role`.
```shell
$ vault write ssh/creds/otp_key_role ip=x.x.x.x
Key Value
lease_id ssh/creds/otp_key_role/73bbf513-9606-4bec-816c-5a2f009765a5
lease_duration 600
lease_renewable false
port 22
username username
ip x.x.x.x
key 2f7e25a2-24c9-4b7b-0d35-27d5e5203a5c
key_type otp
```
### Establish an SSH session
```shell
$ ssh username@localhost
Password: <Enter OTP>
username@ip:~$
```
### Automate it!
Creation of new OTP and running SSH command can be done via a single CLI.
```shell
$ vault ssh -role otp_key_role username@x.x.x.x
OTP for the session is `b4d47e1b-4879-5f4e-ce5c-7988d7986f37`
[Note: Install `sshpass` to automate typing in OTP]
Password: <Enter OTP>
```
OTP will be typed in using `sshpass` if it is installed.
```shell
$ vault ssh -role otp_key_role username@x.x.x.x
username@ip:~$
```
----------------------------------------------------
## API
### /ssh/config/lease
#### POST
<dl class="api">
<dt>Description</dt>
<dd>
Configures the lease settings for generated credentials.
This is a root protected endpoint.
</dd>
<dt>Method</dt>
<dd>POST</dd>
<dt>URL</dt>
<dd>`/ssh/config/lease`</dd>
<dt>Parameters</dt>
<dd>
<ul>
<li>
<span class="param">lease</span>
<span class="param-flags">required</span>
(String)
The lease value provided as a duration
with time suffix. Hour is the largest suffix.
</li>
<li>
<span class="param">lease_max</span>
<span class="param-flags">required</span>
(String)
The maximum lease value provided as a duration
with time suffix. Hour is the largest suffix.
</li>
</ul>
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
</dl>
### /ssh/keys/
#### POST
<dl class="api">
<dt>Description</dt>
<dd>
Creates or updates a named key. This is a root protected endpoint.
</dd>
<dt>Method</dt>
<dd>POST</dd>
<dt>URL</dt>
<dd>`/ssh/keys/<key name>`</dd>
<dt>Parameters</dt>
<dd>
<ul>
<li>
<span class="param">key</span>
<span class="param-flags">required</span>
(String)
SSH private key with super user privileges in host
</li>
</ul>
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
#### GET
<dl class="api">
<dt>Description</dt>
<dd>
Queries a named key. This is a root protected endpoint.
</dd>
<dt>Method</dt>
<dd>GET</dd>
<dt>URL</dt>
<dd>`/ssh/keys/<key name>`</dd>
<dt>Parameters</dt>
<dd>None</dd>
<dt>Returns</dt>
<dd>
```javascript
{
"key": "-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEAvYvoRcWRxqOim5VZnuM6wHCbLUeiND0yaM1tvOl+Fsrz55DG\nA0OZp4RGAu1Fgr46E1mzxFz1+zY4UbcEExg+u21fpa8YH8sytSWW1FyuD8ICib0A\n/l8slmDMw4BkkGOtSlEqgscpkpv/TWZD1NxJWkPcULk8z6c7TOETn2/H9mL+v2RE\nmbE6NDEwJKfD3MvlpIqCP7idR+86rNBAODjGOGgyUbtFLT+K01XmDRALkV3V/nh+\nGltyjL4c6RU4zG2iRyV5RHlJtkml+UzUMkzr4IQnkCC32CC/wmtoo/IsAprpcHVe\nnkBn3eFQ7uND70p5n6GhN/KOh2j519JFHJyokwIDAQABAoIBAHX7VOvBC3kCN9/x\n+aPdup84OE7Z7MvpX6w+WlUhXVugnmsAAVDczhKoUc/WktLLx2huCGhsmKvyVuH+\nMioUiE+vx75gm3qGx5xbtmOfALVMRLopjCnJYf6EaFA0ZeQ+NwowNW7Lu0PHmAU8\nZ3JiX8IwxTz14DU82buDyewO7v+cEr97AnERe3PUcSTDoUXNaoNxjNpEJkKREY6h\n4hAY676RT/GsRcQ8tqe/rnCqPHNd7JGqL+207FK4tJw7daoBjQyijWuB7K5chSal\noPInylM6b13ASXuOAOT/2uSUBWmFVCZPDCmnZxy2SdnJGbsJAMl7Ma3MUlaGvVI+\nTfh1aQkCgYEA4JlNOabTb3z42wz6mz+Nz3JRwbawD+PJXOk5JsSnV7DtPtfgkK9y\n6FTQdhnozGWShAvJvc+C4QAihs9AlHXoaBY5bEU7R/8UK/pSqwzam+MmxmhVDV7G\nIMQPV0FteoXTaJSikhZ88mETTegI2mik+zleBpVxvfdhE5TR+lq8Br0CgYEA2AwJ\nCUD5CYUSj09PluR0HHqamWOrJkKPFPwa+5eiTTCzfBBxImYZh7nXnWuoviXC0sg2\nAuvCW+uZ48ygv/D8gcz3j1JfbErKZJuV+TotK9rRtNIF5Ub7qysP7UjyI7zCssVM\nkuDd9LfRXaB/qGAHNkcDA8NxmHW3gpln4CFdSY8CgYANs4xwfercHEWaJ1qKagAe\nrZyrMpffAEhicJ/Z65lB0jtG4CiE6w8ZeUMWUVJQVcnwYD+4YpZbX4S7sJ0B8Ydy\nAhkSr86D/92dKTIt2STk6aCN7gNyQ1vW198PtaAWH1/cO2UHgHOy3ZUt5X/Uwxl9\ncex4flln+1Viumts2GgsCQKBgCJH7psgSyPekK5auFdKEr5+Gc/jB8I/Z3K9+g4X\n5nH3G1PBTCJYLw7hRzw8W/8oALzvddqKzEFHphiGXK94Lqjt/A4q1OdbCrhiE68D\nMy21P/dAKB1UYRSs9Y8CNyHCjuZM9jSMJ8vv6vG/SOJPsnVDWVAckAbQDvlTHC9t\nO98zAoGAcbW6uFDkrv0XMCpB9Su3KaNXOR0wzag+WIFQRXCcoTvxVi9iYfUReQPi\noOyBJU/HMVvBfv4g+OVFLVgSwwm6owwsouZ0+D/LasbuHqYyqYqdyPJQYzWA2Y+F\n+B6f4RoPdSXj24JHPg/ioRxjaj094UXJxua2yfkcecGNEuBQHSs=\n-----END RSA PRIVATE KEY-----\n"
}
```
</dd>
#### DELETE
<dl class="api">
<dt>Description</dt>
<dd>
Deletes a named key. This is a root protected endpoint.
</dd>
<dt>Method</dt>
<dd>DELETE</dd>
<dt>URL</dt>
<dd>`/ssh/keys/<key name>`</dd>
<dt>Parameters</dt>
<dd>None</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
### /ssh/roles/
#### POST
<dl class="api">
<dt>Description</dt>
<dd>
Creates or updates a named role.
</dd>
<dt>Method</dt>
<dd>POST</dd>
<dt>URL</dt>
<dd>`/ssh/roles/<role name>`</dd>
<dt>Parameters</dt>
<dd>
<ul>
<li>
<span class="param">key</span>
<span class="param-flags">required for Dynamic type, NA for OTP type</span>
(String)
Name of the registered key in Nomad. Before creating the role, use
the `keys/` endpoint to create a named key.
</li>
<li>
<span class="param">admin_user</span>
<span class="param-flags">required for Dynamic type, NA for OTP type</span>
(String)
Admin user at remote host. The shared key being registered should be
for this user and should have root privileges. Everytime a dynamic
credential is being generated for other users, Nomad uses this admin
username to login to remote host and install the generated credential
for the other user.
</li>
<li>
<span class="param">default_user</span>
<span class="param-flags">required for both types</span>
(String)
Default username for which a credential will be generated.
When the endpoint 'creds/' is used without a username, this
value will be used as default username.
</li>
<li>
<span class="param">cidr_list</span>
<span class="param-flags">required for both types</span>
(String)
Comma separated list of CIDR blocks for which the role is applicable for.
CIDR blocks can belong to more than one role.
</li>
<li>
<span class="param">port</span>
<span class="param-flags">optional for both types</span>
(Integer)
Port number for SSH connection. Default is '22'. Port number does not
play any role in creation of OTP. For 'otp' type, this is just a way
to inform client about the port number to use. Port number will be
returned to client by Nomad server along with OTP.
</li>
<li>
<span class="param">key_type</span>
<span class="param-flags">required for both types</span>
(String)
Type of key used to login to hosts. It can be either `otp` or `dynamic`.
`otp` type requires agent to be installed in remote hosts.
</li>
<li>
<span class="param">key_bits</span>
<span class="param-flags">optional for Dynamic type, NA for OTP type</span>
(Integer)
Length of the RSA dynamic key in bits. It is 1024 by default or it can be 2048.
</li>
<li>
<span class="param">install_script</span>
<span class="param-flags">optional for Dynamic type, NA for OTP type</span>
(String)
Script used to install and uninstall public keys in the target machine.
The inbuilt default install script will be for Linux hosts.
</li>
<li>
<span class="param">allowed_users</span>
<span class="param-flags">optional for both types</span>
(String)
If this option is not specified, client can request for a credential for
any valid user at the remote host, including the admin user. If only certain
usernames are to be allowed, then this list enforces it. If this field is
set, then credentials can only be created for default_user and usernames
present in this list.
</li>
</ul>
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
#### GET
<dl class="api">
<dt>Description</dt>
<dd>
Queries a named role.
</dd>
<dt>Method</dt>
<dd>GET</dd>
<dt>URL</dt>
<dd>`/ssh/roles/<role name>`</dd>
<dt>Parameters</dt>
<dd>None</dd>
<dt>Returns</dt>
<dd>For dynamic role:
```json
{
"admin_user": "username",
"cidr_list": "x.x.x.x/y",
"default_user": "username",
"key": "<key name>",
"key_type": "dynamic",
"port": 22
}
```
</dd>
<dd>For OTP role:
```json
{
"cidr_list": "x.x.x.x/y",
"default_user": "username",
"key_type": "otp",
"port": 22
}
```
</dd>
#### DELETE
<dl class="api">
<dt>Description</dt>
<dd>
Deletes a named role.
</dd>
<dt>Method</dt>
<dd>DELETE</dd>
<dt>URL</dt>
<dd>`/ssh/roles/<role name>`</dd>
<dt>Parameters</dt>
<dd>None</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
### /ssh/creds/
#### POST
<dl class="api">
<dt>Description</dt>
<dd>
Creates a credential for a specific username and IP under the given role.
</dd>
<dt>Method</dt>
<dd>POST</dd>
<dt>URL</dt>
<dd>`/ssh/creds/<role name>`</dd>
<dt>Parameters</dt>
<dd>
<ul>
<li>
<span class="param">username</span>
<span class="param-flags">optional</span>
(String)
Username in remote host.
</li>
<li>
<span class="param">ip</span>
<span class="param-flags">required</span>
(String)
IP of the remote host.
</li>
</ul>
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
### /ssh/lookup
#### POST
<dl class="api">
<dt>Description</dt>
<dd>
Lists all the roles given IP is associated with.
</dd>
<dt>Method</dt>
<dd>POST</dd>
<dt>URL</dt>
<dd>`/ssh/lookup`</dd>
<dt>Parameters</dt>
<dd>
<ul>
<li>
<span class="param">ip</span>
<span class="param-flags">required</span>
(String)
IP of the remote host.
</li>
</ul>
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
### /ssh/verify
#### POST
<dl class="api">
<dt>Description</dt>
<dd>
Verifies if the given OTP is valid. This is an unauthenticated endpoint.
</dd>
<dt>Method</dt>
<dd>POST</dd>
<dt>URL</dt>
<dd>`/ssh/verify`</dd>
<dt>Parameters</dt>
<dd>
<ul>
<li>
<span class="param">otp</span>
<span class="param-flags">required</span>
(String)
One-Time-Key that needs to be validated.
</li>
</ul>
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>

View file

@ -1,342 +0,0 @@
---
layout: "docs"
page_title: "Secret Backend: Transit"
sidebar_current: "docs-secrets-transit"
description: |-
The transit secret backend for Nomad encrypts/decrypts data in-transit. It doesn't store any secrets.
---
# Transit Secret Backend
Name: `transit`
The transit secret backend is used to encrypt/data in-transit. Nomad doesn't
store the data sent to the backend. It can also be viewed as "encryption as
a service."
The primary use case for the transit backend is to encrypt data from
applications while still storing that encrypted data in some primary data
store. This relieves the burden of proper encryption/decryption from
application developers and pushes the burden onto the operators of Nomad.
Operators of Nomad generally include the security team at an organization,
which means they can ensure that data is encrypted/decrypted properly.
As of Nomad 0.2, the transit backend also supports doing key derivation. This
allows data to be encrypted within a context such that the same context must be
used for decryption. This can be used to enable per transaction unique keys which
further increase the security of data at rest.
Additionally, since encrypt/decrypt operations must enter the audit log,
any decryption event is recorded.
This page will show a quick start for this backend. For detailed documentation
on every path, use `vault path-help` after mounting the backend.
## Quick Start
The first step to using the transit backend is to mount it. Unlike the `generic`
backend, the `transit` backend is not mounted by default.
```
$ vault mount transit
Successfully mounted 'transit' at 'transit'!
```
The next step is to create a named encryption key. A named key is used so that
many different applications can use the transit backend with independent keys.
This is done by doing a write against the backend:
```
$ vault write -f transit/keys/foo
Success! Data written to: transit/keys/foo
```
This will create the "foo" named key in the transit backend. We can inspect
the settings of the "foo" key by reading it:
```
$ vault read transit/keys/foo
Key Value
name foo
cipher_mode aes-gcm
derived false
````
We can read from the `raw/` endpoint to see the encryption key itself:
```
$ vault read transit/raw/foo
Key Value
name foo
cipher_mode aes-gcm
key PhKFTALCmhAhVQfMBAH4+UwJ6J2gybapUH9BsrtIgR8=
derived false
````
Here we can see that the randomly generated encryption key being used, as
well as the AES-GCM cipher mode. We don't need to know any of this to use
the key however.
Now, if we wanted to encrypt a piece of plain text, we use the encrypt
endpoint using our named key:
```
$ echo -n "the quick brown fox" | base64 | vault write transit/encrypt/foo plaintext=-
Key Value
ciphertext vault:v0:czEwyKqGZY/limnuzDCUUe5AK0tbBObWqeZgFqxCuIqq7A84SeiOq3sKD0Y/KUvv
```
The encryption endpoint expects the plaintext to be provided as a base64 encoded
strings, so we must first convert it. Nomad does not store the plaintext or the
ciphertext, but only handles it _in transit_ for processing. The application
is free to store the ciphertext in a database or file at rest.
To decrypt, we simply use the decrypt endpoint using the same named key:
```
$ vault write transit/decrypt/foo ciphertext=vault:v0:czEwyKqGZY/limnuzDCUUe5AK0tbBObWqeZgFqxCuIqq7A84SeiOq3sKD0Y/KUvv
Key Value
plaintext dGhlIHF1aWNrIGJyb3duIGZveAo=
$ echo "dGhlIHF1aWNrIGJyb3duIGZveAo=" | base64 -D
the quick brown fox
```
Using ACLs, it is possible to restrict using the transit backend such
that trusted operators can manage the named keys, and applications can
only encrypt or decrypt using the named keys they need access to.
## API
### /transit/keys/
#### POST
<dl class="api">
<dt>Description</dt>
<dd>
Creates a new named encryption key. This is a root protected endpoint.
</dd>
<dt>Method</dt>
<dd>POST</dd>
<dt>URL</dt>
<dd>`/transit/keys/<name>`</dd>
<dt>Parameters</dt>
<dd>
<ul>
<li>
<span class="param">derived</span>
<span class="param-flags">optional</span>
Boolean flag indicating if key derivation MUST be used.
If enabled, all encrypt/decrypt requests to this named key
must provide a context which is used for key derivation.
Defaults to false.
</li>
</ul>
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
</dl>
#### GET
<dl class="api">
<dt>Description</dt>
<dd>
Returns information about a named encryption key.
This is a root protected endpoint.
</dd>
<dt>Method</dt>
<dd>GET</dd>
<dt>URL</dt>
<dd>`/transit/keys/<name>`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
```javascript
{
"data": {
"name": "foo",
"cipher_mode": "aes-gcm",
"derived": "true",
"kdf_mode": "hmac-sha256-counter",
}
}
```
</dd>
</dl>
#### DELETE
<dl class="api">
<dt>Description</dt>
<dd>
Deletes a named encryption key. This is a root protected endpoint.
All data encrypted with the named key will no longer be decryptable.
</dd>
<dt>Method</dt>
<dd>DELETE</dd>
<dt>URL</dt>
<dd>`/transit/keys/<name>`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
A `204` response code.
</dd>
</dl>
### /transit/encrypt/
#### POST
<dl class="api">
<dt>Description</dt>
<dd>
Encrypts the provided plaintext using the named key. If the named key
does not already exist, it will be automatically generated for the given
name with the default parameters.
</dd>
<dt>Method</dt>
<dd>POST</dd>
<dt>URL</dt>
<dd>`/transit/encrypt/<name>`</dd>
<dt>Parameters</dt>
<dd>
<ul>
<li>
<span class="param">plaintext</span>
<span class="param-flags">required</span>
The plaintext to encrypt, provided as base64 encoded.
</li>
<li>
<span class="param">context</span>
<span class="param-flags">optional</span>
The key derivation context, provided as base64 encoded.
Must be provided if the derivation enabled.
</li>
</ul>
</dd>
<dt>Returns</dt>
<dd>
```javascript
{
"data": {
"ciphertext": "vault:v0:abcdefgh"
}
}
```
</dd>
</dl>
### /transit/decrypt/
#### POST
<dl class="api">
<dt>Description</dt>
<dd>
Decrypts the provided ciphertext using the named key.
</dd>
<dt>Method</dt>
<dd>POST</dd>
<dt>URL</dt>
<dd>`/transit/decrypt/<name>`</dd>
<dt>Parameters</dt>
<dd>
<ul>
<li>
<span class="param">ciphertext</span>
<span class="param-flags">required</span>
The ciphertext to decrypt, provided as returned by encrypt.
</li>
<li>
<span class="param">context</span>
<span class="param-flags">optional</span>
The key derivation context, provided as base64 encoded.
Must be provided if the derivation enabled.
</li>
</ul>
</dd>
<dt>Returns</dt>
<dd>
```javascript
{
"data": {
"plaintext": "dGhlIHF1aWNrIGJyb3duIGZveAo="
}
}
```
</dd>
</dl>
### /transit/raw/
#### GET
<dl class="api">
<dt>Description</dt>
<dd>
Returns raw information about a named encryption key,
Including the underlying encryption key. This is a root protected endpoint.
</dd>
<dt>Method</dt>
<dd>GET</dd>
<dt>URL</dt>
<dd>`/transit/raw/<name>`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
```javascript
{
"data": {
"name": "foo",
"cipher_mode": "aes-gcm",
"key": "PhKFTALCmhAhVQfMBAH4+UwJ6J2gybapUH9BsrtIgR8="
"derived": "true",
"kdf_mode": "hmac-sha256-counter",
}
}
```
</dd>
</dl>

View file

@ -120,44 +120,24 @@
<li<%= sidebar_current("docs-drivers") %>>
<a href="/docs/drivers/index.html">Drivers</a>
<ul class="nav">
<li<%= sidebar_current("docs-secrets-aws") %>>
<a href="/docs/secrets/aws/index.html">AWS</a>
<li<%= sidebar_current("docs-drivers-docker") %>>
<a href="/docs/drivers/docker/index.html">Docker</a>
</li>
<li<%= sidebar_current("docs-secrets-consul") %>>
<a href="/docs/secrets/consul/index.html">Consul</a>
<li<%= sidebar_current("docs-drivers-exec") %>>
<a href="/docs/drivers/exec/index.html">Fork/Exec</a>
</li>
<li<%= sidebar_current("docs-secrets-pki") %>>
<a href="/docs/secrets/pki/index.html">PKI (Certificates)</a>
<li<%= sidebar_current("docs-drivers-java") %>>
<a href="/docs/drivers/java/index.html">Java</a>
</li>
<li<%= sidebar_current("docs-secrets-postgresql") %>>
<a href="/docs/secrets/postgresql/index.html">PostgreSQL</a>
<li<%= sidebar_current("docs-drivers-qeumu") %>>
<a href="/docs/drivers/qemu/index.html">Qemu</a>
</li>
<li<%= sidebar_current("docs-secrets-mysql") %>>
<a href="/docs/secrets/mysql/index.html">MySQL</a>
</li>
<li<%= sidebar_current("docs-secrets-cassandra") %>>
<a href="/docs/secrets/cassandra/index.html">Cassandra</a>
</li>
<li<%= sidebar_current("docs-secrets-ssh") %>>
<a href="/docs/secrets/ssh/index.html">SSH</a>
</li>
<li<%= sidebar_current("docs-secrets-transit") %>>
<a href="/docs/secrets/transit/index.html">Transit</a>
</li>
<li<%= sidebar_current("docs-secrets-generic") %>>
<a href="/docs/secrets/generic/index.html">Generic</a>
</li>
<li<%= sidebar_current("docs-secrets-custom") %>>
<a href="/docs/secrets/custom.html">Custom</a>
<li<%= sidebar_current("docs-drivers-custom") %>>
<a href="/docs/drivers/custom.html">Custom</a>
</li>
</ul>
</li>