Skip to main content
In this walkthrough you’ll act as a developer to encrypt and decrypt Kubernetes secrets using a PGP key pair and Mozilla SOPS. The demo covers importing the public key, installing SOPS locally, encrypting a plain Secret YAML, and configuring Flux Kustomization so Flux decrypts the secret before applying it to the cluster.
A presentation slide or webpage header titled "Demo – Mozilla SOPS: Secrets OPerationS with PGP (Developer)" with a dark navy banner and repeating yellow keywords, above a mostly white area containing a small blue rocket icon. The bottom shows a copyright credit.
Prerequisites (assumed)
  • You have a Git repository checked out (example: bb-app-source) and are on the infrastructure branch.
  • A SOPS public key file exists in the repository at sops/sops-gpg.pub.
  • Flux is installed and configured to apply resources from the repository.
Quick overview of the workflow
  1. Prepare the Secret YAML in plaintext.
  2. Import the SOPS public (PGP) key into your GPG keyring.
  3. Install SOPS on your developer machine.
  4. Encrypt the secret with SOPS (PGP backend).
  5. Push the encrypted manifest and give Flux the SOPS private key so it can decrypt.
  6. Reconcile Flux and verify the Secret is applied decrypted in the cluster.
Table: Resources and commands at a glance

1) Plaintext Secret (before encryption)

Create a simple Secret using stringData so values are easy to read before encryption:
Suggested file path in the repo: database/secret-mysql.yaml.

2) Import the public PGP key into GPG

On the developer machine, verify and import the public key that ships with the repository:
Sample import output:
Check the imported key fingerprint and metadata:
Sample listing:
Now your local keyring contains the public key; you can encrypt files to that PGP fingerprint.

3) Install SOPS on your machine

Install the SOPS CLI. Example (Linux binary download for sops v3.7.3):
Verify the installation:
SOPS supports multiple backends (PGP, KMS, GCP KMS, Azure Key Vault, HashiCorp Vault, age). This guide uses the PGP backend.

4) Encrypt the Secret using the developer’s public key (SOPS + PGP)

Encrypt only the secret data keys (data or stringData) so metadata remains human-readable. Use the PGP fingerprint you imported:
Notes:
  • --encrypted-regex controls which keys are encrypted (here: data and stringData).
  • --in-place replaces the file with the encrypted version.
Example (abbreviated) of the encrypted YAML:
Only the fields matched by the regex are encrypted; metadata (name, namespace, keys) remains readable.
Never commit private keys to the public repository. Only the public key (sops-gpg.pub) belongs in the repo. The private key must be handled securely (see the next section for how to provide it to Flux).

5) Commit & push the encrypted file; what Flux will do by default

Commit and push the encrypted secret file to your Git repository. Flux will fetch the manifest and apply it as-is. Without extra configuration Flux will apply the encrypted value literally, so the Secret in Kubernetes will contain the SOPS-encrypted string (not the usable plaintext). You can confirm the applied Secret content (it will show the encrypted string after decoding from base64):
To have Flux decrypt SOPS-encrypted YAML prior to apply, provide the private key to Flux and configure the Kustomization decryption section.

6) Provide the SOPS private key to Flux and configure Kustomization decryption

An administrator creates a Kubernetes Secret in the flux-system namespace that contains the SOPS/GPG private key. Example command (performed by an admin):
Then update the Kustomization that applies resources under ./database to include a decryption block. Key parts of the Kustomization:
Important:
  • The Flux secret sops-gpg must exist in the flux-system namespace and include the private key file content under the key name expected by Flux (for PGP, this is typically the raw private key file).
  • After adding decryption, Flux will attempt to decrypt any SOPS-encrypted files in that path before applying them.
Ensure the Flux secret (sops-gpg) contains the SOPS/GPG private key and is created in the flux-system namespace — Flux requires that private key to decrypt SOPS-encrypted manifests.

7) Reconcile Flux and verify the Secret is applied decrypted

Trigger a manual reconcile (optional — Flux will reconcile automatically based on interval):
After a successful reconcile, the Secret in the cluster should contain the decrypted value. Verify by decoding the Kubernetes Secret:
If you see the original plaintext value, Flux successfully decrypted the SOPS-encrypted manifest before applying it.

Summary, options and best practices

  • Mozilla SOPS supports multiple encryption backends: PGP, AWS KMS, GCP KMS, Azure Key Vault, HashiCorp Vault, age, and others. Use the backend that matches your organizational key management policies.
  • In GitOps workflows with Flux, store only encrypted secrets in Git. To let Flux apply decrypted values, configure the Kustomization decryption block and provide the decryption key/secret to Flux.
  • If you omit the Kustomization decryption configuration, Flux will apply the encrypted Secret object as stored in Git — the cluster will hold the encrypted string.
  • Secure the SOPS private key carefully. Prefer storing it in a restricted admin-controlled location and only create the Flux secret in flux-system when necessary.
Links and references That’s all — you’re set to encrypt secrets locally and configure Flux to decrypt them securely before applying to the cluster.

Watch Video

Practice Lab