Skip to content
This repository has been archived by the owner on Mar 18, 2023. It is now read-only.

Commit

Permalink
Merge pull request #84 from stakater/update-vault-usage
Browse files Browse the repository at this point in the history
update vault usage doc
  • Loading branch information
cuttingedge1109 authored Mar 4, 2021
2 parents b245a8e + e05f66d commit fdc9778
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 98 deletions.
Binary file added content/sre/secrets/images/vault_cli.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/sre/secrets/images/vault_oidc_login.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/sre/secrets/images/vault_token.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
140 changes: 42 additions & 98 deletions content/sre/secrets/vault.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,118 +28,62 @@ Tokens are created on demand with a specified expiry time and can be revoked at

For detailed documentation: [Vault Documentation](https://learn.hashicorp.com/vault#getting-started)

# Setting up Vault
# Vault usage

Along with other tools stakater cloud provides vault as a built-in and recommended feature. Stakater is responsible for
deploying it and hands-over the further configuration part to the end user.
In our set-up we leverage on vault agent for lifecycle management of tokens, that are used for authentication.
There are 2 kinds of secrets in the vault.
* Secrets for managed applications provided by Stakater (ex: Nexus repository credential)
Users only have read permission.
The path is `managed-addons/*`.
* Tenant specific secrets.
Users can create/delete/update/read secrets on the `TENANT_NAME/*` path.

![vault-agent](./images/vault-agent.png)
Users can manage secrets via vault UI or vault CLI.

## Choosing Auth Method
## Using Vault UI

For simplicity we use [Kubernetes auth method](https://www.vaultproject.io/docs/auth/kubernetes.html) to authenticate
the clients using a Kubernetes Service Account Token but you can configure
vault to use any of the [auth methods](https://www.vaultproject.io/docs/auth) based on your requirements.
Once the user is included in any tenants, he can access to the Vault UI using OIDC authentication.

## Prerequisites
![vault-oidc-login](./images/vault_oidc_login.png)

On your local machine you should have curl, jq, [vault cli](https://www.vaultproject.io/docs/install) and [openshift cli](https://docs.openshift.com/container-platform/4.2/cli_reference/openshift_cli/getting-started-cli.html#cli-installing-cli_cli-developer-commands)
**Step**
* Access https://stakater-vault-openshift-stakater-vault.CLUSTER_DOMAIN
* Select `OIDC` method on `Sing in to Vault` page.
* Keep `Role` as default.
* Click `Sign in with OIDC Provider` and sign in to the proper IdP.

## Configuring vault

[[toc]]

### Make vault service accessible

Run `oc port-forward -n stakater-vault service/vault 8200:8200 &` to access vault service at https://127.0.0.1:8200
Alternatively, you can create a route/ingress for the service as well but that is not recommended since we are not exposing our
vault for the external world or services, no access outside the cluster.

### Run the following commands

```shell script

# Directory that will contain vault unseal key and root token
mkdir -p vault-secrets
Users can do all actions on the path `TENANT_NAME/*`.

export VAULT_ADDR=https://127.0.0.1:8200
- Enable/disable any kinds of secret engines

# Initialize a vault server
curl \
--insecure \
--silent \
--request PUT \
--data '{"secret_shares": 1, "secret_threshold": 1}' \
${VAULT_ADDR}/v1/sys/init | tee \
>(jq -r '.root_token' > vault-secrets/root-token) \
>(jq -r '.keys[0]' > vault-secrets/unseal-key)

# Export unseal key and root token as environment variables, these are used for authentication
export KEYS=`cat vault-secrets/unseal-key`
export ROOT_TOKEN=`cat vault-secrets/root-token`
export VAULT_TOKEN=$ROOT_TOKEN
- Create/update/get/list/delete secrets

# Unseal vault to make it usable
vault operator unseal -tls-skip-verify $KEYS
## Using Vault CLI

# Set VAULT_SA_NAME to the service account you created earlier
export VAULT_SA_NAME=$(oc get sa vault -o jsonpath="{.secrets[*]['name']}" | grep -o '\S*vault-token\S*' | uniq)
To use vault CLI, the token is required. Users can get/renew/revoke the token on the UI. (Click the user account Avatar.)

# Set SA_JWT_TOKEN value to the service account JWT used to access the TokenReview API
export SA_JWT_TOKEN=$(oc get secret $VAULT_SA_NAME -o jsonpath="{.data.token}" | base64 --decode; echo)
![vault-token](./images/vault_token.png)

# Set SA_CA_CRT to the PEM encoded CA cert used to talk to Kubernetes API
export SA_CA_CRT=$(oc get secret $VAULT_SA_NAME -o jsonpath="{.data['ca\.crt']}" | base64 --decode; echo)
Once token is fetched, users can use the CLI provided by UI. So there is no need to install vault CLI.

export K8S_HOST="https://kubernetes.default.svc:443"
![vault-cli](./images/vault_cli.png)

# Enable Kubernetes Auth Method
vault auth enable -tls-skip-verify kubernetes

# Write config
vault write -tls-skip-verify auth/kubernetes/config \
token_reviewer_jwt="$SA_JWT_TOKEN" \
kubernetes_host="$K8S_HOST" \
kubernetes_ca_cert="$SA_CA_CRT"

# Create Admin Policy
echo '
path "secret/*" {
capabilities = ["read", "list", "create", "update", "delete"]
}' | vault policy write -tls-skip-verify default-policy -

# Create Read Policy
echo '
path "secret/*" {
capabilities = ["read"]
}' | vault policy write -tls-skip-verify read-policy -

# Enable KV secrets
vault secrets enable --tls-skip-verify -path=secret kv

# Create a role for binding the policy to a service account
vault write -tls-skip-verify auth/kubernetes/role/default-role \
bound_service_account_names=default \
bound_service_account_namespaces=default \
policies=default-policy \
ttl=24h
```bash
vault login token=${TOKEN}
```

# Write sample secret
vault kv put -tls-skip-verify secret/helloworld ttl=1m username=test-user password=dummy-pass
## Consuming vault secrets in pods

# Retrieve to verify that it worked
vault kv get -tls-skip-verify secret/helloworld
```
There are different ways to consume vault secrets in a pod

At this point vault is up and ready to use.
1. Vault API
2. Inject secrets via sidecar

# Important
### 1. Vault API

`vault-secrets/root-token` and `vault-secrets/unseal-keys` are used for communication with vault via CLI and they should
be stored somewhere safe.
TBD

# Vault usage example
### 2. Inject vault secrets in pods

For consuming secrets that are stored in vault, we leverage on vault agent. Vault agent adds init containers and side-car
containers for populating secrets and managing token lifecycle.
Expand All @@ -148,7 +92,7 @@ containers for populating secrets and managing token lifecycle.

Let's go through a demonstration:

## Make vault accessible and set environment variables
#### Make vault accessible and set environment variables

```shell script
oc port-forward -n stakater-vault service/vault 8200:8200 &`
Expand All @@ -159,7 +103,7 @@ export ROOT_TOKEN=`cat vault-secrets/root-token`
export VAULT_TOKEN=$ROOT_TOKEN
```

## Create namespace
#### Create namespace

Create a namespace to deploy our sample application that consumes secret stored in vault. We need to label the namespace
with `vault.hashicorp.com/agent-webhook=enabled` to enable the injection of vault sidecars.
Expand All @@ -173,7 +117,7 @@ metadata:
vault.hashicorp.com/agent-webhook: enabled
```

## Create service account
#### Create service account

```yaml
apiVersion: v1
Expand All @@ -185,7 +129,7 @@ metadata:
app: vault-agent-demo
```

## Create a role in vault for authentication
#### Create a role in vault for authentication

```shell script
# Create a role for binding the policy to a service account
Expand All @@ -196,14 +140,14 @@ vault write -tls-skip-verify auth/kubernetes/role/stakater-vault-demo-role \
ttl=24h
```

## Create a secret
#### Create a secret

```shell script
# Write sample secret
vault kv put -tls-skip-verify secret/helloworld ttl=1m username=test-user password=dummy-pass
```

## Required Annotations
#### Add Required Annotations

To inject secrets, we must use the following annotations:

Expand All @@ -216,7 +160,7 @@ To inject secrets, we must use the following annotations:
- `vault.hashicorp.com/agent-inject-template-{path-to-secret}`: Specify template to use for rendering the secrets


## Deploy the application
#### Deploy the application

```yaml
apiVersion: apps/v1
Expand Down Expand Up @@ -259,6 +203,6 @@ spec:
cat /vault/secrets/helloworld
```

## Verify
#### Verify

You can verify the workflow through logs of the application pod.

0 comments on commit fdc9778

Please sign in to comment.