199 lines
4.7 KiB
Markdown
199 lines
4.7 KiB
Markdown
# Vault
|
|
|
|
## Prereqs
|
|
|
|
```bash
|
|
brew tap hashicorp/tap
|
|
brew install hashicorp/tap/vault
|
|
|
|
brew install jq
|
|
```
|
|
|
|
## Install (Standalone)
|
|
|
|
```bash
|
|
kubectl apply -f certificate.yaml
|
|
|
|
helm repo add hashicorp https://helm.releases.hashicorp.com
|
|
helm search repo hashicorp/vault
|
|
helm upgrade --install vault hashicorp/vault --values values.yaml
|
|
|
|
mkdir ~/.vault-keys
|
|
kubectl exec -ti vault-0 -- vault operator init -key-shares=5 -key-threshold=3 -format=json > ~/.vault-keys/cluster-keys.json
|
|
kubectl exec -ti vault-0 -- vault operator unseal
|
|
```
|
|
|
|
## Install (Cluster)
|
|
|
|
```bash
|
|
kubectl apply -f certificate.yaml
|
|
|
|
helm repo add hashicorp https://helm.releases.hashicorp.com
|
|
helm search repo hashicorp/vault
|
|
helm upgrade --install vault hashicorp/vault --values values.yaml
|
|
|
|
mkdir ~/.vault-keys
|
|
kubectl exec -ti vault-0 -- vault operator init -key-shares=5 -key-threshold=3 -format=json > ~/.vault-keys/cluster-keys.json
|
|
kubectl exec -ti vault-0 -- vault operator unseal
|
|
|
|
kubectl exec -ti vault-1 -- vault operator raft join http://vault-0.vault-internal:8200
|
|
kubectl exec -ti vault-1 -- vault operator unseal
|
|
|
|
kubectl exec -ti vault-2 -- vault operator raft join http://vault-0.vault-internal:8200
|
|
kubectl exec -ti vault-2 -- vault operator unseal
|
|
```
|
|
|
|
## Add policy
|
|
|
|
```bash
|
|
vault policy write ducoterra policies/ducoterra.hcl
|
|
```
|
|
|
|
## Add user
|
|
|
|
```bash
|
|
vault auth enable userpass
|
|
vault write auth/userpass/users/ducoterra \
|
|
policies=ducoterra \
|
|
password=password
|
|
```
|
|
|
|
## Enable KV Secrets
|
|
|
|
```bash
|
|
vault secrets enable -path=secret kv-v2
|
|
|
|
vault kv put secret/okta username='static-user' password='static-password'
|
|
vault kv get secret/okta
|
|
```
|
|
|
|
## TOTP
|
|
|
|
```bash
|
|
vault secrets enable totp
|
|
|
|
vault write totp/keys/okta \
|
|
url="otpauth://totp/Vault:test@test.com?secret=SECRET&issuer=Vault"
|
|
|
|
vault read totp/code/okta
|
|
```
|
|
|
|
Policy:
|
|
|
|
```bash
|
|
path "totp/keys/*" {
|
|
capabilities = ["update"]
|
|
}
|
|
|
|
path "totp/code/*" {
|
|
capabilities = ["read"]
|
|
}
|
|
```
|
|
|
|
## Kubernetes Secrets
|
|
|
|
```bash
|
|
kubectl exec -it vault-0 -- /bin/sh
|
|
|
|
vault login -method=token <token>
|
|
vault auth enable kubernetes
|
|
|
|
vault write auth/kubernetes/config \
|
|
token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
|
|
kubernetes_host="https://$KUBERNETES_PORT_443_TCP_ADDR:443" \
|
|
kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
|
|
|
|
vault policy write internal-app - <<EOF
|
|
path "internal/data/database/config" {
|
|
capabilities = ["read"]
|
|
}
|
|
EOF
|
|
|
|
vault write auth/kubernetes/role/internal-app \
|
|
bound_service_account_names=internal-app \
|
|
bound_service_account_namespaces=gitlab \
|
|
policies=internal-app \
|
|
ttl=24h
|
|
|
|
rm /home/vault/.vault-token
|
|
```
|
|
|
|
Set your kube config to the namespace you want to use vault with
|
|
|
|
```bash
|
|
kubectl apply -f service-account-internal-app.yaml
|
|
```
|
|
|
|
Add secrets to your pod
|
|
|
|
```bash
|
|
spec:
|
|
template:
|
|
metadata:
|
|
annotations:
|
|
vault.hashicorp.com/agent-inject: "true"
|
|
vault.hashicorp.com/role: "internal-app"
|
|
vault.hashicorp.com/agent-inject-secret-database-config.txt: "internal/data/database/config"
|
|
```
|
|
|
|
## Gitlab Integration
|
|
|
|
### Enable JWT auth for Gitlab
|
|
|
|
```bash
|
|
# Enable jwt auth
|
|
vault auth enable jwt
|
|
|
|
# Create a policy
|
|
vault policy write myproject-production - <<EOF
|
|
# Policy name: myproject-production
|
|
#
|
|
# Read-only permission on 'secret/data/myproject/production/*' path
|
|
path "secret/data/myproject/production/*" {
|
|
capabilities = [ "read" ]
|
|
}
|
|
EOF
|
|
|
|
# Create a role
|
|
vault write auth/jwt/role/myproject-production - <<EOF
|
|
{
|
|
"role_type": "jwt",
|
|
"policies": ["myproject-production"],
|
|
"token_explicit_max_ttl": 60,
|
|
"user_claim": "user_email",
|
|
"bound_claims_type": "glob",
|
|
"bound_claims": {
|
|
"project_id": "22",
|
|
"ref_protected": "true",
|
|
"ref_type": "branch",
|
|
"ref": "auto-deploy-*"
|
|
}
|
|
}
|
|
EOF
|
|
|
|
# Write the auth method
|
|
vault write auth/jwt/config \
|
|
jwks_url="https://gitlab.ducoterra.net/-/jwks" \
|
|
bound_issuer="gitlab.ducoterra.net"
|
|
```
|
|
|
|
### Pipeline syntax
|
|
|
|
```yaml
|
|
read_secrets:
|
|
script:
|
|
# Check job's ref name
|
|
- echo $CI_COMMIT_REF_NAME
|
|
# and is this ref protected
|
|
- echo $CI_COMMIT_REF_PROTECTED
|
|
# Vault's address can be provided here or as CI/CD variable
|
|
- export VAULT_ADDR=https://vault.ducoterra.net
|
|
# Authenticate and get token. Token expiry time and other properties can be configured
|
|
# when configuring JWT Auth - https://www.vaultproject.io/api/auth/jwt#parameters-1
|
|
- export VAULT_TOKEN="$(vault write -field=token auth/jwt/login role=myproject-production jwt=$CI_JOB_JWT)"
|
|
# Now use the VAULT_TOKEN to read the secret and store it in environment variable
|
|
- export PASSWORD="$(vault kv get -field=password secret/myproject/production/db)"
|
|
# Use the secret
|
|
- echo $PASSWORD
|
|
```
|