Google Drive (native gdrive)¶
kopia has a native Google Drive backend (gdrive) that talks to Drive
directly with a Google service-account key — no rclone in the path. Kopiur
exposes it as backend.gdrive.
Experimental / not maintained upstream
kopia marks the gdrive provider experimental and not actively maintained.
Prefer a native object store (S3, GCS, Azure,
B2) when you have one. Reach for gdrive only when Google Drive is the
storage you have.
Not interchangeable with rclone-backed Drive
A native gdrive repository and an rclone Drive remote lay out data
differently and cannot read each other. Pick one per repository and stay on
it — you can't switch a repository between them, and a restore must use the same
backend that wrote the snapshots.
When to use native gdrive vs rclone¶
Both reach Google Drive. They differ in the connection path:
- Native
gdrive— kopia talks to the Drive API directly with a service-account JSON. Fewer moving parts at connect time; no embeddedrclone serve/WebDAV bridge. - rclone Drive remote — kopia shells out to
rclone, which can be slower to come up duringrepository connect. Use it if you already run rclone or need OAuth-user (not service-account) auth.
Provider prerequisites¶
- A Google Cloud service account with a JSON key, and the Drive API enabled on its project.
- A Drive folder to hold the repository. Copy its folder ID — the last
path segment of the folder URL (
https://drive.google.com/drive/folders/<FOLDER_ID>). - Share the folder with the service account's
client_emailas an Editor, or the mover gets a permission error on connect.
The Secret shape¶
gdrive is file-delivered: the mover reads the whole service-account JSON from
a well-known env key, writes it to a private (0600) file, and runs kopia with
--credentials-file.
| Secret key | Required | What it is |
|---|---|---|
KOPIA_GDRIVE_CREDENTIALS |
yes¹ | The entire service-account key JSON, verbatim. Materialized → --credentials-file. |
KOPIA_PASSWORD |
yes | The repository encryption password. |
¹ Optional in the schema — when absent, kopia falls back to ambient credentials
(GOOGLE_APPLICATION_CREDENTIALS / instance metadata). In a normal cluster you
supply the Secret.
Why KOPIA_GDRIVE_CREDENTIALS and not credentials.json
The mover loads credentials with envFrom, and a dotted key like
credentials.json is not a valid environment-variable name — Kubernetes drops
it. So the JSON goes under KOPIA_GDRIVE_CREDENTIALS; the mover writes it to a
file for you and passes --credentials-file.
The Repository¶
---
apiVersion: v1
kind: Secret
metadata:
name: gdrive-repo-creds
namespace: backups
type: Opaque
stringData:
# The full service-account key JSON, verbatim. The mover writes it to a file
# and passes `--credentials-file` to kopia. The key MUST be
# KOPIA_GDRIVE_CREDENTIALS (a valid env identifier) — a dotted key like
# `credentials.json` is dropped by Kubernetes envFrom.
KOPIA_GDRIVE_CREDENTIALS: |
{
"type": "service_account",
"project_id": "REPLACE_ME",
"private_key_id": "REPLACE_ME",
"private_key": "-----BEGIN PRIVATE KEY-----\nREPLACE_ME\n-----END PRIVATE KEY-----\n",
"client_email": "kopia@REPLACE_ME.iam.gserviceaccount.com",
"client_id": "REPLACE_ME",
"token_uri": "https://oauth2.googleapis.com/token"
}
KOPIA_PASSWORD: "choose-something-long-and-random"
---
apiVersion: kopiur.home-operations.com/v1alpha1
kind: Repository
metadata:
name: gdrive-primary
namespace: backups
spec:
backend:
gdrive:
# The Drive folder ID that holds the repository. Share this folder with the
# service account's client_email (above) as an Editor.
folderId: REPLACE_ME_FOLDER_ID
credentialsSecretRef:
name: gdrive-repo-creds # Secret carrying KOPIA_GDRIVE_CREDENTIALS above
encryption:
passwordSecretRef:
name: gdrive-repo-creds # may be the same Secret; it also carries KOPIA_PASSWORD
key: KOPIA_PASSWORD
# `create` now defaults to enabled (connect-or-create is idempotent); set
# `create.enabled: false` only for a strictly read-only / externally-managed repo.
Fields reference (backend.gdrive)¶
| Field | Required | Default | Example | What it controls |
|---|---|---|---|---|
folderId |
yes | — | 0AbCdEf... |
The Drive folder ID that holds the repository (last segment of the folder URL). |
credentialsSecretRef |
no¹ | — | { name: gdrive-repo-creds } |
Secret holding the service-account JSON under KOPIA_GDRIVE_CREDENTIALS. A ClusterRepository adds namespace:. |
¹ Optional in the schema; in practice required unless the mover already has ambient Google credentials.
Customization — the values you actually change¶
folderId— which Drive folder backs the repository. Share it with the SA.KOPIA_GDRIVE_CREDENTIALS— the service-account JSON; rotate by re-pasting.create.enabled— defaults totrue(connect-or-create is idempotent); setfalseonly for a read-only / externally-managed repository.
As a ClusterRepository¶
The same backend.gdrive stanza works on a cluster-scoped
ClusterRepository; the
credentialsSecretRef (and the encryption.passwordSecretRef) must carry an
explicit namespace:, and the Secret must exist where the movers run — see
Movers.
Troubleshooting¶
403/ permission denied on connect — the Drive folder isn't shared with the service account'sclient_email(needs Editor), or the Drive API isn't enabled on the SA's project.folderIdnot found — copy the ID from the folder URL, not the folder name.- Slow or contradictory results vs an old rclone Drive repo — they're
different repositories; a native
gdriverepo can't read rclone-written data.
See also¶
- rclone — the other way to reach Google Drive (OAuth-user auth).
- Repositories & backends — concepts: scope, encryption, creation.
- Movers, RBAC & credentials — where the credentials Secret must live.