StackGres supports encrypting backups at rest before they are stored in object storage. This provides an additional layer of security for your backup data, ensuring that even if your storage is compromised, the backup contents remain protected.
StackGres supports two encryption methods:
| Method | Description | Key Type | Use Case |
|---|---|---|---|
| sodium | Uses libsodium symmetric encryption | 32-byte secret key | Simple setup, high performance |
| openpgp | Uses OpenPGP standard encryption | PGP key pair | Industry standard, key management flexibility |
Sodium encryption uses the libsodium library for symmetric encryption. It requires a single 32-byte secret key for both encryption and decryption.
Generate a secure random key using one of these methods:
# Generate a hex-encoded key (recommended)
openssl rand -hex 32
# Or generate a base64-encoded key
openssl rand -base64 32
Store the encryption key in a Kubernetes Secret:
# Using hex-encoded key
kubectl create secret generic backup-encryption-key \
--from-literal=key=$(openssl rand -hex 32)
Or using a YAML manifest:
apiVersion: v1
kind: Secret
metadata:
name: backup-encryption-key
type: Opaque
stringData:
key: "your-64-character-hex-encoded-key-here"
apiVersion: stackgres.io/v1beta1
kind: SGObjectStorage
metadata:
name: encrypted-storage
spec:
type: s3
encryption:
method: sodium
sodium:
key:
name: backup-encryption-key
key: key
keyTransform: hex # or 'base64' or 'none'
s3:
bucket: my-encrypted-backups
awsCredentials:
secretKeySelectors:
accessKeyId:
name: s3-backup-secret
key: accessKeyId
secretAccessKey:
name: s3-backup-secret
key: secretAccessKey
The keyTransform field specifies how the key value should be interpreted:
| Value | Description |
|---|---|
hex |
Key is hex-encoded (64 hex characters = 32 bytes) |
base64 |
Key is base64-encoded |
none |
Key is used as-is (truncated or zero-padded to 32 bytes) |
Recommendation: Use hex or base64 for new setups. The none option exists for backwards compatibility.
OpenPGP encryption uses the industry-standard PGP protocol, allowing you to use existing PGP key management practices.
Generate a new PGP key pair:
# Generate a new key pair (follow the prompts)
gpg --full-generate-key
# Export the private key (armored format)
gpg --armor --export-secret-keys your@email.com > private-key.asc
# Export the public key (for reference)
gpg --armor --export your@email.com > public-key.asc
For automated environments, generate without interaction:
cat > key-params <<EOF
%no-protection
Key-Type: RSA
Key-Length: 4096
Subkey-Type: RSA
Subkey-Length: 4096
Name-Real: StackGres Backup
Name-Email: backup@stackgres.local
Expire-Date: 0
%commit
EOF
gpg --batch --generate-key key-params
gpg --armor --export-secret-keys backup@stackgres.local > private-key.asc
Store the PGP private key in a Kubernetes Secret:
kubectl create secret generic backup-pgp-key \
--from-file=private-key=private-key.asc
If your key has a passphrase:
kubectl create secret generic backup-pgp-key \
--from-file=private-key=private-key.asc \
--from-literal=passphrase='your-key-passphrase'
Without passphrase:
apiVersion: stackgres.io/v1beta1
kind: SGObjectStorage
metadata:
name: encrypted-storage
spec:
type: s3
encryption:
method: openpgp
openpgp:
key:
name: backup-pgp-key
key: private-key
s3:
bucket: my-encrypted-backups
awsCredentials:
secretKeySelectors:
accessKeyId:
name: s3-backup-secret
key: accessKeyId
secretAccessKey:
name: s3-backup-secret
key: secretAccessKey
With passphrase:
apiVersion: stackgres.io/v1beta1
kind: SGObjectStorage
metadata:
name: encrypted-storage
spec:
type: s3
encryption:
method: openpgp
openpgp:
key:
name: backup-pgp-key
key: private-key
keyPassphrase:
name: backup-pgp-key
key: passphrase
s3:
bucket: my-encrypted-backups
awsCredentials:
secretKeySelectors:
accessKeyId:
name: s3-backup-secret
key: accessKeyId
secretAccessKey:
name: s3-backup-secret
key: secretAccessKey
Here’s a complete example setting up encrypted backups to AWS S3:
# Generate and store sodium key
kubectl create secret generic backup-encryption-key \
--from-literal=key=$(openssl rand -hex 32)
kubectl create secret generic s3-backup-secret \
--from-literal=accessKeyId=AKIAIOSFODNN7EXAMPLE \
--from-literal=secretAccessKey=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
apiVersion: stackgres.io/v1beta1
kind: SGObjectStorage
metadata:
name: encrypted-s3-storage
spec:
type: s3
encryption:
method: sodium
sodium:
key:
name: backup-encryption-key
key: key
keyTransform: hex
s3:
bucket: my-encrypted-backups
region: us-west-2
awsCredentials:
secretKeySelectors:
accessKeyId:
name: s3-backup-secret
key: accessKeyId
secretAccessKey:
name: s3-backup-secret
key: secretAccessKey
apiVersion: stackgres.io/v1
kind: SGCluster
metadata:
name: my-cluster
spec:
instances: 3
postgres:
version: '16'
pods:
persistentVolume:
size: '10Gi'
configurations:
backups:
- sgObjectStorage: encrypted-s3-storage
cronSchedule: '0 5 * * *'
retention: 7
Encryption works with all supported storage backends. Here are examples for each:
apiVersion: stackgres.io/v1beta1
kind: SGObjectStorage
metadata:
name: encrypted-azure-storage
spec:
type: azureBlob
encryption:
method: sodium
sodium:
key:
name: backup-encryption-key
key: key
keyTransform: hex
azureBlob:
bucket: my-container
azureCredentials:
secretKeySelectors:
storageAccount:
name: azure-backup-secret
key: storageAccount
accessKey:
name: azure-backup-secret
key: accessKey
apiVersion: stackgres.io/v1beta1
kind: SGObjectStorage
metadata:
name: encrypted-gcs-storage
spec:
type: gcs
encryption:
method: openpgp
openpgp:
key:
name: backup-pgp-key
key: private-key
gcs:
bucket: my-encrypted-bucket
gcpCredentials:
secretKeySelectors:
serviceAccountJSON:
name: gcs-backup-secret
key: service-account.json
Secure Key Storage: Store encryption keys in a secure secrets management system (e.g., HashiCorp Vault, AWS Secrets Manager) and sync to Kubernetes Secrets.
Key Rotation: Periodically rotate encryption keys. When rotating:
Key Backup: Always maintain a secure backup of your encryption keys outside of Kubernetes. Without the key, encrypted backups cannot be restored.
Access Control: Use Kubernetes RBAC to restrict access to encryption key Secrets.
Audit Logging: Enable audit logging for Secret access to track who accesses encryption keys.
Encrypted backups are automatically decrypted during restore operations, provided the same SGObjectStorage configuration (with encryption settings) is used.
apiVersion: stackgres.io/v1
kind: SGCluster
metadata:
name: restored-cluster
spec:
instances: 3
postgres:
version: '16'
pods:
persistentVolume:
size: '10Gi'
initialData:
restore:
fromBackup:
name: encrypted-backup-name
The restore process will: