Skip to main content

SOPS Encryption

Purpose: For platform engineers, shows how to encrypt/decrypt with SOPS Age keys and use opencenter cluster sync-secrets.

Task Summary​

Most secret management in openCenter is handled by the CLI (sync-secrets). This guide covers the manual SOPS workflow for cases where you need to encrypt a new secret file, decrypt for debugging, or edit an existing encrypted file in place.

Backend Operation Support​

openCenter supports two secrets backends: SOPS and Barbican. They differ in which CLI operations they support because of a fundamental design difference — SOPS operates on encrypted files, while Barbican is a key-value secret store.

OperationSOPSBarbican
secrets encrypt✅—
secrets decrypt✅—
secrets status✅—
secrets sync✅—
secrets validate✅✅
secrets list✅✅
secrets get❌✅
secrets set❌✅
secrets delete❌✅
secrets describe❌✅
secrets login—✅

SOPS manages secrets as whole encrypted YAML files, not individual key-value pairs. There is no concept of "get one secret by name" or "delete one secret" — you encrypt or decrypt entire files. The get, set, delete, and describe operations are only available with the Barbican backend.

If you attempt a CRUD operation (get, set, delete, describe) with the SOPS backend configured, the CLI returns an error with guidance pointing to the file-level alternatives:

$ opencenter secrets get my-secret
Error: SOPS backend does not support individual secret get operations.

SOPS manages secrets as encrypted YAML files, not individual key-value pairs.
To work with SOPS secrets:
opencenter secrets encrypt Encrypt YAML files
opencenter secrets decrypt Decrypt YAML files
opencenter secrets status Show encryption status

Documentation: https://docs.opencenter.cloud/secrets/sops-encryption

To manage individual secret values with SOPS, edit the plaintext config file and run opencenter secrets sync to re-encrypt. See Secrets Model for the full flow.

Prerequisites​

  • sops CLI installed (v3.8+)
  • age CLI installed (for key generation, if needed)
  • The cluster's Age public key (found in .sops.yaml or secrets/age/)
  • Access to the customer GitOps repository

Encrypt a New Secret​

Step 1: Create the plaintext manifest​

Write a standard Kubernetes Secret manifest:

# secret.yaml (plaintext — do NOT commit this)
apiVersion: v1
kind: Secret
metadata:
name: my-app-credentials
namespace: my-app
type: Opaque
stringData:
username: admin
password: "s3cret-value"

Step 2: Encrypt with SOPS​

If a .sops.yaml file exists in the directory (or a parent directory), SOPS picks up the creation rules automatically:

sops --encrypt --in-place secret.yaml

To encrypt with an explicit Age recipient:

sops --encrypt --age age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \
--encrypted-regex '^(data|stringData)$' \
--in-place secret.yaml

The --encrypted-regex flag ensures only data and stringData fields are encrypted. Metadata stays in plaintext so FluxCD and Kustomize can process the file.

Step 3: Verify encryption​

Open the file and confirm values are replaced with ENC[AES256_GCM,...] blocks:

head -20 secret.yaml

Expected output:

apiVersion: v1
kind: Secret
metadata:
name: my-app-credentials
namespace: my-app
type: Opaque
stringData:
username: ENC[AES256_GCM,data:...,type:str]
password: ENC[AES256_GCM,data:...,type:str]
sops:
age:
- recipient: age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
...

Step 4: Commit the encrypted file​

git add secret.yaml
git commit -m "Add encrypted credentials for my-app"

Decrypt for Debugging​

To view decrypted contents without modifying the file:

export SOPS_AGE_KEY_FILE=secrets/age/<cluster>_keys.txt
sops --decrypt secret.yaml

This prints the plaintext to stdout. Do not redirect to a file in the repository.

Edit an Encrypted File In Place​

SOPS can open an encrypted file in your editor, decrypt it for editing, and re-encrypt on save:

export SOPS_AGE_KEY_FILE=secrets/age/<cluster>_keys.txt
sops secret.yaml

This opens the decrypted content in $EDITOR. When you save and close, SOPS re-encrypts the file automatically.

Use the CLI for Bulk Operations​

For standard secret management, prefer the CLI over manual SOPS commands:

# Sync all secrets from config to encrypted manifests
opencenter cluster sync-secrets <cluster-name>

# Validate that all encrypted files decrypt correctly
opencenter cluster validate-secrets <cluster-name>

sync-secrets reads the plaintext config, generates Secret manifests, encrypts them with the correct .sops.yaml rules, and writes them to the proper overlay directories.

The .sops.yaml Configuration​

Each customer repository contains .sops.yaml files that define encryption rules per directory. SOPS walks up the directory tree to find the nearest .sops.yaml:

creation_rules:
- path_regex: applications/overlays/k8s-sandbox/.*
encrypted_regex: "^(data|stringData)$"
age: age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

See SOPS Configuration Reference for the full schema.

Troubleshooting​

"no matching creation rule" error: SOPS cannot find a .sops.yaml with a path_regex matching the file's path. Check that the file is in a directory covered by a creation rule, or pass --age explicitly.

"failed to decrypt" error: The Age private key does not match the recipient in the encrypted file. Verify SOPS_AGE_KEY_FILE points to the correct key file for this cluster.

Encrypted file has no sops: metadata block: The file was not encrypted. Re-run sops --encrypt --in-place <file>.