Inhaltsverzeichnis
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: <kms-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: <base64-encoded-ca> 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 Key Vault - Azure integration
- AWS KMS - AWS integration
- Kubernetes Cert-Manager - K8s PKI
« <- AWS KMS | -> Operator Scenarios »
Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional
Zuletzt geändert: on 2026/01/30 at 01:26 AM