====== HashiCorp Vault ====== **Cloud:** Multi-Cloud / On-Premises \\ **HSM Level:** FIPS 140-2 Level 2 (Transit SE) \\ **PQ Support:** Possible via custom plugins HashiCorp Vault as central secrets and PKI management for multi-cloud environments. ---- ===== Architecture ===== flowchart TB subgraph VAULT["HASHICORP VAULT"] subgraph ENGINES["Secret Engines"] PKI[PKI Engine] KV[KV Secrets] Transit[Transit] end subgraph AUTH["Auth Methods"] K8S[Kubernetes] OIDC[OIDC] AWS[AWS IAM] AZURE[Azure] end end subgraph CONSUMERS["CONSUMERS"] EKS[AWS EKS] AKS[Azure AKS] GKE[GCP GKE] VM[VMs] end PKI --> EKS & AKS & GKE & VM K8S --> EKS & AKS & GKE AWS --> EKS AZURE --> AKS style VAULT fill:#e8f5e9 style PKI fill:#fff3e0 ---- ===== Installation ===== ==== Docker (Development) ==== # Development mode (not for production!) docker run -d --name vault \ -p 8200:8200 \ -e 'VAULT_DEV_ROOT_TOKEN_ID=root' \ -e 'VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:8200' \ hashicorp/vault:latest ==== Production (Helm) ==== # Helm repository helm repo add hashicorp https://helm.releases.hashicorp.com # Create values cat > vault-values.yaml << 'EOF' server: ha: enabled: true replicas: 3 raft: enabled: true dataStorage: size: 10Gi auditStorage: enabled: true size: 10Gi ingress: enabled: true hosts: - host: vault.example.com extraEnvironmentVars: VAULT_SEAL_TYPE: awskms VAULT_AWSKMS_SEAL_KEY_ID: injector: enabled: true EOF # Installation helm install vault hashicorp/vault \ --namespace vault \ --create-namespace \ -f vault-values.yaml ---- ===== PKI Engine ===== ==== Create Root CA ==== # Enable PKI engine vault secrets enable -path=pki pki # Set max TTL vault secrets tune -max-lease-ttl=87600h pki # Generate Root CA vault write pki/root/generate/internal \ common_name="Example Root CA" \ issuer_name="root-2024" \ ttl=87600h \ key_type=ec \ key_bits=384 # Configure CRL/OCSP URLs vault write pki/config/urls \ issuing_certificates="https://vault.example.com/v1/pki/ca" \ crl_distribution_points="https://vault.example.com/v1/pki/crl" \ ocsp_servers="https://vault.example.com/v1/pki/ocsp" ==== Create Intermediate CA ==== # Intermediate PKI engine vault secrets enable -path=pki_int pki vault secrets tune -max-lease-ttl=43800h pki_int # Generate CSR vault write -format=json pki_int/intermediate/generate/internal \ common_name="Example Intermediate CA" \ issuer_name="intermediate-2024" \ key_type=ec \ key_bits=384 \ | jq -r '.data.csr' > intermediate.csr # Sign with Root vault write -format=json pki/root/sign-intermediate \ csr=@intermediate.csr \ format=pem_bundle \ ttl=43800h \ | jq -r '.data.certificate' > intermediate.pem # Import signed certificate vault write pki_int/intermediate/set-signed \ certificate=@intermediate.pem ==== Role for Certificate Issuance ==== # Server certificate role vault write pki_int/roles/server-cert \ allowed_domains="example.com" \ allow_subdomains=true \ max_ttl=720h \ key_type=ec \ key_bits=384 \ require_cn=false \ allow_any_name=false # Client certificate role vault write pki_int/roles/client-cert \ allowed_domains="example.com" \ allow_subdomains=true \ client_flag=true \ server_flag=false \ max_ttl=720h ==== Issue Certificate ==== # Server certificate vault write pki_int/issue/server-cert \ common_name="server.example.com" \ alt_names="server.example.com,server" \ ttl=720h # Client certificate vault write pki_int/issue/client-cert \ common_name="client@example.com" \ ttl=720h ---- ===== Kubernetes Integration ===== ==== Kubernetes Auth ==== # Enable Kubernetes auth vault auth enable kubernetes # Kubernetes config vault write auth/kubernetes/config \ kubernetes_host="https://kubernetes.default.svc" \ kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt # Role for cert-manager vault write auth/kubernetes/role/cert-manager \ bound_service_account_names=cert-manager \ bound_service_account_namespaces=cert-manager \ policies=pki-issue \ ttl=1h ==== Policy ==== # pki-issue.hcl path "pki_int/issue/server-cert" { capabilities = ["create", "update"] } path "pki_int/sign/server-cert" { capabilities = ["create", "update"] } path "pki_int/roles/server-cert" { capabilities = ["read"] } vault policy write pki-issue pki-issue.hcl ==== Cert-Manager Vault Issuer ==== # vault-issuer.yaml apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: vault-issuer spec: vault: path: pki_int/sign/server-cert server: https://vault.example.com caBundle: auth: kubernetes: role: cert-manager mountPath: /v1/auth/kubernetes serviceAccountRef: name: cert-manager # certificate.yaml apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: app-tls namespace: production spec: secretName: app-tls-secret issuerRef: name: vault-issuer kind: ClusterIssuer dnsNames: - app.example.com ---- ===== Vault Agent Sidecar ===== # pod-with-vault-agent.yaml apiVersion: v1 kind: Pod metadata: name: app-with-certs annotations: vault.hashicorp.com/agent-inject: "true" vault.hashicorp.com/role: "app-role" vault.hashicorp.com/agent-inject-secret-tls.crt: "pki_int/issue/server-cert" vault.hashicorp.com/agent-inject-template-tls.crt: | {{- with secret "pki_int/issue/server-cert" "common_name=app.example.com" -}} {{ .Data.certificate }} {{ .Data.issuing_ca }} {{- end }} vault.hashicorp.com/agent-inject-secret-tls.key: "pki_int/issue/server-cert" vault.hashicorp.com/agent-inject-template-tls.key: | {{- with secret "pki_int/issue/server-cert" "common_name=app.example.com" -}} {{ .Data.private_key }} {{- end }} spec: serviceAccountName: app-sa containers: - name: app image: myapp:latest volumeMounts: - name: tls mountPath: /etc/tls readOnly: true ---- ===== Transit Engine (Signing) ===== # Enable Transit engine vault secrets enable transit # Create signing key vault write transit/keys/signing-key \ type=ecdsa-p384 # Sign vault write transit/sign/signing-key \ input=$(echo -n "data to sign" | base64) # Verify vault write transit/verify/signing-key \ input=$(echo -n "data to sign" | base64) \ signature="vault:v1:..." ---- ===== Audit Logging ===== # File audit backend vault audit enable file file_path=/var/log/vault/audit.log # Syslog backend vault audit enable syslog tag="vault" facility="LOCAL0" # Socket backend (for ELK) vault audit enable socket address="logstash.example.com:5000" socket_type="tcp" ---- ===== High Availability ===== # vault-config.hcl storage "raft" { path = "/vault/data" node_id = "node1" } listener "tcp" { address = "0.0.0.0:8200" tls_cert_file = "/vault/tls/tls.crt" tls_key_file = "/vault/tls/tls.key" } seal "awskms" { region = "eu-central-1" kms_key_id = "alias/vault-unseal" } api_addr = "https://vault-0.vault:8200" cluster_addr = "https://vault-0.vault:8201" ---- ===== Checklist ===== | # | Checkpoint | Done | |---|------------|------| | 1 | Vault installed (HA) | | | 2 | PKI engine configured | | | 3 | Root + Intermediate CA | | | 4 | Roles defined | | | 5 | Kubernetes auth | | | 6 | Audit logging | | | 7 | Auto-unseal configured | | | 8 | Backup strategy | | ---- ===== Related Documentation ===== * [[.:azure-keyvault|Azure Key Vault]] - Azure integration * [[.:aws-kms|AWS KMS]] - AWS integration * [[..:automatisierung:cert-manager-k8s|Kubernetes Cert-Manager]] - K8s PKI ---- << [[.:aws-kms|<- AWS KMS]] | [[..:start|-> Operator Scenarios]] >> ---- //Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional// {{tag>vault hashicorp pki multi-cloud kubernetes operator}}