Skip to content

ESO Setup Runbook -- External Secrets Operator with Infisical

This runbook covers the one-time setup of ESO and the ClusterSecretStore. It is not needed for routine ExternalSecret creation (see ESO Overview).

Prerequisites

  • kubectl access to the k3s cluster (caneast-site1-node4 via PuTTY or CanEast AI Node WSL kubeconfig)
  • Helm 3 installed
  • Infisical UI access at https://REDACTED:[REDACTED]
  • Admin access in the archon-platform Infisical project

Step 1 -- Install ESO via Helm (already done, Sprint 3)

helm repo add external-secrets https://charts.external-secrets.io
helm repo update external-secrets
helm install external-secrets external-secrets/external-secrets \
  --version 2.4.0 \
  -n external-secrets --create-namespace \
  --set installCRDs=true \
  --wait --timeout 3m

Verify:

kubectl get pods -n external-secrets
# Expected: 3 pods Running (external-secrets, cert-controller, webhook)

Step 2 -- Create Machine Identity in Infisical UI

This step requires admin access to the Infisical web UI. It cannot be automated via the CLI.

  1. Open https://REDACTED:[REDACTED]
  2. Navigate to Organization Settings > Access Control > Machine Identities
  3. Click Create Identity
  4. Name: eso-archon-platform
  5. Role: member (or no access -- project access is granted separately)
  6. Under Authentication Methods, click + Add Auth Method
  7. Type: Universal Auth
  8. Client Secret TTL: leave blank (no expiry, or set 365d for rotation hygiene)
  9. Access Token TTL: 86400 (24h)
  10. Access Token Max TTL: 2592000 (30d)
  11. Click Create -- you will see the Client ID and Client Secret
  12. Copy both values immediately -- the Client Secret is only shown once
  13. Navigate to the archon-platform project > Access Control > Machine Identities
  14. Click Add Identity, select eso-archon-platform
  15. Role: Viewer (read-only)
  16. Environment: Production (prod)
  17. Click Save

Step 3 -- Bootstrap the Infisical Credential Secret (one-time manual)

This secret is the chicken-and-egg bootstrap -- it holds the Machine Identity credentials so ESO can authenticate to Infisical. It MUST NOT be committed to any repository.

kubectl create secret generic infisical-eso-creds \
  -n external-secrets \
  --from-literal=clientId=<CLIENT_ID_FROM_STEP_2> \
  --from-literal=clientSecret=REDACTED

Verify it exists:

kubectl get secret infisical-eso-creds -n external-secrets

Step 4 -- Apply CA ConfigMap

The Infisical server uses a self-signed certificate. Apply the CA ConfigMap so ESO trusts it:

kubectl apply -f kubernetes/external-secrets/configmap-infisical-ca.yaml

Verify:

kubectl get configmap infisical-ca -n external-secrets

Step 5 -- Apply ClusterSecretStore

kubectl apply -f kubernetes/external-secrets/clustersecretstore-infisical.yaml

Wait for the store to become Ready:

kubectl get clustersecretstore infisical-archon-platform -o wide

Expected output includes READY=True. If READY=False, check conditions:

kubectl describe clustersecretstore infisical-archon-platform

Common issues:

Symptom Cause Fix
x509: certificate signed by unknown authority CA cert not applied or wrong cert Verify ConfigMap content matches Infisical cert
unauthorized or 401 Machine Identity creds wrong Re-check clientId/clientSecret in Step 2/3
projectSlug not found Wrong slug Verify slug via Infisical API: GET /api/v1/workspace/<projectId>
environmentSlug not found Wrong env slug Must be prod (not production)

Step 6 -- Test with ExternalSecret (validation)

kubectl create ns eso-test

cat <<EOF | kubectl apply -f -
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
  name: test-dashscope
  namespace: eso-test
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: infisical-archon-platform
    kind: ClusterSecretStore
  target:
    name: test-dashscope
  data:
    - secretKey: api-key
      remoteRef:
        key: DASHSCOPE_API_KEY
EOF

Wait up to 60 seconds, then verify:

kubectl get externalsecret test-dashscope -n eso-test
kubectl get secret test-dashscope -n eso-test

Confirm the value matches Infisical (do not paste the value -- compare manually):

kubectl get secret test-dashscope -n eso-test -o jsonpath='{.data.api-key}' | base64 -d

Step 7 -- Cleanup test namespace

kubectl delete ns eso-test

Maintenance Notes

  • CA cert rotation: If the Infisical cert is renewed, update configmap-infisical-ca.yaml and re-apply.
  • Machine Identity secret rotation: If clientSecret is rotated in Infisical UI, re-run Step 3 with the new secret. The existing secret can be patched: kubectl create secret generic infisical-eso-creds -n external-secrets --from-literal=clientId=<id> --from-literal=clientSecret=REDACTED --dry-run=client -o yaml | kubectl apply -f -
  • ESO upgrade: helm upgrade external-secrets external-secrets/external-secrets --version <NEW> -n external-secrets -- check ESO release notes for CRD migration steps before upgrading major versions.