Files
kms/examples/google-cloud-hsm/kubernetes/deployment.yaml
zeekay 44bc0cdcdf feat: sync Cloud HSM providers from lux/kms
- AWS CloudHSM (FIPS 140-2 Level 3, PKCS#11)
- Google Cloud KMS
- Zymbit (edge HSM)
- Examples for all three providers
- Unit tests for each provider
2026-03-25 22:43:15 -07:00

368 lines
7.8 KiB
YAML

# Kubernetes Deployment for Lux KMS with Google Cloud KMS HSM
# Using Workload Identity for secure credential management
---
apiVersion: v1
kind: Namespace
metadata:
name: lux-kms
labels:
app.kubernetes.io/name: lux-kms
app.kubernetes.io/component: kms
---
# Service Account with Workload Identity annotation
apiVersion: v1
kind: ServiceAccount
metadata:
name: lux-kms-sa
namespace: lux-kms
annotations:
iam.gke.io/gcp-service-account: lux-kms-sa@PROJECT_ID.iam.gserviceaccount.com
labels:
app.kubernetes.io/name: lux-kms
app.kubernetes.io/component: kms
---
# ConfigMap for application configuration
apiVersion: v1
kind: ConfigMap
metadata:
name: lux-kms-config
namespace: lux-kms
labels:
app.kubernetes.io/name: lux-kms
data:
HSM_ENABLED: "true"
HSM_PROVIDER: "google-cloud"
GOOGLE_CLOUD_LOCATION: "global"
GOOGLE_CLOUD_KEY_RING: "lux-kms-keyring"
GOOGLE_CLOUD_CRYPTO_KEY: "lux-kms-key"
GOOGLE_CLOUD_PROTECTION_LEVEL: "HSM"
GOOGLE_CLOUD_AUTO_ROTATE: "true"
GOOGLE_CLOUD_ROTATION_PERIOD: "7776000s"
NODE_ENV: "production"
LOG_LEVEL: "info"
LOG_FORMAT: "json"
ENABLE_METRICS: "true"
RATE_LIMIT_ENABLED: "true"
RATE_LIMIT_MAX_REQUESTS: "100"
RATE_LIMIT_WINDOW_MS: "60000"
---
# Secret for sensitive configuration (create manually or via Sealed Secrets)
apiVersion: v1
kind: Secret
metadata:
name: lux-kms-secrets
namespace: lux-kms
labels:
app.kubernetes.io/name: lux-kms
type: Opaque
stringData:
GOOGLE_CLOUD_PROJECT_ID: "your-project-id"
DB_CONNECTION_URI: "postgresql://user:password@postgres:5432/lux_kms"
JWT_SECRET: "your-secure-random-secret-here"
REDIS_URL: "redis://redis:6379"
---
# Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: lux-kms
namespace: lux-kms
labels:
app.kubernetes.io/name: lux-kms
app.kubernetes.io/component: kms
app.kubernetes.io/version: "1.0.0"
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app.kubernetes.io/name: lux-kms
app.kubernetes.io/component: kms
template:
metadata:
labels:
app.kubernetes.io/name: lux-kms
app.kubernetes.io/component: kms
app.kubernetes.io/version: "1.0.0"
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9090"
prometheus.io/path: "/metrics"
spec:
serviceAccountName: lux-kms-sa
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: lux-kms
image: lux/kms:latest
imagePullPolicy: Always
ports:
- name: http
containerPort: 8080
protocol: TCP
- name: metrics
containerPort: 9090
protocol: TCP
envFrom:
- configMapRef:
name: lux-kms-config
- secretRef:
name: lux-kms-secrets
env:
- name: PORT
value: "8080"
- name: METRICS_PORT
value: "9090"
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: http
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 3
successThreshold: 1
failureThreshold: 3
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
capabilities:
drop:
- ALL
volumeMounts:
- name: tmp
mountPath: /tmp
- name: data
mountPath: /app/data
- name: logs
mountPath: /app/logs
volumes:
- name: tmp
emptyDir: {}
- name: data
persistentVolumeClaim:
claimName: lux-kms-data
- name: logs
emptyDir: {}
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- lux-kms
topologyKey: kubernetes.io/hostname
tolerations:
- key: "node.kubernetes.io/not-ready"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 300
- key: "node.kubernetes.io/unreachable"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 300
---
# PersistentVolumeClaim for data storage
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: lux-kms-data
namespace: lux-kms
labels:
app.kubernetes.io/name: lux-kms
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
storageClassName: standard-rwo
---
# Service
apiVersion: v1
kind: Service
metadata:
name: lux-kms
namespace: lux-kms
labels:
app.kubernetes.io/name: lux-kms
app.kubernetes.io/component: kms
annotations:
cloud.google.com/neg: '{"ingress": true}'
spec:
type: LoadBalancer
selector:
app.kubernetes.io/name: lux-kms
app.kubernetes.io/component: kms
ports:
- name: http
protocol: TCP
port: 80
targetPort: http
- name: metrics
protocol: TCP
port: 9090
targetPort: metrics
sessionAffinity: ClientIP
---
# HorizontalPodAutoscaler
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: lux-kms
namespace: lux-kms
labels:
app.kubernetes.io/name: lux-kms
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: lux-kms
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 50
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
- type: Pods
value: 2
periodSeconds: 15
selectPolicy: Max
---
# PodDisruptionBudget
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: lux-kms
namespace: lux-kms
labels:
app.kubernetes.io/name: lux-kms
spec:
minAvailable: 2
selector:
matchLabels:
app.kubernetes.io/name: lux-kms
app.kubernetes.io/component: kms
---
# NetworkPolicy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: lux-kms
namespace: lux-kms
labels:
app.kubernetes.io/name: lux-kms
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: lux-kms
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: hanzo-ingress
ports:
- protocol: TCP
port: 8080
- from:
- namespaceSelector:
matchLabels:
name: monitoring
ports:
- protocol: TCP
port: 9090
egress:
- to:
- namespaceSelector: {}
ports:
- protocol: TCP
port: 5432 # PostgreSQL
- protocol: TCP
port: 6379 # Redis
- to:
- namespaceSelector: {}
ports:
- protocol: TCP
port: 443 # Google Cloud KMS API
- protocol: TCP
port: 53 # DNS
- protocol: UDP
port: 53 # DNS