Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Readme improvements #7

Merged
merged 6 commits into from
Sep 7, 2016
44 changes: 25 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,26 @@
### Status: Experimental POC (Read: Do NOT use for production)

#### To Dos:
* Create catalog entry
* Make work with TLS production Vault setup (currently only works with a Dev Vault configuration).
* Add support for K8s and Swarm
* Create catalog entry.
* Cattle needs signature verification call.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot to remove k8s. It works there now.



---
#### Purpose:
This is a first pass at a service that validates container identity from Rancher and then provides access to Vault. Rancher nor this service actually manage secrets in Vault, that is still left to the user and Vault. What this service will do is create Vault Tokens with policies allowed by the token provided to the service. The token obtained from this service is then used to communicate directly with Vault.
The Secrets Bridge service is a standardized way of integrating Rancher and Vault such that Docker containers at startup are securely connected with their secrets within Vault. The Secrets Bridge service is composed of a server and agents. At container startup, the service first validates the container's identity with Rancher, and then provides the container with access to Vault. Neither Rancher nor the service actually manages any secrets within Vault; that is still left to the user and Vault. What this service will do is create Vault Tokens which are assigned a subset of policies allowed by the initial grantor-default token provided to the Secrets Bridge server at startup. The app token obtained through this service is then used by the container to communicate directly with Vault. This allows a user to define a custom process in their containers that can inject the secrets it reads from Vault into the app that ultimately uses them, using whatever custom input methods required by the user's app.

#### How it works:

In Vault, a user will create a Role for this service, scoping to an environment is probably a good idea. This Role should be assigned all of the Vault policies you need it to create tokens for. Vault only lets you create tokens for a subset of your own assigned tokens.
In Vault, a user will create a Role for this service; scoping to an environment is probably a good idea. This Role should be assigned all of the Vault policies you need it to create tokens for. Vault only lets you create tokens for a subset of your own assigned tokens.

To accomplish this, you need to create some default policies for the `secrets-bridge` along with a Vault Cubbyhole. See Vaults documentation for more details on Cubbyholes, this service relies heavily on them.
To accomplish this, you need to create some default policies for the `secrets-bridge` along with a Vault Cubbyhole. See Vaults documentation for more details on Cubbyholes, as this service relies heavily on them.

A service would then be deployed into an operators/tools/non-application environment. This item will likely be launchable from the catalog.

Once the server side service is deployed, you would then deploy the agents into your application environment. These agents then listen for Docker events and send container start events to the service.
Once the server side service is deployed, you would then deploy the agents into your application environment. These agents then listen for Docker container start events. If your container has the secrets.bridge.enabled and nameKey labels correctly set then the agent will send that container's start event to the service.

The service then verifies with Rancher (see notes/todos below) the containers Identity. If the identity can not be verified, then nothing else happens. If the container is verified, the service checks for a policy key set on the config service tokens config path. If a policy is found, it then generates a temporary token to create a Cubbyhole and a permanent token with the applied policy. The permanent key is placed into the Cubbyhole with the temporary key, which will have a short TTL and 1 more use to get the permanent key.
The service then verifies with Rancher (see notes/todos below) the container's Identity. If the identity can not be verified, then nothing else happens. If the container is verified, the service checks for a policy key set on the config service tokens config path. If a policy is found, the service then generates a temporary token to create a Cubbyhole and a permanent token with the applied policy. The permanent key is placed into the Cubbyhole with the temporary key, which will have a short TTL and 1 more use to get the permanent key.

The response to the agent contains, the Docker container ID (from Rancher), the Vault path of the Cubbyhole and the Temporary token. From this, the Agent does a Docker copy of the Cubbyhole information to: `/tmp/secrets.txt` on the target container.
The response to the agent contains: the Docker container ID (from Rancher), the Vault path of the Cubbyhole, and the Temporary token. From this, the Agent performs a Docker copy of the Cubbyhole information to: `/tmp/secrets.txt` inside the target container.

A process inside the container can then read those credentials to get the permanent key and use Vault as it normally would.

