Skip to content Skip to content

External Secrets Operator (ESO) Integration

The External Secrets Operator syncs secrets from external providers (AWS Secrets Manager, Vault, GCP Secret Manager, etc.) into Kubernetes Secrets. OpenClaw consumes these secrets via envFrom.

External Provider → ExternalSecret CR → Kubernetes Secret → OpenClaw Pod (envFrom)

The OpenClaw operator does not manage secrets directly — it only references them. ESO handles the lifecycle of the Kubernetes Secret, including rotation.

apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: aws-secrets
namespace: openclaw
spec:
provider:
aws:
service: SecretsManager
region: us-east-1
auth:
jwt:
serviceAccountRef:
name: eso-service-account
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: openclaw-api-keys
namespace: openclaw
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-secrets
kind: SecretStore
target:
name: openclaw-api-keys
creationPolicy: Owner
data:
- secretKey: ANTHROPIC_API_KEY
remoteRef:
key: openclaw/api-keys
property: anthropic
- secretKey: OPENAI_API_KEY
remoteRef:
key: openclaw/api-keys
property: openai
apiVersion: openclaw.rocks/v1alpha1
kind: OpenClawInstance
metadata:
name: my-assistant
namespace: openclaw
spec:
envFrom:
- secretRef:
name: openclaw-api-keys
security:
rbac:
createServiceAccount: true
serviceAccountAnnotations:
eks.amazonaws.com/role-arn: "arn:aws:iam::123456789012:role/openclaw-role"

When ESO refreshes a secret, the Kubernetes Secret’s resourceVersion changes. The OpenClaw operator detects this change and triggers a rolling restart of the pod to pick up the new values.

This works because the operator watches Secrets referenced in envFrom and env[].valueFrom.secretKeyRef. No manual intervention is needed.

  1. ESO refreshes the secret based on refreshInterval
  2. Kubernetes Secret is updated (new resourceVersion)
  3. OpenClaw operator detects the change via its watch
  4. Operator updates the config hash annotation on the pod template
  5. StatefulSet controller rolls the pod with the new secret values

ESO and OpenClaw may both need cloud provider credentials. Use serviceAccountAnnotations to configure workload identity:

spec:
security:
rbac:
serviceAccountAnnotations:
eks.amazonaws.com/role-arn: "arn:aws:iam::123456789012:role/openclaw-role"
spec:
security:
rbac:
serviceAccountAnnotations:
iam.gke.io/gcp-service-account: "openclaw@my-project.iam.gserviceaccount.com"
spec:
security:
rbac:
serviceAccountAnnotations:
azure.workload.identity/client-id: "00000000-0000-0000-0000-000000000000"
BackendSecretStore ProviderNotes
AWS Secrets ManagerawsUse IRSA for authentication
AWS Parameter StoreawsSet service: ParameterStore
HashiCorp VaultvaultSupports KV v1/v2, PKI, transit
GCP Secret ManagergcpsmUse Workload Identity
Azure Key VaultazurekvUse Workload Identity
1PasswordonepasswordVia 1Password Connect server
DopplerdopplerDirect integration
Kubernetes (cross-ns)kubernetesCopy secrets across namespaces

Secret not syncing:

Terminal window
kubectl get externalsecret openclaw-api-keys -n openclaw
kubectl describe externalsecret openclaw-api-keys -n openclaw

Pod not restarting after rotation: Check that the secret name in envFrom matches the ExternalSecret’s target.name.

IRSA not working: Verify the ServiceAccount has the correct annotation and the IAM role trust policy allows the service account.