Secrets Management

How I handle secrets using External Secrets and 1Password.

How It Works

1Password -> 1Password Connect -> External Secrets Operator -> Kubernetes Secrets

All my secrets live in 1Password. The External Secrets Operator pulls them into the cluster automatically.

Adding a New Secret

1. Create in 1Password

Add a new item to 1Password with the fields you need. The item name should match what you want the Kubernetes secret to be called.

2. Create an ExternalSecret

Add this to your app's directory:

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: my-app-secret
  namespace: default
spec:
  refreshInterval: 1h
  secretStoreRef:
    kind: ClusterSecretStore
    name: onepassword-connect
  target:
    name: my-app-secret
    creationPolicy: Owner
  dataFrom:
    - extract:
        key: my-1password-item

If you only need specific fields:

spec:
  data:
    - secretKey: api-key
      remoteRef:
        key: my-1password-item
        property: api_key

3. Commit and Let Flux Do Its Thing

Commit to git and Flux will create the secret. Or apply manually:

kubectl apply -f externalsecret.yaml

Verify it worked:

kubectl get secret -n <namespace> <name>
kubectl get externalsecret -n <namespace> <name>

Force Sync All Secrets

If you updated something in 1Password and don't want to wait for the refresh interval:

task kubernetes:sync-secrets

Or for a single secret:

kubectl -n <namespace> annotate externalsecret <name> force-sync="$(date +%s)" --overwrite

Troubleshooting

ExternalSecret Shows Error

Check whats wrong:

kubectl describe externalsecret -n <namespace> <name>

Common issues:

ErrorProblemFix
item not foundItem doesn't exist in 1PasswordCreate it
field not foundRequested field missingAdd the field
connect error1Password Connect is downCheck the pod

1Password Connect Issues

# Check pod status
kubectl get pods -n external-secrets -l app=onepassword-connect

# Check logs
kubectl logs -n external-secrets -l app=onepassword-connect

Secret Not Updating

Secrets refresh based on refreshInterval. Force it:

task kubernetes:sync-secrets

Rotating Secrets

  1. Update the value in 1Password
  2. Force sync: kubectl -n <ns> annotate externalsecret <name> force-sync="$(date +%s)" --overwrite
  3. Restart the app to pick up the new value: kubectl rollout restart deployment -n <ns> <deployment>

Emergency Access

If External Secrets is broken and you need a secret NOW:

kubectl create secret generic <name> -n <namespace> --from-literal=<key>=<value>

Just remember this will get overwritten when External Secrets starts working again. Update 1Password if you want changes to stick.