open-vault/website/source/guides/cubbyhole.html.md

275 lines
7.5 KiB
Markdown
Raw Normal View History

2018-01-10 19:14:59 +00:00
---
layout: "guides"
page_title: "Cubbyhole Response Wrapping - Guides"
sidebar_current: "guides-cubbyhole"
description: |-
Vault provides a capability to wrap Vault response and store it in a
"cubbyhole" where the holder of the one-time use wrapping token can unwrap to
uncover the secret.
---
# Cubbyhole
The term _cubbyhole_ comes from an Americnaism where you get a "locker" or "safe
place" to store your belongings or valuables. In Vault, cubbyhole is your
"locker". All secrets are namespaced under **your token**. If that token
expires or is revoked, all the secrets in its cubbyhole are revoked as well.
It is not possible to reach into another token's cubbyhole even as the root
user. This is the key difference between the cubbyhole and the key/value secret
backend. The secrets in the key/value backends are accessible to any token for as
long as its policy allows it.
## Reference Material
- [Cubbyhole](/docs/secrets/cubbyhole/index.html)
- [Response Wrapping](/docs/concepts/response-wrapping.html)
## Estimated Time to Complete
10 minutes
## Challenge
In order to tightly manage the secrets, you set the scope of who can do what
using the [Vault policy](/docs/concepts/policies.html) and attach that to
tokens, roles, entities, etc.
How to securely distribute the initial token to a machine or app?
## Solution
Use Vault's **cubbyhole response wrapping** where the initial token is stored in
the cubbyhole backend. The wrapped secret can be unwrap using the single use
wrapping token. Even the user or the system created the initial token won't see
the original value. The wrapping token is short-lived and can be revoked just
like any other tokens so that the risk of unauthorized access can be minimized.
## Prerequisites
To perform the tasks described in this guide, you need to have a Vault
2018-01-18 01:39:21 +00:00
environment. Refer to the [Getting
Started](/intro/getting-started/install.html) guide to install Vault.
2018-01-10 19:14:59 +00:00
2018-01-18 01:39:21 +00:00
Make sure that your Vault server has been [initialized and
unsealed](/intro/getting-started/deploy.html).
2018-01-10 19:14:59 +00:00
## Steps
To distribute the initial token to an app using cubbyhole response wrapping, you
perform the following tasks:
1. Create and wrap a token
2. Unwrap the secret
### Step 1: Create and wrap a token
When the response to `vault token-create` request is wrapped, Vault inserts the
generated token it into the cubbyhole of a single-use token, returning that
single-use wrapping token. Retrieving the secret requires an unwrap operation
against this wrapping token.
#### CLI command
```shell
vault token-create -policy=<POLICY_NAME> -wrap-ttl=<WRAP_TTL>
```
Where the `<WRAP_TTL>` is a numeric string indicating the TTL of the response.
**Example:**
```shell
vault token-create -policy=app-policy -wrap-ttl=60s
Key Value
--- -----
wrapping_token: 9ac59985-094f-a2de-aed8-bf688e436fbc
wrapping_token_ttl: 1m0s
wrapping_token_creation_time: 2018-01-10 00:47:54.970185208 +0000 UTC
wrapping_token_creation_path: auth/token/create
wrapped_accessor: 195763a9-3f26-1fcf-6a1a-ee0a11e76cb1
```
#### API call using cURL
2018-01-18 01:39:21 +00:00
Before begin, create the following environment variables for your convenience:
- **VAULT_ADDR** is set to your Vault server address
- **VAULT_TOKEN** is set to your Vault token
**Example:**
```plaintext
$ export VAULT_ADDR=http://127.0.0.1:8201
$ export VAULT_TOKEN=0c4d13ba-9f5b-475e-faf2-8f39b28263a5
```
2018-01-10 19:14:59 +00:00
Response wrapping is per-request and is triggered by providing to Vault the
desired TTL for a response-wrapping token for that request. This is set using
the **`X-Vault-Wrap-TTL`** header in the request and can be either an integer
number of seconds or a string duration.
**Example:**
```text
curl -X POST -H "X-Vault-Token: $VAULT_TOKEN" -H "X-Vault-Wrap-TTL: 60s" \
-d '{"policies":["app-policy"]}' $VAULT_ADDR/v1/auth/token/create | jq
{
"request_id": "",
"lease_id": "",
"renewable": false,
"lease_duration": 0,
"data": null,
"wrap_info": {
"token": "e095129f-123a-4fef-c007-1f6a487cfa78",
"ttl": 60,
"creation_time": "2018-01-10T01:43:38.025351336Z",
"creation_path": "auth/token/create",
"wrapped_accessor": "44e8253c-65b4-1690-1bf1-7902a7a6b2aa"
},
"warnings": null,
"auth": null
}
```
### Step 2: Unwrap the secret
The client uses the wrapping token to unwrap the secret.
**NOTE:**
If a client has been expecting delivery of a response-wrapping token and none
arrives, this may be due to an attacker intercepting the token and then
preventing it from traveling further. This should cause an alert to trigger an
immediate investigation.
#### CLI command
```text
vault unwrap <WRAPPING_TOKEN>
```
Or
```text
VAULT_TOKEN=<WRAPPING_TOKEN> vault unwrap
```
2018-01-18 01:39:21 +00:00
In this scenario, the wrapped secret is a Vault token. Therefore, it probably
makes better sense to use the second option.
2018-01-10 19:14:59 +00:00
**Example:**
```shell
2018-01-18 01:39:21 +00:00
$ VAULT_TOKEN=9ac59985-094f-a2de-aed8-bf688e436fbc vault unwrap
2018-01-10 19:14:59 +00:00
Key Value
--- -----
token 7bb915b2-8a44-48b0-a71d-72b590252016
token_accessor 195763a9-3f26-1fcf-6a1a-ee0a11e76cb1
token_duration 768h0m0s
token_renewable true
token_policies [app-policy default]
```
#### API call using cURL
To enable the AppRole auth backend via API:
```text
curl -X POST -H "X-Vault-Token: $WRAPPING_TOKEN" $VAULT_ADDR/v1/sys/wrapping/unwrap | jq
{
"request_id": "d704435d-c1cf-b8a3-52f6-ec50bc8246c4",
"lease_id": "",
"renewable": false,
"lease_duration": 0,
"data": null,
"wrap_info": null,
"warnings": null,
"auth": {
"client_token": "af5f7682-aa55-fa37-5039-ee116df56600",
"accessor": "19b5407e-b304-7cde-e946-54942325d3c1",
"policies": [
"app-policy",
"default"
],
"metadata": null,
"lease_duration": 2764800,
"renewable": true
}
}
```
2018-01-18 01:39:21 +00:00
## Additional Discussion
2018-01-10 19:14:59 +00:00
Similar to the key/value secret backend, the cubbyhole backend is mounted at the
**`cubbyhole/`** prefix by default. The secrets you store in the `cubbyhole/` path
are tied to your token and only accessible by you.
To test the cubbyhole secret backend, perform the following steps.
First, create `tester` policy which grants permissions on the path under `cubbyhole/private/` prefix.
```text
$ vault policy-write tester tester.hcl
$ cat tester.hcl
path "cubbyhole/private/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
```
Create a token attached to the `tester` policy, and then authenticate using the
token.
```text
$ vault token-create -policy=tester
Key Value
--- -----
token 2ba26888-b531-1626-3598-01ea4aa383bb
token_accessor 28cbd05c-31a3-0aaa-4dca-838a9aafe4cb
token_duration 768h0m0s
token_renewable true
token_policies [default tester]
$ unset VAULT_TOKEN
$ vault auth 2ba26888-b531-1626-3598-01ea4aa383bb
Successfully authenticated! You are now logged in.
token: 2ba26888-b531-1626-3598-01ea4aa383bb
token_duration: 2764651
token_policies: [default tester]
```
You should be able to write secrets under `cubbyhole/private/` path, and read it
back.
```text
$ vault write cubbyhole/private/access-token token="123456789abcdefg87654321"
Success! Data written to: cubbyhole/private/access-token
$ vault read cubbyhole/private/access-token
Key Value
--- -----
token 123456789abcdefg87654321
```
Now, try to access the secret using the root token, you shouldn't be able to
read.
```text
VAULT_TOKEN=<ROOT_TOKEN> vault read cubbyhole/private/access-token
No value found at cubbyhole/private/access-token
```
Also, refer to [Cubbyhole Secret Backend HTTP API](/api/secret/cubbyhole/index.html).
## Next steps