StorageBackend CRD
The StorageBackend Custom Resource Definition defines where backups are stored. Retour writes to S3-compatible storage, Azure Blob Storage, Google Cloud Storage, and client-side encrypted (crypt) backends, all through rclone or kopia.
Overview
- API Group:
retour.thebackup.company/v1
- Kind:
StorageBackend
- Scope: Namespaced
- Supported types:
s3, azureblob, gcs, crypt
- Refused:
type: local. A local path is a path inside the carrier pod, which the worker deletes when the job finishes, so those backups reported success and left nothing behind.
Spec
Required Fields
| Field |
Type |
Description |
type |
string |
s3, azureblob, gcs, or crypt. |
Optional Fields
| Field |
Type |
Default |
Description |
description |
string |
— |
Human-readable description. |
s3 |
object |
— |
S3 configuration (required when type: s3). |
azureblob |
object |
— |
Azure Blob configuration (required when type: azureblob). |
gcs |
object |
— |
Google Cloud Storage configuration (required when type: gcs). |
crypt |
object |
— |
Crypt configuration (required when type: crypt). |
engine |
string |
rclone |
Data plane for volume data. kopia stores deduplicated, incremental snapshots in a repository and works on s3, azureblob and gcs. It requires secretRef.keys.kopiaPassword and cannot be combined with crypt or Object Lock. |
transfer |
object |
— |
Bounds every transfer through this backend: bandwidthLimit in rclone --bwlimit syntax (a timetable is how a backup window is expressed), transfers, checkers. |
encryption |
object |
— |
encryption.keySource (aws-kms or vault-transit) envelope-wraps the backend's passphrase material, so only ciphertext is stored. Each job unwraps it just in time; rotation is a rewrap. |
S3 Config
| Field |
Type |
Default |
Description |
bucket |
string |
— |
Bucket name. Required. |
region |
string |
— |
Region (e.g., us-east-1). Required for AWS S3. |
endpoint |
string |
— |
Custom endpoint for MinIO, Ceph, etc. Leave empty for AWS. |
useSSL |
bool |
false |
Use HTTPS. Set to true for production. |
envAuth |
bool |
false |
Use IRSA (EKS). When true, secretRef not required. |
secretRef |
object |
— |
Secret for credentials. Not required when envAuth: true. |
serverSideEncryption |
string |
— |
AES256 (SSE-S3) or aws:kms (SSE-KMS). S3 only. |
kmsKeyID |
string |
— |
KMS key for SSE-KMS. Rejected without serverSideEncryption: "aws:kms". |
immutability |
object |
— |
S3 Object Lock retention on every uploaded object: mode (GOVERNANCE or COMPLIANCE) and retainDays. Needs a bucket created with Object Lock enabled. A lock that cannot be applied fails the backup. |
SecretReference
| Field |
Type |
Default |
Description |
name |
string |
— |
Secret name. |
namespace |
string |
same as StorageBackend |
Secret namespace. |
keys |
object |
— |
Keys in the secret. |
SecretKeys (S3)
When omitted, the controller assumes conventional Secret key names. Specify keys when your Secret uses different key names.
| Field |
Type |
Default |
Description |
accessKeyID |
string |
access-key-id |
Secret key for access key ID. |
secretAccessKey |
string |
secret-access-key |
Secret key for secret access key. |
endpoint |
string |
— |
Secret key for endpoint (if stored in secret). |
region |
string |
— |
Secret key for region (if stored in secret). |
Azure Blob Config
| Field |
Type |
Description |
container |
string |
Container that receives backups. Required. |
account |
string |
Storage account name. Required unless a SAS URL identifies the account, and always required with engine: kopia. |
endpoint |
string |
Overrides the blob service endpoint for Azurite or a sovereign cloud. rclone only: kopia's Azure provider has no endpoint override, so the combination is refused. |
envAuth |
bool |
Azure Workload Identity or a managed identity instead of a secret. |
secretRef |
object |
keys.accountKey (shared key) or keys.sasToken (the full SAS URL, not the bare token). |
GCS Config
| Field |
Type |
Description |
bucket |
string |
Bucket that receives backups. Required. |
endpoint |
string |
Overrides the storage endpoint for fake-gcs-server or private access. rclone only. |
envAuth |
bool |
Application Default Credentials, for GKE Workload Identity. |
secretRef |
object |
keys.serviceAccountKey holds the service-account JSON document itself, not a path. |
Crypt Config
| Field |
Type |
Description |
backend |
string |
Underlying backend. s3 only: azureblob and gcs cannot be crypt-wrapped. |
s3 |
object |
S3 config for the base remote. |
secretRef |
object |
Must include password. Add secretsPassword to use the encrypted Secrets stream; it has to differ from password. |
SecretKeys (Crypt)
| Field |
Type |
Description |
password |
string |
Encryption password. Required for crypt. |
secretsPassword |
string |
Separate passphrase for the encrypted Secrets stream. Must differ from password, so normal restore credentials cannot decrypt Secrets. |
accessKeyID |
string |
For underlying S3. |
secretAccessKey |
string |
For underlying S3. |
kopiaPassword |
string |
Repository password for engine: kopia. Required on every kopia backend, including under envAuth. Losing it makes every kopia backup in that repository unrestorable. |
Status
| Field |
Type |
Description |
phase |
string |
Pending, Ready, Failed, or Deleting. |
message |
string |
Status or error message. |
lastUpdated |
string |
When status was last updated. |
A Ready backend is re-checked periodically, so rotated or revoked credentials show up before the next backup fails.
Examples
AWS S3
apiVersion: v1
kind: Secret
metadata:
name: s3-credentials
namespace: retour
type: Opaque
stringData:
access-key-id: "your-access-key"
secret-access-key: "your-secret-key"
---
apiVersion: retour.thebackup.company/v1
kind: StorageBackend
metadata:
name: s3-production
namespace: retour
spec:
type: s3
description: "Production S3 bucket"
s3:
bucket: retour-backups
region: us-east-1
useSSL: true
secretRef:
name: s3-credentials
keys:
accessKeyID: access-key-id
secretAccessKey: secret-access-key
MinIO (S3-compatible)
apiVersion: retour.thebackup.company/v1
kind: StorageBackend
metadata:
name: minio
namespace: retour
spec:
type: s3
s3:
endpoint: https://minio.example.com
bucket: retour-backups
region: us-east-1
useSSL: true
secretRef:
name: minio-credentials
keys:
accessKeyID: access-key-id
secretAccessKey: secret-access-key
AWS S3 with IRSA (EKS, no secrets)
apiVersion: retour.thebackup.company/v1
kind: StorageBackend
metadata:
name: s3-aws-irsa
namespace: retour
spec:
type: s3
s3:
bucket: retour-backups
region: us-east-1
useSSL: true
envAuth: true
Azure Blob Storage
apiVersion: retour.thebackup.company/v1
kind: StorageBackend
metadata:
name: azure-production
namespace: retour
spec:
type: azureblob
azureblob:
account: retourstorage
container: retour-backups
secretRef:
name: azure-credentials
keys:
accountKey: account-key
Google Cloud Storage
apiVersion: retour.thebackup.company/v1
kind: StorageBackend
metadata:
name: gcs-production
namespace: retour
spec:
type: gcs
gcs:
bucket: retour-backups
secretRef:
name: gcs-credentials
keys:
serviceAccountKey: service-account-json
Immutable and Incremental
Object Lock and the kopia engine are mutually exclusive: kopia rewrites
repository metadata, which a lock forbids.
apiVersion: retour.thebackup.company/v1
kind: StorageBackend
metadata:
name: s3-locked
namespace: retour
spec:
type: s3
s3:
bucket: retour-immutable
region: us-east-1
serverSideEncryption: "aws:kms"
immutability:
mode: COMPLIANCE
retainDays: 30
secretRef:
name: s3-credentials
keys:
accessKeyID: access-key-id
secretAccessKey: secret-access-key
Bandwidth Windows
spec:
type: s3
transfer:
bandwidthLimit: "08:00,512k 19:00,10M 23:00,off"
transfers: 4
checkers: 8
Encrypted (Crypt over S3)
apiVersion: v1
kind: Secret
metadata:
name: crypt-credentials
namespace: retour
type: Opaque
stringData:
password: "encryption-password"
access-key-id: "minio"
secret-access-key: "minio123"
---
apiVersion: retour.thebackup.company/v1
kind: StorageBackend
metadata:
name: s3-encrypted
namespace: retour
spec:
type: crypt
crypt:
backend: s3
s3:
endpoint: http://minio.retour.svc.cluster.local:9000
bucket: retour-backups
region: us-east-1
useSSL: false
secretRef:
name: crypt-credentials
keys:
password: password
accessKeyID: access-key-id
secretAccessKey: secret-access-key