Helm Secrets + SOPS Encrypted Values Workflow Prompt
Design a GitOps-safe workflow for encrypting Helm values with the helm-secrets plugin and SOPS (age/KMS) — encrypted values in git, decryption at deploy time, key rotation, and CI wiring.
- Target user
- Platform and release engineers who ship Helm charts through GitOps and CI
- Difficulty
- Advanced
- Tools
- Claude, ChatGPT, Cursor
The prompt
You are a senior release engineer who manages Helm-based deployments across many environments and keeps encrypted secrets in git using the `helm-secrets` plugin backed by SOPS. You know the difference between SOPS with `age` and with cloud KMS, how the `.sops.yaml` creation rules drive which keys encrypt which files, and how to wire `helm secrets` into both local workflows and CI without ever writing plaintext to disk in a way that leaks. I will provide: - The chart(s) and the environments involved (e.g. `values.yaml` + per-env `secrets.<env>.yaml`) - Which SOPS backend you want: `age` (file/recipient keys) or a cloud KMS key - Where deploys run: laptop, CI runner, and/or a GitOps controller - What is currently plaintext that must move into encrypted values - Constraints: who may decrypt which environment, rotation cadence, and whether a GitOps controller must decrypt in-cluster Your job: 1. **Explain the moving parts** so nothing is a black box: - `helm-secrets` is a Helm plugin that wraps SOPS. `helm secrets` sub-commands decrypt referenced values files just-in-time and pass them to Helm as `-f`. - SOPS encrypts **only the values** of YAML keys (structure and keys stay readable), so diffs are meaningful and only secret material is ciphertext. - `.sops.yaml` `creation_rules` (matched by `path_regex`) decide which recipients/KMS keys encrypt a given file — this is what makes per-environment key separation work. 2. **Design the file layout**: which values are non-secret (`values.yaml`, checked in plaintext) vs. secret (`secrets.<env>.yaml`, SOPS-encrypted), and a naming/`path_regex` scheme so `prod` files are encrypted to a different key set than `dev`. 3. **Produce the `.sops.yaml`** with `creation_rules` for each environment — `age` recipients and/or a `kms`/`gcp_kms`/`azure_keyvault` key, plus `encrypted_regex` so only intended keys (e.g. `^(data|stringData|.*[Pp]assword|.*[Tt]oken|.*[Kk]ey)$`) are encrypted. 4. **Give the day-to-day commands** with exact invocation: - Encrypt/edit: `sops <file>` or `helm secrets edit secrets.prod.yaml` - Preview rendered output with secrets merged: `helm secrets template <release> ./chart -f values.yaml -f secrets.prod.yaml` - Deploy: `helm secrets upgrade --install <release> ./chart -f values.yaml -f secrets.prod.yaml -n <ns>` Explain that `helm secrets` decrypts to a temp file, runs Helm, then removes it — so plaintext never persists in the working tree. 5. **Wire CI** for a runner that has the decrypt key: how the age key or KMS credentials reach the runner (env var / mounted key / cloud IAM), and why the key must NOT be committed. For a GitOps controller, explain the in-cluster decryption path (the controller holds the private key and decrypts SOPS files itself) versus decrypt-at-CI-then-apply. 6. **Design key rotation and access changes.** To rotate or add/remove a recipient you must `sops updatekeys <file>` (or `sops rotate`) for every affected file so re-encryption picks up the new key set, then commit. Explain that removing a recipient from `.sops.yaml` does NOT re-encrypt existing files — the removed key can still decrypt history until you rotate and, for a true compromise, treat the underlying secret as leaked and rotate the secret itself. 7. **List the traps**: committing a partially-encrypted file (SOPS refused but a plaintext copy was left), the `enc: ` metadata mismatch after a manual edit, a decryption failure in CI because the runner lacks the key, and mixing `helm template` (no decryption) with encrypted files (renders ciphertext into manifests). Mark anything IRREVERSIBLE or leak-prone: committing a plaintext values file that was meant to be encrypted, losing the age private key (files become undecryptable), and echoing decrypted values in CI logs. --- Chart(s) + environments: [DESCRIBE] SOPS backend: [age / aws kms / gcp kms / azure keyvault] Where deploys run: [laptop / CI / GitOps controller] Currently-plaintext secrets to migrate: [LIST] Access + rotation constraints: [who decrypts what; cadence] Existing `.sops.yaml` (if any): ```yaml [PASTE or "none"] ```
Run this prompt with AI
Test it, get an AI-improved version, or compare models — live in the Prompt Workspace. No copy-paste.
Why this prompt works
Teams reach for helm-secrets + SOPS because it keeps encrypted secrets in git next to the chart, but the failure modes are all about which key encrypts what and when decryption happens. This prompt makes the model reason about .sops.yaml creation rules, the just-in-time decryption model, and rotation — the parts that turn into leaks or broken deploys when skipped.
How to use it
- Separate non-secret and secret values into different files so plaintext config stays reviewable.
- Let
.sops.yamlpath_regexdo the per-environment key separation — do not hand-pick keys per command. - Always deploy through
helm secrets ..., never plainhelmagainst an encrypted file. - Rotate with
sops updatekeys, and treat a real key compromise as a reason to rotate the secret itself.
Useful commands
# Install the plugin
helm plugin install https://github.com/jkroepke/helm-secrets
# Create / edit an encrypted values file
sops secrets.prod.yaml # uses .sops.yaml creation_rules
helm secrets edit secrets.prod.yaml
# Preview rendered manifests with secrets merged (decrypts JIT)
helm secrets template myapp ./chart -f values.yaml -f secrets.prod.yaml
# Deploy with decryption at apply time
helm secrets upgrade --install myapp ./chart \
-f values.yaml -f secrets.prod.yaml -n prod
# Rotate / update recipients after changing .sops.yaml
sops updatekeys secrets.prod.yaml
sops rotate -i secrets.prod.yaml # new data key, re-encrypt in place
# View who can decrypt a file (metadata)
sops --decrypt --extract '["sops"]["age"]' secrets.prod.yaml 2>/dev/null || \
grep -A3 'sops:' secrets.prod.yaml
Pattern: .sops.yaml with per-environment keys
creation_rules:
- path_regex: secrets\.prod\.ya?ml$
encrypted_regex: '^(data|stringData|.*[Pp]assword|.*[Tt]oken|.*[Kk]ey|.*[Ss]ecret)$'
age: >-
age1prodxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- path_regex: secrets\.(dev|staging)\.ya?ml$
encrypted_regex: '^(data|stringData|.*[Pp]assword|.*[Tt]oken|.*[Kk]ey|.*[Ss]ecret)$'
age: >-
age1devxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Pattern: encrypted values file (structure stays readable)
# secrets.prod.yaml (after sops encryption — abbreviated)
database:
host: db.prod.svc.cluster.local # NOT matched by encrypted_regex -> plaintext
password: ENC[AES256_GCM,data:....,tag:....]
apiToken: ENC[AES256_GCM,data:....,tag:....]
sops:
age:
- recipient: age1prodxxxx...
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
...
Common findings this catches
- Ciphertext ends up in manifests → deployed with plain
helm/helm templateinstead ofhelm secrets. - Wrong environment can decrypt prod →
.sops.yamlpath_regexoverlaps or a shared key is used everywhere. - Secret field left in plaintext →
encrypted_regexdoesn’t match the key name (e.g.apitokenvsapiToken). - CI fails to decrypt → runner lacks the age key / KMS IAM; key was never provisioned to the pipeline.
- Rotation didn’t take → recipient removed from
.sops.yamlbutsops updatekeysnever run on existing files.
When to escalate
- Suspected key or repo compromise — rotate the underlying secrets, not just the SOPS keys; involve security.
- GitOps controller in-cluster decryption failing — coordinate with whoever owns the controller’s key/secret backend.
- Cloud KMS access/permission issues — involve the team owning the KMS key policy and IAM.
Related prompts
-
Kustomize ConfigMap & Secret Generators Prompt
Master Kustomize generators for ConfigMaps and Secrets — content-hash suffixes that trigger safe rolling restarts, generator options, merge behavior, and avoiding the immutable-name and disableNameSuffixHash traps.
-
Sealed Secrets (Bitnami) Workflow Design Prompt
Design a GitOps-safe secret workflow using Bitnami Sealed Secrets — controller install, key scope choices, sealing CLI flow, rotation, and disaster recovery for the sealing key.
-
Helmfile Multi-Release Orchestration Prompt
Design a declarative Helmfile that orchestrates dozens of Helm releases across environments — with layered values, secrets, dependency ordering, and reproducible diffs.
-
Helm to Kustomize Migration Prompt
Plan and execute a migration from Helm templating to Kustomize overlays — or a deliberate hybrid — keeping environment differences declarative and avoiding a big-bang rewrite that drifts from production.
More Kubernetes & Helm prompts & error guides
Browse every Kubernetes & Helm prompt and troubleshooting guide in one place.
Reading prompts? Get all 500 in one free PDF
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.