Expand Down Expand Up @@ -66,7 +63,7 @@ path "secret/*" {
capabilities = ["deny"]
}
```
`Note: default is lower-cased within name grantor-default b/c the vault write command converts the name to lowercase. And the name within the auth/token/create/ must be consistent for path searches.`
`Note: default is lower-cased within name grantor-default b/c the vault write command converts the name to lowercase. And the name within the auth/token/create/ must be consistent for path searches.`

This policy gives the `grantor-default` role the ability to grant tokens.

Expand Down Expand Up @@ -117,7 +114,7 @@ export VAULT_ADDR=http://xxx.xxx.xxx.xxx:$VAULT_PORT
export ROOT_TOKEN=62c08fb4-e635-6a2d-f315-002e374e2ff1
export RANCHER_ENVIRONMENT_API_URL=http://xxx.xxx.xxx.xxy:XXXX/v1/projects/YYY
```
Set RANCHER_ENVIRONMENT_API_URL to the URL of API key for the Rancher Environment being used. For example, RANCHER_ENVIRONMENT_API_URL=http://192.168.101.128:8080/v1/projects/1a5
Set RANCHER_ENVIRONMENT_API_URL to the URL of API key for the Rancher Environment being used. For example, RANCHER_ENVIRONMENT_API_URL=http://192.168.101.128:8080/v1/projects/1a5

##### Step 4: Create grantor-default role

Expand All @@ -128,24 +125,25 @@ curl -s -X POST -H "X-Vault-Token: ${VAULT_TOKEN}" -d '{"allowed_policies": "def
##### Step 5: Assign policies to applications

```
vault write secrets/secrets-bridge/Default/Stack1/app1 policies=default,app1
vault write secrets/secrets-bridge/Default/Stack2/app2 policies=default,app2
vault write secret/secrets-bridge/Default/Stack1/app1 policies=default,app1
vault write secret/secrets-bridge/Default/Stack2/app2 policies=default,app2
```

##### Step 6: Configure Vault for Secrets-Bridge startup

Start but creating a temporary token with a TTL of 15m and a max usage of 2 attempts (1st used to place permanent token within cubbyhole; 2nd usage is when secrets-bridge starts up and contacts Vault to get permanent token)
Start by creating a permanent token for the grantor-default role. This token will be used by the secrets-bridge to interact with Vault and create temp tokens for applications.

```
TEMP_TOKEN=$(curl -s -H "X-Vault-Token: $ROOT_TOKEN" ${VAULT_URL}/v1/auth/token/create -d '{"policies": ["default"], "ttl": "15m", "num_uses": 2}' | jq -r '.auth.client_token')
PERM_TOKEN=$(curl -s -X POST -H "X-Vault-Token: $ROOT_TOKEN" ${VAULT_URL}/v1/auth/token/create/grantor-default -d '{"policies": ["default", "grantor-default", "app1", "app2"], "ttl": "72h", "meta": {"configPath": "secret/secrets-bridge/Default"}}' | jq -r '.auth.client_token')
```
Then create a permanent token for the grantor-default role. This token will be used by the secrets-bride to interact with Vault and create temp tokens for applications.

Then create a temporary token with a TTL of 15m and a max usage of 2 attempts (1st used to place permanent token within cubbyhole; 2nd usage is when secrets-bridge starts up and contacts Vault to get permanent token)

```
PERM_TOKEN=$(curl -s -X POST -H "X-Vault-Token: $ROOT_TOKEN" ${VAULT_URL}/v1/auth/token/create/grantor-default -d '{"policies": ["default", "grantor-default", "app1", "app2"], "ttl": "72h", "meta": {"configPath": "secret/secrets-bridge/Default"}}' | jq -r '.auth.client_token')
TEMP_TOKEN=$(curl -s -H "X-Vault-Token: $ROOT_TOKEN" ${VAULT_URL}/v1/auth/token/create -d '{"policies": ["default"], "ttl": "15m", "num_uses": 2}' | jq -r '.auth.client_token')
```

Finally, place the permanent token within a cubbyhole using the temporary token. The secrets bridge will use the temporary token (2nd and final usage) to retrieve the permanent token from the cubbyhole when it starts up.
Finally, place the permanent token within a cubbyhole using the temporary token. The secrets bridge will use the temporary token (2nd and final usage) to retrieve the permanent token from the cubbyhole when it starts up.

```
curl -X POST -H "X-Vault-Token: ${TEMP_TOKEN}" ${VAULT_URL}/v1/cubbyhole/Default -d "{\"permKey\": \"${PERM_TOKEN}\"}"
Expand All @@ -163,3 +161,11 @@ secrets-bridge server --vault-url $VAULT_ADDR --rancher-url $RANCHER_ENVIRONMENT
```
secrets-bridge agent --bridge-url http://[IP Of Secrets Bridge Server]:8181
```

#### Debugging:

To enable debug output the '-d' flag has to be placed before any of the other command line arguments. For example:

```
secrets-bridge -d agent --bridge-url http://[IP Of Secrets Bridge Server]:8181
```