Backend configuration¶
This is the index for Kopiur's storage backends. Each backend has its own dedicated page with provider prerequisites, the exact Secret shape, a field-by-field reference, customization knobs, and backend-specific troubleshooting. Start here for the cross-cutting rules (the mental model, the credential-key conventions), then jump to your backend below. For the concepts behind a repository (the namespaced-vs-cluster split, encryption, repository creation) read Repositories & backends first.
The mental model (read this once)
A Repository is where snapshots live. It splits cleanly into two halves:
- Non-secret connection identifiers — bucket, container, endpoint, host, path. These go in
spec.backend.<kind>. - Secrets — backend access keys and the kopia encryption password. These live in a Kubernetes
Secret, read by well-known keys, and are passed to kopia as environment variables (never on argv, never in status).
SnapshotPolicy / Snapshot / Restore never repeat any of this — they point at the Repository by name.
Externally tagged — there is no kind: field
A backend is chosen by which key you set (backend.s3, backend.azure, …), not a kind: discriminator. backend: { kind: S3 } will not admit. Exactly one backend key is allowed. (Why: API conventions.)
Pick your backend¶
| Backend | Covers | Spec key |
|---|---|---|
| S3 & S3-compatible | Amazon S3, MinIO, RustFS, Ceph RGW, Wasabi, Cloudflare R2, … | backend.s3 |
| Azure Blob Storage | Azure Blob containers (key or SAS token) | backend.azure |
| Google Cloud Storage | GCS buckets (service-account key) | backend.gcs |
| Backblaze B2 | Backblaze B2 native API | backend.b2 |
| Filesystem (PVC / NFS) | A NAS/PVC or inline NFS export mounted into the mover | backend.filesystem |
| SFTP | Any server reachable over SSH/SFTP | backend.sftp |
| WebDAV | Nextcloud, Apache mod_dav, … |
backend.webDav |
| rclone | Google Drive, OneDrive, Dropbox, and dozens more | backend.rclone |
| Google Drive (native) | Google Drive via kopia's native gdrive (experimental) |
backend.gdrive |
How to use these pages¶
- Find your backend above.
- Provider prerequisites — create the bucket/container/share and a scoped credential on the provider side.
- Copy the manifest on the page, fill in every
REPLACE_ME, set a long randomKOPIA_PASSWORD, andkubectl apply -f. - Watch it become
Ready(see Watching a repository).
Lose the password, lose the backups
KOPIA_PASSWORD encrypts the repository. kopia cannot decrypt without it and there is no recovery. Use a long random value, store it outside the cluster (a password manager / external secret store), and back up the Secret itself. The three create-time tunables (encryption/splitter/hash) are fixed forever at creation — see Encryption and repository creation.
Credential keys at a glance¶
The mover reads these exact key names from the Secret you reference and feeds them to kopia. KOPIA_PASSWORD is required for every backend.
| Backend | Secret keys (besides KOPIA_PASSWORD) |
Spec key |
|---|---|---|
| S3 / S3-compatible | AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, (opt) AWS_SESSION_TOKEN |
backend.s3 |
| Azure | AZURE_STORAGE_KEY or AZURE_STORAGE_SAS_TOKEN |
backend.azure |
| Google Cloud Storage | KOPIA_GCS_CREDENTIALS (the SA-key JSON) |
backend.gcs |
| Backblaze B2 | B2_KEY_ID, B2_KEY |
backend.b2 |
| Filesystem | (none — only KOPIA_PASSWORD) |
backend.filesystem |
| SFTP | KOPIA_SFTP_KEY_DATA, KOPIA_SFTP_KNOWN_HOSTS |
backend.sftp |
| WebDAV | KOPIA_WEBDAV_USERNAME, KOPIA_WEBDAV_PASSWORD |
backend.webDav |
| rclone | KOPIA_RCLONE_CONFIG (via configSecretRef) |
backend.rclone |
| Google Drive | KOPIA_GDRIVE_CREDENTIALS (via credentialsSecretRef) |
backend.gdrive |
Cloud clusters: workload identity instead of static keys
On EKS, AKS, or GKE the three cloud backends can skip the static keys entirely:
auth.workloadIdentity.serviceAccountName runs the mover Jobs as a
user-supplied, IAM-federated ServiceAccount, and only KOPIA_PASSWORD remains
in the cluster. See S3 / IRSA,
Azure / AKS, and
GCS / GKE. The non-cloud backends (B2, SFTP,
WebDAV) are Secret-only — they have no IAM plane to federate with.
Env-delivered vs. file-delivered credentials
Most backends authenticate via environment variables kopia reads directly — the mover loads the Secret with envFrom, so the keys above become env vars. Four backends need their credentials as files instead (kopia's SFTP/GCS/rclone/gdrive flags have no env form, and a Secret key like ssh-privatekey isn't a valid env-var name so envFrom would silently drop it). For those, the mover reads a well-known env key and writes it to a private (0600) file, then points kopia at the path:
| Secret key | Becomes | kopia flag |
|---|---|---|
KOPIA_SFTP_KEY_DATA |
the SSH private key file | --keyfile |
KOPIA_SFTP_KNOWN_HOSTS |
the known_hosts file |
--known-hosts |
KOPIA_GCS_CREDENTIALS |
the service-account JSON file | --credentials-file |
KOPIA_RCLONE_CONFIG |
the rclone.conf file |
rclone --config |
KOPIA_GDRIVE_CREDENTIALS |
the service-account JSON file | --credentials-file |
You don't manage the files — just put the value under the right key; the secret never lands on kopia's argv.
ClusterRepository: where Secret refs resolve
The per-backend pages use a namespaced Repository. The same backend stanzas apply to a cluster-scoped ClusterRepository, with one wrinkle: it has no namespace of its own, so "absent = the referrer's namespace" has nothing to resolve to.
- When the operator itself reads the Secret — to connect, to bootstrap, or to run the repository server — a Secret reference with no
namespace:resolves to the operator's namespace (KOPIUR_NAMESPACE, which the Helm chart sets for you). Settingnamespace:explicitly always wins. This is what makes aClusterRepositorywith no namespaces on its refs reachReadyat all. - When a workload mover reads it — a
Snapshot,RestoreorMaintenanceJob — the Secret must exist in that workload's namespace, becauseenvFromis namespace-local. Either replicate it there yourself, or turn on credential projection (recommended for shared repos) and let Kopiur copy it in.
Set namespace: explicitly if anything other than the operator reads the Secret
The operator-namespace default above applies only to the repository's own connect / bootstrap / server. The mover side does not default it: credential projection needs an explicit namespace: on the reference to know what to copy, and without projection a mover looks for a same-named Secret in its own namespace. So a ClusterRepository with no namespace: on its refs will reach Ready and then fail its Snapshot/Restore Jobs with a MissingDependency naming the Secret.
If you run backups (i.e. almost always), pin the namespace:
A worked S3 example is on the S3 page.
See also¶
- Repositories & backends — the concepts: scope, encryption, creation,
ClusterRepository. - Permissions, UID & GID — the filesystem/SFTP ownership story and the mover UID knob.
- Movers, RBAC & credentials — where the credential Secret must live, and why.