Skip to content

Use the Helm chart when Containment Chamber runs next to validator clients in Kubernetes. This page covers the normal path: install the chart, mount configuration, expose only private traffic, and wire metrics. For every chart value, use the chart’s values.yaml as the reference.

Diagram
  • Helm 3+
  • Kubernetes 1.24+
  • PostgreSQL for production anti-slashing when running more than one replica
  • Validator keys supplied through filesystem mounts, DynamoDB, or runtime import

Create a values.yaml, then install:

Terminal window
helm install containment-chamber oci://ghcr.io/unforeseen-consequences/charts/containment-chamber \
--namespace validators \
--create-namespace \
-f values.yaml

Upgrade with the same values file:

Terminal window
helm upgrade containment-chamber oci://ghcr.io/unforeseen-consequences/charts/containment-chamber \
--namespace validators \
-f values.yaml

Check rollout:

Terminal window
kubectl -n validators rollout status deployment/containment-chamber
image:
repository: ghcr.io/unforeseen-consequences/containment-chamber
tag: ""
config:
network: mainnet
server:
listen_address: "0.0.0.0"
listen_port: 9000
metrics:
listen_address: "0.0.0.0"
listen_port: 3000
key_sources:
filesystem:
paths:
- /keystores
env:
- name: CONTAINMENT_ANTI_SLASHING__BACKEND
value: "postgres"
- name: CONTAINMENT_ANTI_SLASHING__URL
valueFrom:
secretKeyRef:
name: containment-chamber-secrets
key: database-url
extraVolumeMounts:
- name: keystores
mountPath: /keystores
readOnly: true
extraVolumes:
- name: keystores
secret:
secretName: validator-keystores

The chart uses two health endpoints:

  • /upcheck for startup and liveness. It succeeds when the HTTP server is alive, even if the signer is sealed.
  • /healthcheck for readiness. It succeeds only when the signer can safely serve signing traffic.

This keeps sealed pods alive but removes them from Service endpoints until they are ready to sign.

The chart is intended to run with restricted pod security:

podSecurityContext:
runAsNonRoot: true
runAsUser: 65534
securityContext:
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL

Keep the signing Service private. Expose it only to validator clients, and expose metrics only to your monitoring stack.

Enable ServiceMonitor when using Prometheus Operator:

serviceMonitor:
enabled: true
additionalLabels:
release: prometheus

The additionalLabels must match your Prometheus selector.

Restrict ingress to validator clients and metrics scrapers. If you restrict egress, allow DNS and the required backends: PostgreSQL, DynamoDB, KMS, STS, or any endpoint used by your deployment mode.

netpolicies:
ingress:
allowedNamespaces:
- consensus-layer
egress:
allowDns:
enabled: true
restrictEgress:
enabled: true
allowedEgressCIDRs:
- 10.0.0.0/8

On EKS, prefer IAM Roles for Service Accounts or EKS Pod Identity over static AWS credentials.

serviceAccount:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::ACCOUNT_ID:role/containment-chamber-role

For the exact DynamoDB and KMS actions, see AWS IAM Permissions.

When using the DynamoDB key source, configure the key table and the separate signer-state table:

config:
key_sources:
dynamodb:
table: containment-keys
signer_state:
backend: dynamodb
table: containment-state

See DynamoDB Key Source and Seal & Unseal Guide for the operational flow.

For large validator sets, increase CPU, memory, signing concurrency, and the PostgreSQL pool size together. Start conservative, then tune with metrics from Observability.

resources:
requests:
cpu: "1000m"
memory: "512Mi"
limits:
memory: "1Gi"
config:
signing:
max_concurrent_jobs: 2000
queue_buffer_size: 4000
anti_slashing:
backend: postgres
pool_size: 32

For Nitro Enclave mode, use the dedicated Nitro Enclave Deployment guide. The parent proxy and enclave image must be kept on the same release.