Skip to content

Field reference

Every spec and status field of all eight CRDs in kopiur.home-operations.com/v1alpha1, with its type, schema default, and a one-line meaning taken straight from the Rust doc comments.

This page is generated from the kopiur-api CRD schemas by cargo xtask gen-docs (run mise run gen); it is drift-checked in CI, so it can never go stale against the shipped CRDs. To change an entry, edit the doc comment on the field in crates/api — not this file. For the task-oriented explanations (mental model, which knobs you actually change), see the per-CRD pages under CRD reference.

Conventions

  • Type uses the CRD/YAML shape. enum: A \| B lists the allowed values; []T is an array, map[string]T a map, object (free-form) an unvalidated object, and core/v1 X an embedded Kubernetes type (see the Kubernetes API reference for its fields).
  • Default is the schema default: the API server materializes when the field is absent. means no schema default — an optional field that is simply unset, or one whose effective default depends on context (the description says which).
  • required marks a field with no default that must be present, or admission fails.
  • Externally-tagged unions select a variant by which key you set, never a kind: field; each is flagged "set exactly one of …".
  • Validation rules enforced by the API server (x-kubernetes-validations, including immutability) are listed under the table they apply to.

Repository

Scope: Namespaced · Short names: kopiarepo · Print columns: Phase, Backend, Server, IndexBlobs, Age

spec

Field Type Default Description
backend union required Exactly one storage backend.
encryption object required Repository password (a Secret reference).
bootstrap object Tuning for the bootstrap/discovery mover Job (<name>-discovery) that connects/creates an object-store repository the operator cannot reach in-process (and re-runs for catalog re-scans).
catalog object Bounds materialization of origin: discovered Snapshot CRs from the kopia catalog.
create object What to do when the repository does not yet exist (absent means it must already exist).
deletionProtection object Mass-deletion circuit breaker for this repository's Snapshots.
health object Repository health thresholds (tunes the index-blob-count warning).
identityDefaults object Identity defaults (CEL *Expr) applied when consumers don't override. Set cluster when this repository's backend is shared across clusters (e.g. one bucket backed up from more than one Kubernetes cluster) — the default kopia identity hostname then becomes <namespace>.<cluster> instead of bare <namespace>, so same-named namespaces on different clusters never collide. Same semantics as ClusterRepository's field of the same name (ADR-0004 §5); a consumer's explicit spec.identity still wins over anything here.
maintenance object Maintenance control; when absent or enabled the reconciler creates and owns a Maintenance CR.
mode enum: ReadWrite | ReadOnly ReadWrite Access mode: ReadWrite (default) or ReadOnly (serves restores only).
moverDefaults object Base mover configuration inherited by every mover this repository spawns.
onNamespaceDelete enum: Orphan | Delete Orphan What happens to this repository's snapshots when a consuming namespace is deleted.
parameters object Mutable kopia repository parameters, re-applied on bootstrap whenever they drift.
scheduleDefaults object Scheduling defaults (e.g. timezone) inherited by consumers that don't set their own equivalent field — verification, replication, and maintenance schedules today; set once here instead of repeating it on every cron.
server object Optional kopia web-UI server, exposed via a Service in this namespace.
suspend boolean Pause this repository: skip connect/bootstrap and maintenance projection.

Validation rules (enforced at admission):

  • create.splitter is immutable after creation
  • create.hash is immutable after creation
  • create.encryption is immutable after creation
  • create.ecc is immutable after creation

spec.backend

Externally tagged — set exactly one of: azure · b2 · filesystem · gcs · gdrive · rclone · s3 · sftp · webDav.

Field Type Default Description
azure object Azure Blob Storage.
b2 object Backblaze B2.
filesystem object A local filesystem path, backed by a PVC the operator mounts into the mover.
gcs object Google Cloud Storage.
gdrive object Google Drive via kopia's native gdrive provider (service-account JSON). kopia marks this provider experimental / not maintained, and a native gdrive repository is not interchangeable with an rclone-backed Drive remote.
rclone object Any rclone remote (kopia shells out to rclone), broadening reach to providers without a native kopia backend.
s3 object Amazon S3 or any S3-compatible object store (MinIO, RustFS, Ceph RGW, …).
sftp object SFTP server.
webDav object WebDAV endpoint.
spec.backend.azure
Field Type Default Description
container string required Blob container holding the kopia repository.
auth object Access credentials (Secret ref / workload identity).
prefix string Blob-name prefix within the container; empty/absent means the container root.
storageAccount string Storage-account name (when not inferred from credentials).
spec.backend.azure.auth
Field Type Default Description
secretRef object Secret holding the backend's static access credentials (mutually exclusive with workloadIdentity).
workloadIdentity object Use a cloud-federated ServiceAccount instead of static keys (mutually exclusive with secretRef).
spec.backend.azure.auth.secretRef
Field Type Default Description
name string required Name of the Secret.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.
spec.backend.azure.auth.workloadIdentity
Field Type Default Description
serviceAccountName string required Name of the ServiceAccount the mover pod runs as, resolved in the Job's own namespace.
spec.backend.b2
Field Type Default Description
bucket string required B2 bucket holding the kopia repository.
auth object Access credentials (application key ID/key Secret); Secret-only.
prefix string Object-name prefix within the bucket; empty/absent means the bucket root.
spec.backend.b2.auth
Field Type Default Description
secretRef object Secret holding the backend's access credentials, read by well-known keys.
spec.backend.b2.auth.secretRef
Field Type Default Description
name string required Name of the Secret.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.
spec.backend.filesystem
Field Type Default Description
path string required Mount path inside the mover pod where kopia writes the repository (e.g. /repo).
volume union What backs path: a PVC or an inline NFS export; absent for a path already on the node/image.
spec.backend.filesystem.volume

Externally tagged — set exactly one of: nfs · pvc.

Field Type Default Description
nfs object An inline NFS export mounted directly (no PVC).
pvc object A PersistentVolumeClaim mounted read-write at the repo path.
spec.backend.filesystem.volume.nfs
Field Type Default Description
path string required Exported path on the NFS server (e.g. /export/kopia or /mnt/eros/Media).
server string required NFS server hostname or IP (e.g. nas.lan or expanse.internal).
spec.backend.filesystem.volume.pvc
Field Type Default Description
name string required Name of the PersistentVolumeClaim to mount (in the mover's namespace).
spec.backend.gcs
Field Type Default Description
bucket string required GCS bucket holding the kopia repository.
auth object Access credentials (service-account key Secret / workload identity).
prefix string Object-name prefix within the bucket; empty/absent means the bucket root.
spec.backend.gcs.auth
Field Type Default Description
secretRef object Secret holding the backend's static access credentials (mutually exclusive with workloadIdentity).
workloadIdentity object Use a cloud-federated ServiceAccount instead of static keys (mutually exclusive with secretRef).
spec.backend.gcs.auth.secretRef
Field Type Default Description
name string required Name of the Secret.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.
spec.backend.gcs.auth.workloadIdentity
Field Type Default Description
serviceAccountName string required Name of the ServiceAccount the mover pod runs as, resolved in the Job's own namespace.
spec.backend.gdrive
Field Type Default Description
folderId string required Google Drive folder ID that holds the kopia repository.
credentialsSecretRef object Secret holding the Google service-account JSON used to reach the folder, read by the well-known key KOPIA_GDRIVE_CREDENTIALS. Absent means kopia falls back to ambient credentials (GOOGLE_APPLICATION_CREDENTIALS or instance metadata).
spec.backend.gdrive.credentialsSecretRef
Field Type Default Description
name string required Name of the Secret.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.
spec.backend.rclone
Field Type Default Description
remotePath string required rclone path in remote:path form (the remote name must exist in the supplied rclone config).
configSecretRef object Secret holding the rclone.conf that defines the remote referenced by remote_path.
startupTimeout string How long kopia waits for its embedded rclone serve to come up before failing the connect, as a Go duration (e.g. 2m). kopia's default is 15s; raise it for slow remotes whose repository metadata/indexes load through the rclone/WebDAV bridge and take longer than the default budget.
spec.backend.rclone.configSecretRef
Field Type Default Description
name string required Name of the Secret.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.
spec.backend.s3
Field Type Default Description
bucket string required Bucket holding the kopia repository.
auth object Access credentials (Secret ref / workload identity).
endpoint string S3 endpoint host. Omit for AWS; set it for MinIO/RustFS/other S3-compatible stores.
prefix string Key prefix under the bucket, letting several repositories share one bucket (e.g. clusters/prod/). Empty/absent means the bucket root.
region string S3 region. Required by AWS and some compatible providers.
tls object TLS overrides for self-signed CAs or HTTP-only endpoints.
spec.backend.s3.auth
Field Type Default Description
secretRef object Secret holding the backend's static access credentials (mutually exclusive with workloadIdentity).
workloadIdentity object Use a cloud-federated ServiceAccount instead of static keys (mutually exclusive with secretRef).
spec.backend.s3.auth.secretRef
Field Type Default Description
name string required Name of the Secret.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.
spec.backend.s3.auth.workloadIdentity
Field Type Default Description
serviceAccountName string required Name of the ServiceAccount the mover pod runs as, resolved in the Job's own namespace.
spec.backend.s3.tls
Field Type Default Description
caBundleRef object CA bundle (PEM) used to verify the endpoint's certificate, sourced from a ConfigMap.
disableTls boolean Disable TLS entirely and talk plain HTTP; maps to kopia's --disable-tls.
insecureSkipVerify boolean Skip TLS certificate verification (still uses TLS); maps to kopia's --disable-tls-verification.
spec.backend.s3.tls.caBundleRef
Field Type Default Description
configMapName string Name of the ConfigMap holding the value (e.g. a CA bundle).
key string Which key inside the ConfigMap to read.
spec.backend.sftp
Field Type Default Description
host string required SFTP server hostname or IP.
path string required Remote path on the server that holds the kopia repository.
auth object Credentials (SSH private key / known-hosts) sourced from a Secret; Secret-only.
port integer
min 0; max 65535
TCP port; defaults to 22 when absent.
username string SSH username to connect as.
spec.backend.sftp.auth
Field Type Default Description
secretRef object Secret holding the backend's access credentials, read by well-known keys.
spec.backend.sftp.auth.secretRef
Field Type Default Description
name string required Name of the Secret.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.
spec.backend.webDav
Field Type Default Description
url string required WebDAV collection URL holding the kopia repository.
auth object HTTP basic-auth credentials sourced from a Secret; Secret-only.
spec.backend.webDav.auth
Field Type Default Description
secretRef object Secret holding the backend's access credentials, read by well-known keys.
spec.backend.webDav.auth.secretRef
Field Type Default Description
name string required Name of the Secret.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.

spec.encryption

Field Type Default Description
passwordSecretRef object required Repository password, always a Secret reference (never inline).
spec.encryption.passwordSecretRef
Field Type Default Description
name string required Name of the Secret.
key string Which key inside the Secret to read.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.

spec.bootstrap

Field Type Default Description
failurePolicy object Failure policy for the bootstrap Job. activeDeadlineSeconds caps how long a connect may run before the Job is marked failed (default 120s); raise it for a slow backend — e.g. an rclone remote whose repository metadata and indexes load through kopia's embedded rclone serve/WebDAV bridge. backoffLimit bounds retries. podStartupDeadlineSeconds is accepted for shape parity but is not honored by the bootstrap Job.
spec.bootstrap.failurePolicy
Field Type Default Description
activeDeadlineSeconds integer Mover Job.spec.activeDeadlineSeconds — wall-clock cap after which a running run is killed.
backoffLimit integer Mover Job.spec.backoffLimit — retries before a failed run is marked failed.
podStartupDeadlineSeconds integer Seconds a non-starting (wedged) mover pod may sit before the run is failed; default 300s.

spec.catalog

Field Type Default Description
adoption enum: Adopt | Ignore Whether a discovered snapshot whose resolved identity matches a live SnapshotPolicy is automatically adopted — re-attached (stamped with that policy's config label, status.origin flipped to Adopted) so GFS retention governs it and eventually prunes it, instead of it sitting in the catalog forever as an immortal discovered row.
fallbackNamespace string Where to materialize discovered Snapshots with no allowed-namespace mapping (ClusterRepository only).
foreignSnapshots enum: Ignore | Fallback How catalog discovery treats snapshots written by ANOTHER cluster. status.catalog.foreignSnapshotCount counts an identity hostname carrying a different .<cluster> suffix ALWAYS, under either value below, plus — under Ignore only — a bare hostname naming no allowed namespace here. Under Fallback, that same disallowed bare host is NOT counted foreign: it materializes into catalog.fallbackNamespace exactly like a disallowed OwnCluster host would, so it is placed rather than dropped-and-counted (see classify_hostname/decide_cluster_placement). Meaningful only when identityDefaults.cluster is set: without a cluster identity there is no notion of "foreign" and the legacy hostname-names-a-namespace placement applies (validators enforce this).
periodicRefresh boolean Opt-in: periodically re-scan the repository to keep discovered Snapshot CRs current (re-list snapshots; for object-store / volume-backed repos this recycles the <name>-discovery mover Job every refreshInterval). Off by default — the repository still bootstraps once, re-bootstraps on a spec change, and re-probes on a backup failure, but does not re-run on a timer. Enable it if you rely on discovered snapshots reflecting changes made outside this operator.
refreshInterval string 1h How often to re-scan when periodicRefresh: true (Go-style duration; minimum 30s, default 1h). Inert unless periodicRefresh is enabled.
retain object How many discovered Snapshot CRs to keep materialized (bounds etcd footprint).
spec.catalog.retain
Field Type Default Description
maxAgeDays integer Expire discovered Snapshot CRs older than this many days (minimum 1); kopia snapshots untouched.
perIdentity integer Keep the most-recent N discovered Snapshot CRs per identity; 0 disables materialization.

spec.create

Field Type Default Description
ecc object Reed-Solomon ECC parity for a freshly-created repository (creation-time only, immutable after).
enabled boolean true Create the repository if it does not exist yet — on by default. Repository create/connect is idempotent: pointing create at an already-initialized repository just connects to it (it never re-creates or clobbers), so the only effect of the default is that a genuinely-absent repository is bootstrapped instead of erroring. Set false for a strictly read-only or externally-managed repository the operator must never create.
encryption string kopia encryption algorithm for a freshly-created repository (creation-time only).
hash string kopia content hash algorithm for a freshly-created repository (creation-time only).
splitter string kopia object splitter for a freshly-created repository (creation-time only).
spec.create.ecc
Field Type Default Description
algorithm string ECC algorithm, e.g. REED-SOLOMON-CRC32 (--ecc).
overheadPercent integer Parity overhead as a percentage (--ecc-overhead-percent).

spec.deletionProtection

Field Type Default Description
threshold integer 10
min 0
Pending EXTERNAL destructive Snapshot deletions (deletionTimestamp set, effective deletionPolicy Delete, not operator-pruned) that trip the breaker for this repository: at or above this, those deletions are HELD (finalizers wait) until acknowledged via the kopiur.home-operations.com/allow-mass-deletion annotation. 0 disables the breaker. Default 10.

spec.health

Field Type Default Description
indexBlobWarnThreshold integer 1000 Index-blob count above which the reconciler raises the IndexBlobHealth warning (0 disables).
probe object Opt-in periodic backend health probe: re-connect a Ready repository on a timer to confirm the kopia repository still exists at the backend.
spec.health.probe
Field Type Default Description
enabled boolean Turn the probe on. Off by default — existing repositories keep their current behavior until a user opts in.
failureThreshold integer 3 How many consecutive failing probes to require before raising the loud condition + event (default 3). Debounces a single transient blip from alarming or nudging a destructive manual recreate. Any success resets it.
interval string 30m How often to re-probe the backend (Go-style duration like 30m or 1h; minimum 30s, default 30m). Inert unless enabled.

spec.identityDefaults

Field Type Default Description
cluster string This cluster's identity suffix for repositories shared across clusters (an RFC 1123 label, at most 32 characters; dots are rejected — the first . in a hostname is the namespace/cluster delimiter). When set, the default kopia identity hostname becomes <namespace>.<cluster> instead of <namespace>, so two clusters backing up same-named namespaces write distinct identities (and one cluster's retention prune can no longer touch the other's snapshots). Also exposed to hostnameExpr/ usernameExpr as the CEL variable cluster.
hostnameExpr string CEL expression for the kopia identity hostname (e.g. "namespace").
usernameExpr string CEL expression for the kopia identity username (e.g. "namespace + '-' + policyName").

spec.maintenance

Field Type Default Description
enabled boolean true Whether the operator manages a Maintenance CR for this repository (default true).
failurePolicy object Failure handling (backoff/deadline) for the managed Maintenance run.
mover object Mover overrides for the managed Maintenance.
namespace string ClusterRepository only: namespace the managed Maintenance CR is created in (default the operator's namespace).
schedule object Schedule override; absent uses the default quick-6h / full-daily schedule.
takeoverPolicy enum: Never | PromptCondition | Force What to do when another owner already holds the lease. Defaults to Never (the safest: never seize a lease another owner holds).
spec.maintenance.failurePolicy
Field Type Default Description
activeDeadlineSeconds integer Mover Job.spec.activeDeadlineSeconds — wall-clock cap after which a running run is killed.
backoffLimit integer Mover Job.spec.backoffLimit — retries before a failed run is marked failed.
podStartupDeadlineSeconds integer Seconds a non-starting (wedged) mover pod may sit before the run is failed; default 300s.
spec.maintenance.mover
Field Type Default Description
cache object Override the repository's CacheDefaults for this recipe's movers.
inheritSecurityContextFrom union Copy the UID/GID security context from a live workload rather than hard-coding it.
Requires the workload to pin runAsUser (container or pod level): a UID that comes from the container image's USER line is invisible in the pod spec and cannot be inherited — the mover would silently run as its own image's UID instead.
May be combined with securityContext/podSecurityContext, which override it field-wise and act as the fallback when no workload pod can be resolved.
podSecurityContext core/v1 PodSecurityContext Pod security context for the mover (notably fsGroup for group-writable restore volumes). Same layering as securityContext: highest layer, merged field-wise, and combinable with inheritSecurityContextFrom.
privilegedMode boolean Opt-in, namespace-gated privileged mode; preserves UID/GID on restore.
resources core/v1 ResourceRequirements Resource requests/limits for the mover container.
securityContext core/v1 SecurityContext Container security context for the mover; merged field-wise over the hardened base, moverDefaults, and any inherited context — this is the highest layer, so every field set here wins. Combines with inheritSecurityContextFrom: fields you set override the workload's, fields you omit are inherited, and this context stands in alone when inheritance cannot resolve a pod.
ttlSecondsAfterFinished integer Per-recipe override of Job.spec.ttlSecondsAfterFinished so finished Jobs self-GC.
spec.maintenance.mover.cache
Field Type Default Description
capacity string Size of the PVC backing the mover's kopia cache (e.g. 10Gi).
contentCacheSizeMb integer kopia content cache budget in MiB (--content-cache-size-mb).
metadataCacheSizeMb integer kopia metadata cache budget in MiB (--metadata-cache-size-mb).
mode enum: Ephemeral | Persistent How a mover's kopia cache volume is provisioned.
storageClassName string StorageClass for the cache PVC; absent uses the cluster default.
spec.maintenance.mover.inheritSecurityContextFrom

Externally tagged — set exactly one of: pvcConsumer · snapshot · workloadSelector.

Field Type Default Description
pvcConsumer object Backup sources only: auto-derive the workload from the PVC this snapshot backs up.
snapshot object Restores only: inherit the identity RECORDED on the backup itself (Snapshot.status.recorded, decoded from the kopiur-meta kopia tag) — uid/gid/fsGroup the backup mover actually ran as. Needs no live workload pod, so it works on a rebuilt cluster and with target.populator. Rejected at admission on SnapshotPolicy/Maintenance (backups read the live workload; maintenance has no snapshot). Write it as snapshot: {} (an empty sub-object) — a bare snapshot: is null and rejected.
workloadSelector object Inherit from workload pod(s) matched by an explicit label selector (backup or restore).
spec.maintenance.mover.inheritSecurityContextFrom.pvcConsumer
Field Type Default Description
container string Which container within the matched consumer pod to inherit from; absent uses the first/only.
spec.maintenance.mover.inheritSecurityContextFrom.workloadSelector
Field Type Default Description
podSelector core/v1 LabelSelector required Label selector matching the workload pod(s) to read context/hooks from.
container string Which container within the matched pod; absent uses the first/only container.
spec.maintenance.schedule
Field Type Default Description
full object required Cron and jitter for kopia maintenance run --full (content reclamation).
quick object required Cron and jitter for kopia maintenance run (quick, cheap index/log work).
timezone string IANA timezone both crons are evaluated in; absent means the controller default.
spec.maintenance.schedule.full
Field Type Default Description
cron string required The cron expression, parsed by croner; may contain an H placeholder for deterministic jitter.
jitter string Optional deterministic jitter window as a Go-style duration string (e.g. 30m).
timezone string IANA timezone the cron is evaluated in (e.g. America/Chicago); absent uses the enclosing schedule's timezone, else the controller default (UTC).
spec.maintenance.schedule.quick
Field Type Default Description
cron string required The cron expression, parsed by croner; may contain an H placeholder for deterministic jitter.
jitter string Optional deterministic jitter window as a Go-style duration string (e.g. 30m).
timezone string IANA timezone the cron is evaluated in (e.g. America/Chicago); absent uses the enclosing schedule's timezone, else the controller default (UTC).

spec.moverDefaults

Field Type Default Description
affinity core/v1 Affinity Pod affinity for every mover.
cache object kopia cache defaults for every mover.
nodeSelector map[string]string Pod nodeSelector for every mover.
podSecurityContext core/v1 PodSecurityContext Pod security-context base (notably fsGroup) for every mover.
resources core/v1 ResourceRequirements Resource requests/limits base for the mover container.
scratch object Defaults for the deep-verification scratch (restore-test) volume.
securityContext core/v1 SecurityContext Container security-context base for every mover.
sourceColocation object How a mover co-locates with its RWO PVC's node; defaults to SourceColocationMode::Auto.
throttle object Repository throttle limits applied by every mover after it connects.
tolerations []core/v1 Toleration Pod tolerations for every mover.
ttlSecondsAfterFinished integer Job.spec.ttlSecondsAfterFinished for every mover Job so finished Jobs self-GC.
spec.moverDefaults.cache
Field Type Default Description
capacity string Size of the PVC backing the mover's kopia cache (e.g. 10Gi).
contentCacheSizeMb integer kopia content cache budget in MiB (--content-cache-size-mb).
metadataCacheSizeMb integer kopia metadata cache budget in MiB (--metadata-cache-size-mb).
mode enum: Ephemeral | Persistent How a mover's kopia cache volume is provisioned.
storageClassName string StorageClass for the cache PVC; absent uses the cluster default.
spec.moverDefaults.scratch
Field Type Default Description
capacity string Size of the ephemeral scratch PVC (e.g. 100Gi); absent falls back to an emptyDir.
storageClassName string StorageClass for the ephemeral scratch PVC; only applies when capacity is set.
spec.moverDefaults.sourceColocation
Field Type Default Description
mode enum: Auto | Required | Disabled How the mover co-locates with the node an RWO source/destination PVC is attached to.
spec.moverDefaults.throttle
Field Type Default Description
downloadBytesPerSecond integer Cap download throughput in bytes/sec (--download-bytes-per-second).
readOpsPerSecond integer Cap read/list ops/sec (--read-requests-per-second).
uploadBytesPerSecond integer Cap upload throughput in bytes/sec (--upload-bytes-per-second).
writeOpsPerSecond integer Cap write ops/sec (--write-requests-per-second).

spec.parameters

Field Type Default Description
epoch object Epoch-manager tuning — how fast kopia closes epochs and therefore how fast index blobs get compacted.
spec.parameters.epoch
Field Type Default Description
advanceOnCount integer Index blobs in an epoch that trigger an advance, once older than minDuration (kopia default 20).
advanceOnSizeMiB integer Total index size in an epoch that triggers an advance, once older than minDuration (kopia default 10 MiB).
Named MiB, not MB, with an explicit rename rather than the derived camelCase (advanceOnSizeMb, which reads as megabit). The unit is genuinely mebibytes — kopia's --epoch-advance-on-size-mb multiplies by 1048576, so 10 is 10485760 bytes — even though kopia's own log renders the result as "MB". That ambiguity is this field's main hazard; the API surface should not reproduce it.
checkpointFrequency integer Epochs between full index checkpoints (kopia default 7).
deleteParallelism integer Parallelism for epoch cleanup deletions (kopia default 4).
minDuration string Minimum epoch age before it may advance (kopia default 24h). A Go-style duration (6h, 90m). The advance gate — no blob count closes an epoch younger than this.
refreshFrequency string How often clients re-read epoch state (kopia default 20m). Go-style duration.

spec.scheduleDefaults

Field Type Default Description
timezone string IANA timezone name applied to every consuming cron that doesn't set its own timezone (e.g. America/New_York). Set once here instead of repeating it on every SnapshotPolicy.verification, RepositoryReplication.schedule, and Maintenance.schedule cron.

spec.server

Field Type Default Description
auth union UI authentication mode; omitted ⇒ ServerAuth::Generate (never no-auth).
podSecurityContext core/v1 PodSecurityContext Pod-level security context for the server pod (notably supplementalGroups for NFS exports).
readOnly boolean Connect the server's repository read-only so the UI cannot mutate backups (browse + restore only).
resources core/v1 ResourceRequirements Resource requests/limits for the server pod.
securityContext core/v1 SecurityContext Override the hardened default container security context.
service object How the server is exposed as a Kubernetes Service.
spec.server.auth

Externally tagged — set exactly one of: generate · insecure · secretRef.

Field Type Default Description
generate object The operator mints random UI credentials into an owned Secret; the safe default.
insecure object No UI authentication; requires an explicit acknowledgeInsecure: true.
secretRef object The user supplies UI credentials via a Secret (name + the two keys).
spec.server.auth.generate
Field Type Default Description
username string UI username to provision (default kopia).
spec.server.auth.insecure
Field Type Default Description
acknowledgeInsecure boolean false Must be true; the webhook rejects insecure mode otherwise.
spec.server.auth.secretRef
Field Type Default Description
name string required Name of the Secret holding the UI credentials.
passwordKey string required Key within the secret holding the password.
usernameKey string required Key within the secret holding the username.
spec.server.service
Field Type Default Description
annotations map[string]string Annotations applied to the Service — the seam users wire their own Ingress/LoadBalancer controller onto.
port integer 51515
min 0; max 65535
Listen/Service port. Defaults to DEFAULT_SERVER_PORT when omitted.
type enum: ClusterIP | NodePort | LoadBalancer ClusterIP Service type. Defaults to ClusterIP (routing is the user's responsibility).

status

Field Type Default Description
backend string Mirror of spec.backend discriminant for the print column.
catalog object Catalog-materialization status (how many discovered Snapshots, last refresh).
conditions []object Standard Kubernetes conditions (e.g. Connected, MaintenanceOwned).
health object Backend health-probe state (spec.health.probe), when enabled.
lastReverifyAt string Last reverify-request token honored from a Snapshot's re-probe nudge (RFC3339); the loop guard that keeps each request a one-shot.
observedGeneration integer metadata.generation of the spec last reconciled; drives staleness detection.
parameters object The kopia repository parameters actually observed at the last bootstrap. Compare against spec.parameters to see whether a declared value landed.
phase enum: Pending | Initializing | Ready | Degraded | Failed Lifecycle phase of a repository. A freshly admitted CR starts in Pending.
resolvedCredentialVersion string resourceVersion of the password Secret observed at the last connect attempt.
server object Resolved kopia server endpoint/auth, pinned by the reconciler.
storageStats object Repository size and snapshot counts from the last catalog scan.
uniqueId string Kopia repository unique ID.

status.catalog

Field Type Default Description
discoveredBackupCount integer How many Snapshot CRs were materialized from the catalog scan.
foreignSnapshotCount integer Snapshots in the last complete listing classified as another cluster's (see catalog.foreignSnapshots); never materialized under Ignore. As of catalog.lastRefreshAt — enable periodicRefresh to keep it current.
lastRefreshAt string RFC 3339 timestamp of the last catalog refresh.
scanRequestAttemptAt string RFC 3339 timestamp of the last bootstrap/scan attempt initiated BECAUSE OF a pending catalog-scan-requested-at token (i.e. the token arm was the reason the attempt fired). Used only to rate-limit token-driven attempts on a Ready-but-unreachable repository — it is never compared against the token for retirement (that's scanRequestHonored, by equality).
scanRequestHonored string The RFC3339 token VALUE of the kopiur.home-operations.com/catalog-scan-requested-at annotation last honored by a completed catalog scan. Compared by equality against the live annotation to decide whether a requested on-demand scan is still pending — deliberately NOT a timestamp comparison against lastRefreshAt (a periodic refresh completing after the request was made would otherwise look like it honored the request even though it started before the annotation was set).

status.conditions[]

Field Type Default Description
lastTransitionTime string required lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
message string required message is a human readable message indicating details about the transition. This may be an empty string.
reason string required reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
status string required status of the condition, one of True, False, Unknown.
type string required type of condition in CamelCase or in foo.example.com/CamelCase.
observedGeneration integer observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditionsx.observedGeneration is 9, the condition is out of date with respect to the current state of the instance.

status.health

Field Type Default Description
consecutiveProbeFailures integer Consecutive failing probes accrued; reset to zero on any success. The loud condition is raised only once this reaches the failure threshold.
firstFailureAt string RFC 3339 timestamp of the first failure in the current failing streak.
lastHealthyAt string RFC 3339 timestamp of the last successful probe (backend reachable, repo present).
lastProbeAt string RFC 3339 timestamp of the last completed probe (success or failure); drives the health_probe_due timer so the probe re-fires on cadence.
probeAttemptAt string RFC 3339 timestamp at which the last backend health probe was launched (the bootstrap Job created for it), cleared when its result is finalized.
This is the launch-side rate limit, and it is what makes the probe terminate. lastProbeAt is written only at finalize, so gating the launch on that alone recycles the bootstrap Job forever: the gate destroys every Job whose completion would have cleared it (#273). Never compared against lastProbeAt — see kopiur_controller::health::probe_action.

status.parameters

Field Type Default Description
epoch object The epoch parameters the repository reports.
status.parameters.epoch
Field Type Default Description
advanceOnCount integer required Observed index-blob count that triggers an epoch advance.
advanceOnSizeMiB integer required Observed total index size (MiB) that triggers an epoch advance.
checkpointFrequency integer required Observed epochs between full index checkpoints.
cleanupSafetyMargin string required Observed cleanup safety margin, as a Go-style duration. Reported for diagnosis; not settable through spec.parameters.
deleteParallelism integer required Observed epoch-cleanup delete parallelism.
enabled boolean required Whether kopia's epoch manager is enabled on this repository at all.
minDuration string required Observed minimum epoch age, as a Go-style duration.
refreshFrequency string required Observed epoch-state refresh frequency, as a Go-style duration.

status.server

Field Type Default Description
authMode string Resolved auth mode discriminant (Generate/SecretRef/Insecure).
endpoint string In-cluster endpoint, <service>.<namespace>.svc:<port>.
generatedSecretRef object For Generate mode: the operator-owned Secret holding the UI credentials.
namespace string Namespace the server objects were last applied to.
readOnly boolean Effective read-only state of the served connection.
status.server.generatedSecretRef
Field Type Default Description
name string required Name of the Secret.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.

status.storageStats

Field Type Default Description
indexBlobCount integer Number of content-index blobs (kopia index list) observed at the last bootstrap.
lastObservedAt string RFC 3339 timestamp these stats were last observed.
snapshotCount integer Total snapshots present in the repository (across all identities).
totalSize string Human-readable total on-disk size (e.g. 412Gi).
totalSizeBytes integer Logical bytes under management (the integer form of total_size): the sum, over each distinct snapshot source, of the most-recent snapshot's logical size. Exposed to backup preflight as repository.sizeBytes. This is repository total size, not backend free space (object stores don't report remaining capacity).

ClusterRepository

Scope: Cluster · Short names: kopiacrepo · Print columns: Phase, Backend, Namespaces, Server, IndexBlobs, Age

spec

Field Type Default Description
allowedNamespaces union required Which namespaces are permitted to reference this repository.
backend union required Exactly one storage backend.
encryption object required Repository password (a Secret reference that must carry an explicit namespace).
bootstrap object Tuning for the bootstrap/discovery mover Job (<name>-discovery) that connects/creates an object-store repository the operator cannot reach in-process (and re-runs for catalog re-scans).
catalog object Bounds materialization of origin: discovered Snapshot CRs from the kopia catalog.
create object What to do when the repository does not yet exist (absent means it must already exist).
credentialProjection object Repository-owner gate for projecting credential Secrets into a foreign consumer namespace.
deletionProtection object Mass-deletion circuit breaker for this repository's Snapshots.
health object Repository health thresholds (tunes the index-blob-count warning).
identityDefaults object Identity defaults (CEL *Expr) applied when consumers don't override.
maintenance object Maintenance control; maintenance.namespace selects where the owned Maintenance CR lands.
mode enum: ReadWrite | ReadOnly ReadWrite Access mode: ReadWrite (default) or ReadOnly (serves restores only).
moverDefaults object Base mover configuration inherited by every mover this repository spawns.
onNamespaceDelete enum: Orphan | Delete Orphan What happens to this repository's snapshots when a consuming namespace is deleted.
parameters object Mutable kopia repository parameters, re-applied on bootstrap whenever they drift.
scheduleDefaults object Scheduling defaults (e.g. timezone) inherited by consumers that don't set their own equivalent field — verification, replication, and maintenance schedules today; set once here instead of repeating it on every cron.
server object Optional kopia web-UI server (the target namespace is required).
suspend boolean Pause this cluster repository: skip connect/bootstrap and maintenance projection.

Validation rules (enforced at admission):

  • create.splitter is immutable after creation
  • create.hash is immutable after creation
  • create.encryption is immutable after creation
  • create.ecc is immutable after creation

spec.allowedNamespaces

Externally tagged — set exactly one of: all · list · selector.

Field Type Default Description
all boolean Allow all namespaces (must be true).
list []string Explicit namespace names.
selector core/v1 LabelSelector Match namespaces by label.

spec.backend

Externally tagged — set exactly one of: azure · b2 · filesystem · gcs · gdrive · rclone · s3 · sftp · webDav.

Field Type Default Description
azure object Azure Blob Storage.
b2 object Backblaze B2.
filesystem object A local filesystem path, backed by a PVC the operator mounts into the mover.
gcs object Google Cloud Storage.
gdrive object Google Drive via kopia's native gdrive provider (service-account JSON). kopia marks this provider experimental / not maintained, and a native gdrive repository is not interchangeable with an rclone-backed Drive remote.
rclone object Any rclone remote (kopia shells out to rclone), broadening reach to providers without a native kopia backend.
s3 object Amazon S3 or any S3-compatible object store (MinIO, RustFS, Ceph RGW, …).
sftp object SFTP server.
webDav object WebDAV endpoint.
spec.backend.azure
Field Type Default Description
container string required Blob container holding the kopia repository.
auth object Access credentials (Secret ref / workload identity).
prefix string Blob-name prefix within the container; empty/absent means the container root.
storageAccount string Storage-account name (when not inferred from credentials).
spec.backend.azure.auth
Field Type Default Description
secretRef object Secret holding the backend's static access credentials (mutually exclusive with workloadIdentity).
workloadIdentity object Use a cloud-federated ServiceAccount instead of static keys (mutually exclusive with secretRef).
spec.backend.azure.auth.secretRef
Field Type Default Description
name string required Name of the Secret.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.
spec.backend.azure.auth.workloadIdentity
Field Type Default Description
serviceAccountName string required Name of the ServiceAccount the mover pod runs as, resolved in the Job's own namespace.
spec.backend.b2
Field Type Default Description
bucket string required B2 bucket holding the kopia repository.
auth object Access credentials (application key ID/key Secret); Secret-only.
prefix string Object-name prefix within the bucket; empty/absent means the bucket root.
spec.backend.b2.auth
Field Type Default Description
secretRef object Secret holding the backend's access credentials, read by well-known keys.
spec.backend.b2.auth.secretRef
Field Type Default Description
name string required Name of the Secret.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.
spec.backend.filesystem
Field Type Default Description
path string required Mount path inside the mover pod where kopia writes the repository (e.g. /repo).
volume union What backs path: a PVC or an inline NFS export; absent for a path already on the node/image.
spec.backend.filesystem.volume

Externally tagged — set exactly one of: nfs · pvc.

Field Type Default Description
nfs object An inline NFS export mounted directly (no PVC).
pvc object A PersistentVolumeClaim mounted read-write at the repo path.
spec.backend.filesystem.volume.nfs
Field Type Default Description
path string required Exported path on the NFS server (e.g. /export/kopia or /mnt/eros/Media).
server string required NFS server hostname or IP (e.g. nas.lan or expanse.internal).
spec.backend.filesystem.volume.pvc
Field Type Default Description
name string required Name of the PersistentVolumeClaim to mount (in the mover's namespace).
spec.backend.gcs
Field Type Default Description
bucket string required GCS bucket holding the kopia repository.
auth object Access credentials (service-account key Secret / workload identity).
prefix string Object-name prefix within the bucket; empty/absent means the bucket root.
spec.backend.gcs.auth
Field Type Default Description
secretRef object Secret holding the backend's static access credentials (mutually exclusive with workloadIdentity).
workloadIdentity object Use a cloud-federated ServiceAccount instead of static keys (mutually exclusive with secretRef).
spec.backend.gcs.auth.secretRef
Field Type Default Description
name string required Name of the Secret.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.
spec.backend.gcs.auth.workloadIdentity
Field Type Default Description
serviceAccountName string required Name of the ServiceAccount the mover pod runs as, resolved in the Job's own namespace.
spec.backend.gdrive
Field Type Default Description
folderId string required Google Drive folder ID that holds the kopia repository.
credentialsSecretRef object Secret holding the Google service-account JSON used to reach the folder, read by the well-known key KOPIA_GDRIVE_CREDENTIALS. Absent means kopia falls back to ambient credentials (GOOGLE_APPLICATION_CREDENTIALS or instance metadata).
spec.backend.gdrive.credentialsSecretRef
Field Type Default Description
name string required Name of the Secret.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.
spec.backend.rclone
Field Type Default Description
remotePath string required rclone path in remote:path form (the remote name must exist in the supplied rclone config).
configSecretRef object Secret holding the rclone.conf that defines the remote referenced by remote_path.
startupTimeout string How long kopia waits for its embedded rclone serve to come up before failing the connect, as a Go duration (e.g. 2m). kopia's default is 15s; raise it for slow remotes whose repository metadata/indexes load through the rclone/WebDAV bridge and take longer than the default budget.
spec.backend.rclone.configSecretRef
Field Type Default Description
name string required Name of the Secret.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.
spec.backend.s3
Field Type Default Description
bucket string required Bucket holding the kopia repository.
auth object Access credentials (Secret ref / workload identity).
endpoint string S3 endpoint host. Omit for AWS; set it for MinIO/RustFS/other S3-compatible stores.
prefix string Key prefix under the bucket, letting several repositories share one bucket (e.g. clusters/prod/). Empty/absent means the bucket root.
region string S3 region. Required by AWS and some compatible providers.
tls object TLS overrides for self-signed CAs or HTTP-only endpoints.
spec.backend.s3.auth
Field Type Default Description
secretRef object Secret holding the backend's static access credentials (mutually exclusive with workloadIdentity).
workloadIdentity object Use a cloud-federated ServiceAccount instead of static keys (mutually exclusive with secretRef).
spec.backend.s3.auth.secretRef
Field Type Default Description
name string required Name of the Secret.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.
spec.backend.s3.auth.workloadIdentity
Field Type Default Description
serviceAccountName string required Name of the ServiceAccount the mover pod runs as, resolved in the Job's own namespace.
spec.backend.s3.tls
Field Type Default Description
caBundleRef object CA bundle (PEM) used to verify the endpoint's certificate, sourced from a ConfigMap.
disableTls boolean Disable TLS entirely and talk plain HTTP; maps to kopia's --disable-tls.
insecureSkipVerify boolean Skip TLS certificate verification (still uses TLS); maps to kopia's --disable-tls-verification.
spec.backend.s3.tls.caBundleRef
Field Type Default Description
configMapName string Name of the ConfigMap holding the value (e.g. a CA bundle).
key string Which key inside the ConfigMap to read.
spec.backend.sftp
Field Type Default Description
host string required SFTP server hostname or IP.
path string required Remote path on the server that holds the kopia repository.
auth object Credentials (SSH private key / known-hosts) sourced from a Secret; Secret-only.
port integer
min 0; max 65535
TCP port; defaults to 22 when absent.
username string SSH username to connect as.
spec.backend.sftp.auth
Field Type Default Description
secretRef object Secret holding the backend's access credentials, read by well-known keys.
spec.backend.sftp.auth.secretRef
Field Type Default Description
name string required Name of the Secret.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.
spec.backend.webDav
Field Type Default Description
url string required WebDAV collection URL holding the kopia repository.
auth object HTTP basic-auth credentials sourced from a Secret; Secret-only.
spec.backend.webDav.auth
Field Type Default Description
secretRef object Secret holding the backend's access credentials, read by well-known keys.
spec.backend.webDav.auth.secretRef
Field Type Default Description
name string required Name of the Secret.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.

spec.encryption

Field Type Default Description
passwordSecretRef object required Repository password, always a Secret reference (never inline).
spec.encryption.passwordSecretRef
Field Type Default Description
name string required Name of the Secret.
key string Which key inside the Secret to read.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.

spec.bootstrap

Field Type Default Description
failurePolicy object Failure policy for the bootstrap Job. activeDeadlineSeconds caps how long a connect may run before the Job is marked failed (default 120s); raise it for a slow backend — e.g. an rclone remote whose repository metadata and indexes load through kopia's embedded rclone serve/WebDAV bridge. backoffLimit bounds retries. podStartupDeadlineSeconds is accepted for shape parity but is not honored by the bootstrap Job.
spec.bootstrap.failurePolicy
Field Type Default Description
activeDeadlineSeconds integer Mover Job.spec.activeDeadlineSeconds — wall-clock cap after which a running run is killed.
backoffLimit integer Mover Job.spec.backoffLimit — retries before a failed run is marked failed.
podStartupDeadlineSeconds integer Seconds a non-starting (wedged) mover pod may sit before the run is failed; default 300s.

spec.catalog

Field Type Default Description
adoption enum: Adopt | Ignore Whether a discovered snapshot whose resolved identity matches a live SnapshotPolicy is automatically adopted — re-attached (stamped with that policy's config label, status.origin flipped to Adopted) so GFS retention governs it and eventually prunes it, instead of it sitting in the catalog forever as an immortal discovered row.
fallbackNamespace string Where to materialize discovered Snapshots with no allowed-namespace mapping (ClusterRepository only).
foreignSnapshots enum: Ignore | Fallback How catalog discovery treats snapshots written by ANOTHER cluster. status.catalog.foreignSnapshotCount counts an identity hostname carrying a different .<cluster> suffix ALWAYS, under either value below, plus — under Ignore only — a bare hostname naming no allowed namespace here. Under Fallback, that same disallowed bare host is NOT counted foreign: it materializes into catalog.fallbackNamespace exactly like a disallowed OwnCluster host would, so it is placed rather than dropped-and-counted (see classify_hostname/decide_cluster_placement). Meaningful only when identityDefaults.cluster is set: without a cluster identity there is no notion of "foreign" and the legacy hostname-names-a-namespace placement applies (validators enforce this).
periodicRefresh boolean Opt-in: periodically re-scan the repository to keep discovered Snapshot CRs current (re-list snapshots; for object-store / volume-backed repos this recycles the <name>-discovery mover Job every refreshInterval). Off by default — the repository still bootstraps once, re-bootstraps on a spec change, and re-probes on a backup failure, but does not re-run on a timer. Enable it if you rely on discovered snapshots reflecting changes made outside this operator.
refreshInterval string 1h How often to re-scan when periodicRefresh: true (Go-style duration; minimum 30s, default 1h). Inert unless periodicRefresh is enabled.
retain object How many discovered Snapshot CRs to keep materialized (bounds etcd footprint).
spec.catalog.retain
Field Type Default Description
maxAgeDays integer Expire discovered Snapshot CRs older than this many days (minimum 1); kopia snapshots untouched.
perIdentity integer Keep the most-recent N discovered Snapshot CRs per identity; 0 disables materialization.

spec.create

Field Type Default Description
ecc object Reed-Solomon ECC parity for a freshly-created repository (creation-time only, immutable after).
enabled boolean true Create the repository if it does not exist yet — on by default. Repository create/connect is idempotent: pointing create at an already-initialized repository just connects to it (it never re-creates or clobbers), so the only effect of the default is that a genuinely-absent repository is bootstrapped instead of erroring. Set false for a strictly read-only or externally-managed repository the operator must never create.
encryption string kopia encryption algorithm for a freshly-created repository (creation-time only).
hash string kopia content hash algorithm for a freshly-created repository (creation-time only).
splitter string kopia object splitter for a freshly-created repository (creation-time only).
spec.create.ecc
Field Type Default Description
algorithm string ECC algorithm, e.g. REED-SOLOMON-CRC32 (--ecc).
overheadPercent integer Parity overhead as a percentage (--ecc-overhead-percent).

spec.credentialProjection

Field Type Default Description
allowed boolean false When true, the owner permits projecting this repository's credential Secret(s) into a consumer namespace.

spec.deletionProtection

Field Type Default Description
threshold integer 10
min 0
Pending EXTERNAL destructive Snapshot deletions (deletionTimestamp set, effective deletionPolicy Delete, not operator-pruned) that trip the breaker for this repository: at or above this, those deletions are HELD (finalizers wait) until acknowledged via the kopiur.home-operations.com/allow-mass-deletion annotation. 0 disables the breaker. Default 10.

spec.health

Field Type Default Description
indexBlobWarnThreshold integer 1000 Index-blob count above which the reconciler raises the IndexBlobHealth warning (0 disables).
probe object Opt-in periodic backend health probe: re-connect a Ready repository on a timer to confirm the kopia repository still exists at the backend.
spec.health.probe
Field Type Default Description
enabled boolean Turn the probe on. Off by default — existing repositories keep their current behavior until a user opts in.
failureThreshold integer 3 How many consecutive failing probes to require before raising the loud condition + event (default 3). Debounces a single transient blip from alarming or nudging a destructive manual recreate. Any success resets it.
interval string 30m How often to re-probe the backend (Go-style duration like 30m or 1h; minimum 30s, default 30m). Inert unless enabled.

spec.identityDefaults

Field Type Default Description
cluster string This cluster's identity suffix for repositories shared across clusters (an RFC 1123 label, at most 32 characters; dots are rejected — the first . in a hostname is the namespace/cluster delimiter). When set, the default kopia identity hostname becomes <namespace>.<cluster> instead of <namespace>, so two clusters backing up same-named namespaces write distinct identities (and one cluster's retention prune can no longer touch the other's snapshots). Also exposed to hostnameExpr/ usernameExpr as the CEL variable cluster.
hostnameExpr string CEL expression for the kopia identity hostname (e.g. "namespace").
usernameExpr string CEL expression for the kopia identity username (e.g. "namespace + '-' + policyName").

spec.maintenance

Field Type Default Description
enabled boolean true Whether the operator manages a Maintenance CR for this repository (default true).
failurePolicy object Failure handling (backoff/deadline) for the managed Maintenance run.
mover object Mover overrides for the managed Maintenance.
namespace string ClusterRepository only: namespace the managed Maintenance CR is created in (default the operator's namespace).
schedule object Schedule override; absent uses the default quick-6h / full-daily schedule.
takeoverPolicy enum: Never | PromptCondition | Force What to do when another owner already holds the lease. Defaults to Never (the safest: never seize a lease another owner holds).
spec.maintenance.failurePolicy
Field Type Default Description
activeDeadlineSeconds integer Mover Job.spec.activeDeadlineSeconds — wall-clock cap after which a running run is killed.
backoffLimit integer Mover Job.spec.backoffLimit — retries before a failed run is marked failed.
podStartupDeadlineSeconds integer Seconds a non-starting (wedged) mover pod may sit before the run is failed; default 300s.
spec.maintenance.mover
Field Type Default Description
cache object Override the repository's CacheDefaults for this recipe's movers.
inheritSecurityContextFrom union Copy the UID/GID security context from a live workload rather than hard-coding it.
Requires the workload to pin runAsUser (container or pod level): a UID that comes from the container image's USER line is invisible in the pod spec and cannot be inherited — the mover would silently run as its own image's UID instead.
May be combined with securityContext/podSecurityContext, which override it field-wise and act as the fallback when no workload pod can be resolved.
podSecurityContext core/v1 PodSecurityContext Pod security context for the mover (notably fsGroup for group-writable restore volumes). Same layering as securityContext: highest layer, merged field-wise, and combinable with inheritSecurityContextFrom.
privilegedMode boolean Opt-in, namespace-gated privileged mode; preserves UID/GID on restore.
resources core/v1 ResourceRequirements Resource requests/limits for the mover container.
securityContext core/v1 SecurityContext Container security context for the mover; merged field-wise over the hardened base, moverDefaults, and any inherited context — this is the highest layer, so every field set here wins. Combines with inheritSecurityContextFrom: fields you set override the workload's, fields you omit are inherited, and this context stands in alone when inheritance cannot resolve a pod.
ttlSecondsAfterFinished integer Per-recipe override of Job.spec.ttlSecondsAfterFinished so finished Jobs self-GC.
spec.maintenance.mover.cache
Field Type Default Description
capacity string Size of the PVC backing the mover's kopia cache (e.g. 10Gi).
contentCacheSizeMb integer kopia content cache budget in MiB (--content-cache-size-mb).
metadataCacheSizeMb integer kopia metadata cache budget in MiB (--metadata-cache-size-mb).
mode enum: Ephemeral | Persistent How a mover's kopia cache volume is provisioned.
storageClassName string StorageClass for the cache PVC; absent uses the cluster default.
spec.maintenance.mover.inheritSecurityContextFrom

Externally tagged — set exactly one of: pvcConsumer · snapshot · workloadSelector.

Field Type Default Description
pvcConsumer object Backup sources only: auto-derive the workload from the PVC this snapshot backs up.
snapshot object Restores only: inherit the identity RECORDED on the backup itself (Snapshot.status.recorded, decoded from the kopiur-meta kopia tag) — uid/gid/fsGroup the backup mover actually ran as. Needs no live workload pod, so it works on a rebuilt cluster and with target.populator. Rejected at admission on SnapshotPolicy/Maintenance (backups read the live workload; maintenance has no snapshot). Write it as snapshot: {} (an empty sub-object) — a bare snapshot: is null and rejected.
workloadSelector object Inherit from workload pod(s) matched by an explicit label selector (backup or restore).
spec.maintenance.mover.inheritSecurityContextFrom.pvcConsumer
Field Type Default Description
container string Which container within the matched consumer pod to inherit from; absent uses the first/only.
spec.maintenance.mover.inheritSecurityContextFrom.workloadSelector
Field Type Default Description
podSelector core/v1 LabelSelector required Label selector matching the workload pod(s) to read context/hooks from.
container string Which container within the matched pod; absent uses the first/only container.
spec.maintenance.schedule
Field Type Default Description
full object required Cron and jitter for kopia maintenance run --full (content reclamation).
quick object required Cron and jitter for kopia maintenance run (quick, cheap index/log work).
timezone string IANA timezone both crons are evaluated in; absent means the controller default.
spec.maintenance.schedule.full
Field Type Default Description
cron string required The cron expression, parsed by croner; may contain an H placeholder for deterministic jitter.
jitter string Optional deterministic jitter window as a Go-style duration string (e.g. 30m).
timezone string IANA timezone the cron is evaluated in (e.g. America/Chicago); absent uses the enclosing schedule's timezone, else the controller default (UTC).
spec.maintenance.schedule.quick
Field Type Default Description
cron string required The cron expression, parsed by croner; may contain an H placeholder for deterministic jitter.
jitter string Optional deterministic jitter window as a Go-style duration string (e.g. 30m).
timezone string IANA timezone the cron is evaluated in (e.g. America/Chicago); absent uses the enclosing schedule's timezone, else the controller default (UTC).

spec.moverDefaults

Field Type Default Description
affinity core/v1 Affinity Pod affinity for every mover.
cache object kopia cache defaults for every mover.
nodeSelector map[string]string Pod nodeSelector for every mover.
podSecurityContext core/v1 PodSecurityContext Pod security-context base (notably fsGroup) for every mover.
resources core/v1 ResourceRequirements Resource requests/limits base for the mover container.
scratch object Defaults for the deep-verification scratch (restore-test) volume.
securityContext core/v1 SecurityContext Container security-context base for every mover.
sourceColocation object How a mover co-locates with its RWO PVC's node; defaults to SourceColocationMode::Auto.
throttle object Repository throttle limits applied by every mover after it connects.
tolerations []core/v1 Toleration Pod tolerations for every mover.
ttlSecondsAfterFinished integer Job.spec.ttlSecondsAfterFinished for every mover Job so finished Jobs self-GC.
spec.moverDefaults.cache
Field Type Default Description
capacity string Size of the PVC backing the mover's kopia cache (e.g. 10Gi).
contentCacheSizeMb integer kopia content cache budget in MiB (--content-cache-size-mb).
metadataCacheSizeMb integer kopia metadata cache budget in MiB (--metadata-cache-size-mb).
mode enum: Ephemeral | Persistent How a mover's kopia cache volume is provisioned.
storageClassName string StorageClass for the cache PVC; absent uses the cluster default.
spec.moverDefaults.scratch
Field Type Default Description
capacity string Size of the ephemeral scratch PVC (e.g. 100Gi); absent falls back to an emptyDir.
storageClassName string StorageClass for the ephemeral scratch PVC; only applies when capacity is set.
spec.moverDefaults.sourceColocation
Field Type Default Description
mode enum: Auto | Required | Disabled How the mover co-locates with the node an RWO source/destination PVC is attached to.
spec.moverDefaults.throttle
Field Type Default Description
downloadBytesPerSecond integer Cap download throughput in bytes/sec (--download-bytes-per-second).
readOpsPerSecond integer Cap read/list ops/sec (--read-requests-per-second).
uploadBytesPerSecond integer Cap upload throughput in bytes/sec (--upload-bytes-per-second).
writeOpsPerSecond integer Cap write ops/sec (--write-requests-per-second).

spec.parameters

Field Type Default Description
epoch object Epoch-manager tuning — how fast kopia closes epochs and therefore how fast index blobs get compacted.
spec.parameters.epoch
Field Type Default Description
advanceOnCount integer Index blobs in an epoch that trigger an advance, once older than minDuration (kopia default 20).
advanceOnSizeMiB integer Total index size in an epoch that triggers an advance, once older than minDuration (kopia default 10 MiB).
Named MiB, not MB, with an explicit rename rather than the derived camelCase (advanceOnSizeMb, which reads as megabit). The unit is genuinely mebibytes — kopia's --epoch-advance-on-size-mb multiplies by 1048576, so 10 is 10485760 bytes — even though kopia's own log renders the result as "MB". That ambiguity is this field's main hazard; the API surface should not reproduce it.
checkpointFrequency integer Epochs between full index checkpoints (kopia default 7).
deleteParallelism integer Parallelism for epoch cleanup deletions (kopia default 4).
minDuration string Minimum epoch age before it may advance (kopia default 24h). A Go-style duration (6h, 90m). The advance gate — no blob count closes an epoch younger than this.
refreshFrequency string How often clients re-read epoch state (kopia default 20m). Go-style duration.

spec.scheduleDefaults

Field Type Default Description
timezone string IANA timezone name applied to every consuming cron that doesn't set its own timezone (e.g. America/New_York). Set once here instead of repeating it on every SnapshotPolicy.verification, RepositoryReplication.schedule, and Maintenance.schedule cron.

spec.server

Field Type Default Description
namespace string required Target namespace for the server Deployment/Service (and generated Secret).
auth union UI authentication mode; omitted ⇒ ServerAuth::Generate (never no-auth).
podSecurityContext core/v1 PodSecurityContext Pod-level security context for the server pod (notably supplementalGroups for NFS exports).
readOnly boolean Connect the server's repository read-only so the UI cannot mutate backups (browse + restore only).
resources core/v1 ResourceRequirements Resource requests/limits for the server pod.
securityContext core/v1 SecurityContext Override the hardened default container security context.
service object How the server is exposed as a Kubernetes Service.
spec.server.auth

Externally tagged — set exactly one of: generate · insecure · secretRef.

Field Type Default Description
generate object The operator mints random UI credentials into an owned Secret; the safe default.
insecure object No UI authentication; requires an explicit acknowledgeInsecure: true.
secretRef object The user supplies UI credentials via a Secret (name + the two keys).
spec.server.auth.generate
Field Type Default Description
username string UI username to provision (default kopia).
spec.server.auth.insecure
Field Type Default Description
acknowledgeInsecure boolean false Must be true; the webhook rejects insecure mode otherwise.
spec.server.auth.secretRef
Field Type Default Description
name string required Name of the Secret holding the UI credentials.
passwordKey string required Key within the secret holding the password.
usernameKey string required Key within the secret holding the username.
spec.server.service
Field Type Default Description
annotations map[string]string Annotations applied to the Service — the seam users wire their own Ingress/LoadBalancer controller onto.
port integer 51515
min 0; max 65535
Listen/Service port. Defaults to DEFAULT_SERVER_PORT when omitted.
type enum: ClusterIP | NodePort | LoadBalancer ClusterIP Service type. Defaults to ClusterIP (routing is the user's responsibility).

status

Field Type Default Description
allowedNamespaceCount integer Number of namespaces currently resolved by spec.allowedNamespaces.
backend string Mirror of spec.backend discriminant for the print column.
catalog object Catalog-materialization status (discovered-backup count, last refresh).
conditions []object Standard Kubernetes conditions (e.g. Connected, MaintenanceOwned).
health object Backend health-probe state (spec.health.probe), when enabled.
lastReverifyAt string Last reverify-request token honored from a Snapshot's re-probe nudge (RFC3339); the loop guard that keeps each request a one-shot.
observedGeneration integer metadata.generation of the spec last reconciled; drives staleness detection.
parameters object The kopia repository parameters actually observed at the last bootstrap. Compare against spec.parameters to see whether a declared value landed.
phase enum: Pending | Initializing | Ready | Degraded | Failed Lifecycle phase of a repository. A freshly admitted CR starts in Pending.
resolvedCredentialVersion string resourceVersion of the password Secret observed at the last connect attempt.
server object Resolved kopia server endpoint/auth, pinned by the reconciler.
storageStats object Repository size and snapshot counts from the last catalog scan.
uniqueId string Kopia repository unique ID.

status.catalog

Field Type Default Description
discoveredBackupCount integer How many Snapshot CRs were materialized from the catalog scan.
foreignSnapshotCount integer Snapshots in the last complete listing classified as another cluster's (see catalog.foreignSnapshots); never materialized under Ignore. As of catalog.lastRefreshAt — enable periodicRefresh to keep it current.
lastRefreshAt string RFC 3339 timestamp of the last catalog refresh.
scanRequestAttemptAt string RFC 3339 timestamp of the last bootstrap/scan attempt initiated BECAUSE OF a pending catalog-scan-requested-at token (i.e. the token arm was the reason the attempt fired). Used only to rate-limit token-driven attempts on a Ready-but-unreachable repository — it is never compared against the token for retirement (that's scanRequestHonored, by equality).
scanRequestHonored string The RFC3339 token VALUE of the kopiur.home-operations.com/catalog-scan-requested-at annotation last honored by a completed catalog scan. Compared by equality against the live annotation to decide whether a requested on-demand scan is still pending — deliberately NOT a timestamp comparison against lastRefreshAt (a periodic refresh completing after the request was made would otherwise look like it honored the request even though it started before the annotation was set).

status.conditions[]

Field Type Default Description
lastTransitionTime string required lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
message string required message is a human readable message indicating details about the transition. This may be an empty string.
reason string required reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
status string required status of the condition, one of True, False, Unknown.
type string required type of condition in CamelCase or in foo.example.com/CamelCase.
observedGeneration integer observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditionsx.observedGeneration is 9, the condition is out of date with respect to the current state of the instance.

status.health

Field Type Default Description
consecutiveProbeFailures integer Consecutive failing probes accrued; reset to zero on any success. The loud condition is raised only once this reaches the failure threshold.
firstFailureAt string RFC 3339 timestamp of the first failure in the current failing streak.
lastHealthyAt string RFC 3339 timestamp of the last successful probe (backend reachable, repo present).
lastProbeAt string RFC 3339 timestamp of the last completed probe (success or failure); drives the health_probe_due timer so the probe re-fires on cadence.
probeAttemptAt string RFC 3339 timestamp at which the last backend health probe was launched (the bootstrap Job created for it), cleared when its result is finalized.
This is the launch-side rate limit, and it is what makes the probe terminate. lastProbeAt is written only at finalize, so gating the launch on that alone recycles the bootstrap Job forever: the gate destroys every Job whose completion would have cleared it (#273). Never compared against lastProbeAt — see kopiur_controller::health::probe_action.

status.parameters

Field Type Default Description
epoch object The epoch parameters the repository reports.
status.parameters.epoch
Field Type Default Description
advanceOnCount integer required Observed index-blob count that triggers an epoch advance.
advanceOnSizeMiB integer required Observed total index size (MiB) that triggers an epoch advance.
checkpointFrequency integer required Observed epochs between full index checkpoints.
cleanupSafetyMargin string required Observed cleanup safety margin, as a Go-style duration. Reported for diagnosis; not settable through spec.parameters.
deleteParallelism integer required Observed epoch-cleanup delete parallelism.
enabled boolean required Whether kopia's epoch manager is enabled on this repository at all.
minDuration string required Observed minimum epoch age, as a Go-style duration.
refreshFrequency string required Observed epoch-state refresh frequency, as a Go-style duration.

status.server

Field Type Default Description
authMode string Resolved auth mode discriminant (Generate/SecretRef/Insecure).
endpoint string In-cluster endpoint, <service>.<namespace>.svc:<port>.
generatedSecretRef object For Generate mode: the operator-owned Secret holding the UI credentials.
namespace string Namespace the server objects were last applied to.
readOnly boolean Effective read-only state of the served connection.
status.server.generatedSecretRef
Field Type Default Description
name string required Name of the Secret.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.

status.storageStats

Field Type Default Description
indexBlobCount integer Number of content-index blobs (kopia index list) observed at the last bootstrap.
lastObservedAt string RFC 3339 timestamp these stats were last observed.
snapshotCount integer Total snapshots present in the repository (across all identities).
totalSize string Human-readable total on-disk size (e.g. 412Gi).
totalSizeBytes integer Logical bytes under management (the integer form of total_size): the sum, over each distinct snapshot source, of the most-recent snapshot's logical size. Exposed to backup preflight as repository.sizeBytes. This is repository total size, not backend free space (object stores don't report remaining capacity).

SnapshotPolicy

Scope: Namespaced · Short names: kopiasp · Print columns: Repository, Last-Snapshot, Last-Verified, Suspended, Age

spec

Field Type Default Description
repository object required Discriminated reference to a Repository or ClusterRepository.
adoption enum: Adopt | Ignore Whether a discovered snapshot whose resolved identity matches a live SnapshotPolicy is automatically adopted — re-attached (stamped with that policy's config label, status.origin flipped to Adopted) so GFS retention governs it and eventually prunes it, instead of it sitting in the catalog forever as an immortal discovered row.
compression object Compression algorithm + per-extension opt-outs.
copyMethod enum: Snapshot | Clone | Direct Snapshot How the source volume is captured before kopia reads it: Snapshot (default), Direct, or Clone.
credentialProjection object Opt-in credential-Secret projection into each backup mover's namespace (default off).
defaultDeletionPolicy enum: Delete | Retain | Orphan Delete Lifecycle of the underlying kopia snapshot when its Snapshot CR is deleted. Produced backups default to Delete; discovered snapshots are forced to Retain.
deletion object Deletion semantics for the Snapshot CRs carrying this recipe's config label.
errorHandling object Backup-side error handling: let a snapshot complete-with-errors instead of failing outright.
extraArgs []string Escape hatch for kopia flags not yet modeled.
files object Paths/patterns kopia should skip while snapshotting.
groupBy enum: VolumeGroupSnapshot | None VolumeGroupSnapshot Multi-PVC grouping strategy. Defaults to a consistent group snapshot across all PVCs; set None explicitly to accept independent per-PVC snapshots, because a silent per-PVC fallback would produce inconsistent backups.
hooks object Pre/post snapshot hooks that run in the workload, not the mover.
identity object Identity overrides — what kopia records as username@hostname:path.
mover object Per-recipe mover overrides (resources, cache, security context).
preflight object Named CEL preconditions evaluated before each backup run; opt-in (absent ⇒ no preflight). A failing check holds the Snapshot in Pending (PreflightFailed) and, after timeout, fails it.
retention object GFS retention, enforced by the operator pruning Snapshot CRs.
sources []object
maxItems 100
What to back up (at least one source; webhook-enforced).
staging object Staging knobs for copyMethod: Snapshot/Clone (e.g. how long to wait for the CSI capture to become ready before failing the backup).
suspend boolean Pause this recipe declaratively (schedules and reconcile skip a suspended policy).
upload object Upload parallelism (kopia's --max-parallel-snapshots / --max-parallel-file-reads).
verification object First-class backup verification; opt-in (absent ⇒ no verification runs).
volumeSnapshotClassName string VolumeSnapshotClass used when copyMethod snapshots/clones the source.

spec.repository

Field Type Default Description
name string required Name of the referenced Repository/ClusterRepository.
kind enum: Repository | ClusterRepository Repository Which repository CRD this points at; defaults to RepositoryKind::Repository.
namespace string Cross-namespace Repository reference; ignored/forbidden for ClusterRepository.

spec.compression

Field Type Default Description
compressor string kopia compressor name (e.g. zstd); absent leaves kopia's default.
neverCompress []string Filename globs to leave uncompressed (e.g. already-compressed media).

spec.credentialProjection

Field Type Default Description
enabled boolean false Copy the repository's credential Secret(s) into the namespace of each mover Job; off by default.

spec.deletion

Field Type Default Description
onPolicyDelete enum: Retain | Delete Retain Consulted by the Snapshot finalizer when the deletion is external and the owning SnapshotPolicy is gone. Absent resolves to Retain.

spec.errorHandling

Field Type Default Description
failFast boolean Abort the snapshot at the first error instead of collecting and continuing (snapshot create --fail-fast; kopia default: false). This is a snapshot create argv flag, not a policy set knob, but lives beside its semantic opposites (ignore*Errors) for discoverability.
ignoreDirErrors boolean Continue the snapshot when a directory cannot be read (--ignore-dir-errors).
ignoreFileErrors boolean Continue the snapshot when a file cannot be read (--ignore-file-errors).
ignoreUnknownTypes boolean Continue past entries of unknown type (--ignore-unknown-types).

spec.files

Field Type Default Description
ignoreCacheDirs boolean Honor CACHEDIR.TAG.
ignoreIdenticalSnapshots boolean Skip taking a new snapshot when the source is identical to the previous one.
ignoreRules []string ["/lost+found","System Volume Information","$RECYCLE.BIN","@eaDir",".snapshot"] Filename/path globs to exclude from the snapshot (e.g. *.tmp, */cache/*). Absent ⇒ default_ignore_rules (OS-artifact junk: /lost+found, System Volume Information, $RECYCLE.BIN, @eaDir, .snapshot). An explicit list REPLACES the default wholesale (re-add any entries you still want); explicit ignoreRules: [] opts fully out. NOT skip_serializing_if — an explicit empty list must round-trip as [], not vanish back to "absent" (which would silently resurrect the default on the next parse).

spec.hooks

Field Type Default Description
afterSnapshot []object Hooks run (in order) after the snapshot completes — e.g. resuming the workload.
beforeSnapshot []object Hooks run (in order) before the snapshot is taken — e.g. quiescing a database.
spec.hooks.afterSnapshot[]

Externally tagged — set exactly one of: httpRequest · runJob · workloadExec.

Field Type Default Description
httpRequest object Typed POST to a URL for cross-system orchestration.
runJob object Full JobSpec run as a one-shot Job (k8up PreBackupPod analog).
workloadExec object kubectl exec-style into a matched workload pod/container (the default form).
spec.hooks.afterSnapshot[].httpRequest
Field Type Default Description
url string required Target URL to call.
body string Optional request body.
continueOnFailure boolean If true, a failed request does not abort the backup (default: abort).
headers []object Additional request headers (e.g. Content-Type: application/json).
method string HTTP method (default POST).
timeout string Max time to wait for the response (Go duration string).
spec.hooks.afterSnapshot[].httpRequest.headers[]
Field Type Default Description
name string required Header name (case-insensitive; RFC 7230 token, e.g. Content-Type).
value string required Header value.
spec.hooks.afterSnapshot[].runJob
Field Type Default Description
jobSpec object (free-form) required The full Kubernetes JobSpec to run.
continueOnFailure boolean If true, a failed Job does not abort the backup (default: abort).
timeout string Max time to wait for the Job to complete (Go duration string).
spec.hooks.afterSnapshot[].workloadExec
Field Type Default Description
podSelector core/v1 LabelSelector required Label selector matching the workload pod(s) to read context/hooks from.
command []string Command + args to run inside the selected container.
container string Which container within the matched pod; absent uses the first/only container.
continueOnFailure boolean If true, a failed hook does not abort the backup (default: abort).
timeout string Max time to wait for the command (Go duration string, e.g. 2m).
spec.hooks.beforeSnapshot[]

Externally tagged — set exactly one of: httpRequest · runJob · workloadExec.

Field Type Default Description
httpRequest object Typed POST to a URL for cross-system orchestration.
runJob object Full JobSpec run as a one-shot Job (k8up PreBackupPod analog).
workloadExec object kubectl exec-style into a matched workload pod/container (the default form).
spec.hooks.beforeSnapshot[].httpRequest
Field Type Default Description
url string required Target URL to call.
body string Optional request body.
continueOnFailure boolean If true, a failed request does not abort the backup (default: abort).
headers []object Additional request headers (e.g. Content-Type: application/json).
method string HTTP method (default POST).
timeout string Max time to wait for the response (Go duration string).
spec.hooks.beforeSnapshot[].httpRequest.headers[]
Field Type Default Description
name string required Header name (case-insensitive; RFC 7230 token, e.g. Content-Type).
value string required Header value.
spec.hooks.beforeSnapshot[].runJob
Field Type Default Description
jobSpec object (free-form) required The full Kubernetes JobSpec to run.
continueOnFailure boolean If true, a failed Job does not abort the backup (default: abort).
timeout string Max time to wait for the Job to complete (Go duration string).
spec.hooks.beforeSnapshot[].workloadExec
Field Type Default Description
podSelector core/v1 LabelSelector required Label selector matching the workload pod(s) to read context/hooks from.
command []string Command + args to run inside the selected container.
container string Which container within the matched pod; absent uses the first/only container.
continueOnFailure boolean If true, a failed hook does not abort the backup (default: abort).
timeout string Max time to wait for the command (Go duration string, e.g. 2m).

spec.identity

Field Type Default Description
hostname string Override the hostname portion of username@hostname:path; absent uses the resolved default.
username string Override the username portion of username@hostname:path; absent uses the resolved default.

spec.mover

Field Type Default Description
cache object Override the repository's CacheDefaults for this recipe's movers.
inheritSecurityContextFrom union Copy the UID/GID security context from a live workload rather than hard-coding it.
Requires the workload to pin runAsUser (container or pod level): a UID that comes from the container image's USER line is invisible in the pod spec and cannot be inherited — the mover would silently run as its own image's UID instead.
May be combined with securityContext/podSecurityContext, which override it field-wise and act as the fallback when no workload pod can be resolved.
podSecurityContext core/v1 PodSecurityContext Pod security context for the mover (notably fsGroup for group-writable restore volumes). Same layering as securityContext: highest layer, merged field-wise, and combinable with inheritSecurityContextFrom.
privilegedMode boolean Opt-in, namespace-gated privileged mode; preserves UID/GID on restore.
resources core/v1 ResourceRequirements Resource requests/limits for the mover container.
securityContext core/v1 SecurityContext Container security context for the mover; merged field-wise over the hardened base, moverDefaults, and any inherited context — this is the highest layer, so every field set here wins. Combines with inheritSecurityContextFrom: fields you set override the workload's, fields you omit are inherited, and this context stands in alone when inheritance cannot resolve a pod.
ttlSecondsAfterFinished integer Per-recipe override of Job.spec.ttlSecondsAfterFinished so finished Jobs self-GC.
spec.mover.cache
Field Type Default Description
capacity string Size of the PVC backing the mover's kopia cache (e.g. 10Gi).
contentCacheSizeMb integer kopia content cache budget in MiB (--content-cache-size-mb).
metadataCacheSizeMb integer kopia metadata cache budget in MiB (--metadata-cache-size-mb).
mode enum: Ephemeral | Persistent How a mover's kopia cache volume is provisioned.
storageClassName string StorageClass for the cache PVC; absent uses the cluster default.
spec.mover.inheritSecurityContextFrom

Externally tagged — set exactly one of: pvcConsumer · snapshot · workloadSelector.

Field Type Default Description
pvcConsumer object Backup sources only: auto-derive the workload from the PVC this snapshot backs up.
snapshot object Restores only: inherit the identity RECORDED on the backup itself (Snapshot.status.recorded, decoded from the kopiur-meta kopia tag) — uid/gid/fsGroup the backup mover actually ran as. Needs no live workload pod, so it works on a rebuilt cluster and with target.populator. Rejected at admission on SnapshotPolicy/Maintenance (backups read the live workload; maintenance has no snapshot). Write it as snapshot: {} (an empty sub-object) — a bare snapshot: is null and rejected.
workloadSelector object Inherit from workload pod(s) matched by an explicit label selector (backup or restore).
spec.mover.inheritSecurityContextFrom.pvcConsumer
Field Type Default Description
container string Which container within the matched consumer pod to inherit from; absent uses the first/only.
spec.mover.inheritSecurityContextFrom.workloadSelector
Field Type Default Description
podSelector core/v1 LabelSelector required Label selector matching the workload pod(s) to read context/hooks from.
container string Which container within the matched pod; absent uses the first/only container.

spec.preflight

Field Type Default Description
checks []object
maxItems 50
Checks that must all pass (AND) before the backup launches. An empty list is an inert no-op (symmetric with verification absent).
timeout string How long to hold a Snapshot in Pending while a check is unsatisfied before failing it (Go-style duration like 10m or 1h; default 10m). A zero duration (0/0s) holds indefinitely (never fail on preflight).
spec.preflight.checks[]
Field Type Default Description
expr string required CEL bool predicate; the backup proceeds only when this evaluates true.
name string required
minLength 1; maxLength 63
Stable identifier surfaced in the Snapshot's status when this check blocks (e.g. maintenance-fresh). Unique within the policy.
message string Optional human message surfaced alongside the check name when it blocks.

spec.retention

Field Type Default Description
keepAnnual integer
min 0
Keep one snapshot per year for the most-recent N years.
keepDaily integer
min 0
Keep one snapshot per day for the most-recent N days.
keepHourly integer
min 0
Keep one snapshot per hour for the most-recent N hours.
keepLatest integer
min 0
Keep the N most-recent snapshots regardless of age.
keepMonthly integer
min 0
Keep one snapshot per month for the most-recent N months.
keepWeekly integer
min 0
Keep one snapshot per week for the most-recent N weeks.

spec.sources[]

Externally tagged — set exactly one of: nfs · pvc · pvcSelector.

Field Type Default Description
acknowledgeLiveMutation boolean Acknowledges that copyMethod: Direct + readOnly: false lets the kubelet recursively chgrp the live volume to the mover's fsGroup and make it group-writable — permanently, while the workload is running. Required for that combination alone.
Ignored (not rejected) otherwise: it is an acknowledgement, never harmful to carry, and rejecting a stale one would make switching copyMethod between Direct and Snapshot/Clone a two-step edit in both directions.
nfs object An inline NFS export to back up directly. Mutually exclusive with pvc/pvcSelector.
pvc object Single PVC by name. Mutually exclusive with pvcSelector/nfs.
pvcSelector object Label/namespace selector matching many PVCs. Mutually exclusive with pvc/nfs.
readOnly boolean true Mount the source read-only (default true; kopia only ever reads it).
Set false only to make fsGroup work on the source. The kubelet applies fsGroup by recursively chgrp-ing the volume and adding group-write — and it skips that walk entirely on a read-only mount, which is why a mover fsGroup/fsGroupChangePolicy otherwise has no effect here. Under copyMethod: Snapshot/Clone the walk rewrites the throwaway staged PVC and never touches your data. Under copyMethod: Direct it rewrites the LIVE volume, which requires acknowledgeLiveMutation.
Not supported on an nfs source: the kubelet does not apply fsGroup to in-tree NFS volumes at all, so a read-write mount would grant nothing.
sourcePathOverride string
maxLength 4096
What kopia records as the source path (default /pvc/<name>, or the NFS export path).
sourcePathStrategy enum: PvcName | PvcNamespacedName PvcName How a selector-matched PVC's source path is derived. Only relevant for pvcSelector sources, where one recipe expands to many PVCs and each needs a distinct kopia source path. Defaults to PvcName.
spec.sources[].nfs
Field Type Default Description
path string required Exported path on the NFS server (e.g. /export/kopia or /mnt/eros/Media).
server string required NFS server hostname or IP (e.g. nas.lan or expanse.internal).
spec.sources[].pvc
Field Type Default Description
name string required Name of the PersistentVolumeClaim to back up (in the SnapshotPolicy's namespace).
spec.sources[].pvcSelector
Field Type Default Description
labelSelector core/v1 LabelSelector Standard Kubernetes label selector matching the PVCs to include.
namespaceSelector object Restricts the search to specific namespaces; absent means the policy's own namespace.
spec.sources[].pvcSelector.namespaceSelector
Field Type Default Description
matchNames []string Exact namespace names to search; empty means the policy's own namespace.

spec.staging

Field Type Default Description
accessModes []enum: ReadWriteOnce | ReadOnlyMany | ReadWriteMany | ReadWriteOncePod Access modes for the staged PVC. Empty ⇒ copy the source PVC's modes. ReadOnlyMany pairs with snapshot-backed read-only classes (e.g. CephFS backingSnapshot); the mover mounts the staged PVC read-only to match, and rejects it at admission if a source sets readOnly: false (a read-only stage cannot be mounted read-write).
storageClassName string StorageClass for the staged PVC — the temporary PVC restored from the CSI VolumeSnapshot (copyMethod: Snapshot) or cloned from the source (copyMethod: Clone). Absent ⇒ the staged PVC copies the source PVC's class. Must belong to the same CSI driver as the source (staging fails fast on a mismatch). Flagship use: a rook-ceph CephFS class with backingSnapshot: "true", which mounts the snapshot shallowly (metadata-only, near-instant, read-only) instead of running a full subvolume clone that can take many minutes on small-file-heavy volumes.
timeout string How long each staging phase may take before the backup is failed (Go-style duration like 10m or 1h; default 10m): first the staged VolumeSnapshot becoming readyToUse (measured from its creation), then — on an Immediate-binding StorageClass — the staged PVC binding (a fresh budget measured from the PVC's creation, covering the CSI restore/clone). A transient CSI/snapshot-controller error during either wait is retried, never fatal on its own — only this deadline fails staging. A zero duration (0/0s) waits indefinitely. Raise this for backends whose snapshots or clones take long (e.g. cloud snapshots of large volumes, CephFS full clones of small-file-heavy volumes).

spec.upload

Field Type Default Description
limitMb integer snapshot create --upload-limit-mb: abort the snapshot once this many MB have been uploaded (kopia default: 0 — unlimited). Named limitMb rather than uploadLimitMb to avoid the upload.uploadLimitMb stutter; like failFast, this is a snapshot create argv flag, not a policy set knob, but lives here beside its parallelism siblings.
maxParallelFileReads integer --max-parallel-file-reads: file-read concurrency within a snapshot.
maxParallelSnapshots integer --max-parallel-snapshots: how many sources snapshot concurrently.

spec.verification

Field Type Default Description
deep object Schedule + knobs for the rarer scratch-restore test; absent ⇒ no deep verification.
quick object Quick (blob-level) verification tier; absent ⇒ no quick verification. Its cron lives under quick.schedule (matching deep.schedule), see QuickVerification.
successExpr string CEL pass/fail predicate over the verify result; applies to both tiers.
verifyFilesPercent integer
min 0; max 255
How many files quick verifies fully (--verify-files-percent); absent leaves kopia's default.
spec.verification.deep
Field Type Default Description
schedule object required Cron + jitter for the deep restore-test (e.g. weekly).
capacity string Size of the ephemeral scratch PVC (e.g. 10Gi); absent falls back to a node-ephemeral emptyDir.
parallel integer
min 0
restore --parallel: restore parallelism for the scratch-restore (deep verify IS a restore under the hood); absent leaves kopia's default.
storageClassName string StorageClass for the ephemeral scratch PVC; absent uses the cluster default (only with capacity).
spec.verification.deep.schedule
Field Type Default Description
cron string required The cron expression, parsed by croner; may contain an H placeholder for deterministic jitter.
jitter string Optional deterministic jitter window as a Go-style duration string (e.g. 30m).
timezone string IANA timezone the cron is evaluated in (e.g. America/Chicago); absent uses the enclosing schedule's timezone, else the controller default (UTC).
spec.verification.quick
Field Type Default Description
fileParallelism integer
min 0
--file-parallelism: parallelism for file verification (kopia default: unset).
fileQueueLength integer
min 0
--file-queue-length: queue length for file verification (kopia default: 20000).
maxErrors integer
min 0
--max-errors: stop after this many errors (kopia default: 0, meaning stop at the first error).
parallel integer
min 0
--parallel: verification parallelism (kopia default: 8).
schedule object Cron + jitter + timezone for the frequent blob-level verify; absent ⇒ quick tier disabled.
spec.verification.quick.schedule
Field Type Default Description
cron string required The cron expression, parsed by croner; may contain an H placeholder for deterministic jitter.
jitter string Optional deterministic jitter window as a Go-style duration string (e.g. 30m).
timezone string IANA timezone the cron is evaluated in (e.g. America/Chicago); absent uses the enclosing schedule's timezone, else the controller default (UTC).

status

Field Type Default Description
adoption object Summary of automatic adoption of discovered snapshots into this recipe.
conditions []object Standard Kubernetes conditions (e.g. RepositoryReachable, GroupSnapshotSupported).
lastSuccessfulSnapshot string RFC3339 timestamp of the most recent successful child Snapshot from this recipe.
lastVerified string RFC3339 timestamp of the most recent successful verification (any tier).
observedGeneration integer metadata.generation last reconciled, for staleness detection.
resolved object What would be passed to kopia — pinned at admission.
retention object Summary of GFS retention pruning against this config's Snapshot CRs.

status.adoption

Field Type Default Description
lastAdoptedCount integer
min 0
Number of discovered Snapshot CRs adopted by the last adoption pass.
lastAdoptionAt string RFC3339 timestamp of the last adoption pass that adopted at least one snapshot.
scanRequestedAt string RFC3339 token echoing an in-flight on-demand adoption scan request for this policy's identity; cleared once honored.
scanRequestedIdentity string The resolved kopia identity the requested scan was scoped to, pinned at request time so a later identity-changing edit can't retarget an in-flight scan.
skippedByRetention integer
min 0
Identity-matching discovered snapshots the last adoption pass left discovered because spec.retention would prune them immediately under the effective deletionPolicy (Retain/Orphan — a CR-only prune that would re-discover and re-adopt forever). 0/absent when nothing was withheld. See the AdoptionSkippedByRetention event for the levers.
totalAdopted integer
min 0
Running total of Snapshot CRs ever adopted into this recipe.

status.conditions[]

Field Type Default Description
lastTransitionTime string required lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
message string required message is a human readable message indicating details about the transition. This may be an empty string.
reason string required reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
status string required status of the condition, one of True, False, Unknown.
type string required type of condition in CamelCase or in foo.example.com/CamelCase.
observedGeneration integer observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditionsx.observedGeneration is 9, the condition is out of date with respect to the current state of the instance.

status.resolved

Field Type Default Description
identity object The resolved username@hostname identity.
sources []object The concrete PVCs + source paths after selector expansion.
status.resolved.identity
Field Type Default Description
hostname string required The final hostname kopia records, fixed at admission.
username string required The final username kopia records, fixed at admission.
sourcePath string The resolved snapshot source path, when applicable (username@hostname:path).
status.resolved.sources[]
Field Type Default Description
pvc string namespace/name of the PVC, as kopia sees it.
sourcePath string The source path kopia records for this PVC.

status.retention

Field Type Default Description
activeSnapshotCount integer CRs currently inside the GFS window.
lastPruneAt string RFC3339 timestamp of the last prune pass.
lastPruneDeleted integer Number of Snapshot CRs deleted by the last prune pass.

Snapshot

Scope: Namespaced · Short names: kopiasnap · Print columns: Phase, Origin, Snapshot, Age

spec

Field Type Default Description
deletionPolicy enum: Delete | Retain | Orphan Lifecycle of the underlying kopia snapshot when its Snapshot CR is deleted. Produced backups default to Delete; discovered snapshots are forced to Retain.
description string
maxLength 1024
Free-form text recorded on the kopia snapshot manifest (snapshot create --description). Per-invocation by nature — scheduled/discovered Snapshots never set this (no templated descriptions).
failurePolicy object Mover Job retry and deadline limits for this run.
onScheduleDelete enum: Retain | Delete What the deletion of a SnapshotSchedule does to the Snapshot CRs it produced (which Kubernetes GC cascade-deletes via their ownerReference). Default Retain: the CRs are removed but their kopia snapshots survive and the catalog rediscovers them as origin: discovered. Delete opts into the cascade: each Snapshot's own deletionPolicy applies.
Deliberately 2-variant (not reusing DeletionPolicy): an Orphan in cascade position would differ from Retain only in per-CR event/metric bookkeeping — an invalid state made unrepresentable. The guard's Retain is exactly DeletionPolicy::Retain's semantics (CR removed, kopia snapshot stays, catalog rediscovers it), deliberately NOT the Orphan event storm (no per-CR "orphaned" event/metric for every produced Snapshot).
pin boolean Exempt this snapshot from GFS retention.
policyRef object The SnapshotPolicy recipe to run; absent for discovered backups.
tags map[string]string Free-form tags attached to the kopia snapshot manifest itself (snapshot create --tags), e.g. reason: pre-upgrade — durable in the repository, independent of this CR. Keys must be non-empty, colon-free (kopia splits on the first colon), and must not start with the reserved kopiur prefix; at most 10 tags, keys ≤ 63 bytes, values ≤ 256 bytes (webhook-enforced).

spec.failurePolicy

Field Type Default Description
activeDeadlineSeconds integer Mover Job.spec.activeDeadlineSeconds — wall-clock cap after which a running run is killed.
backoffLimit integer Mover Job.spec.backoffLimit — retries before a failed run is marked failed.
podStartupDeadlineSeconds integer Seconds a non-starting (wedged) mover pod may sit before the run is failed; default 300s.

spec.policyRef

Field Type Default Description
name string required Name of the referenced SnapshotPolicy.
namespace string Namespace of the SnapshotPolicy; absent = same namespace as the referrer.

status

Field Type Default Description
cleanup object Post-run cleanup bookkeeping, so each cleanup runs at most once per Snapshot.
conditions []object Standard Kubernetes conditions (e.g. SourcesQuiesced, SnapshotCreated).
failure object Structured terminal-failure detail (kopia error class, stderr tail, retry hint).
hooks object Hook-execution bookkeeping so each hook list runs exactly once per Snapshot.
job object The mover Job backing this run; absent for discovered.
logTail string The last lines of the run's output, written by the mover at the terminal transition.
observedGeneration integer metadata.generation last reconciled, for staleness detection.
origin enum: scheduled | manual | discovered | adopted How a Snapshot came to exist. Canonical value mirrored from the kopiur.home-operations.com/origin label. Origin drives the deletion-policy default: discovered backups are forced to Retain because the operator did not create those snapshots.
phase enum: Pending | Running | Succeeded | Failed | Deleting | Discovered Lifecycle phase of a Snapshot.
pinned boolean The observed kopia-side pin state: Some(true) if pinned, Some(false) if unpinned, None before any pin reconcile.
preflightSince string RFC 3339 timestamp of the first reconcile where the repository was Ready but a spec.preflight check was failing. The one-shot anchor for the preflight timeout deadline (so the budget covers preflight only, not the earlier repository-not-Ready wait). Cleared once every preflight check passes, so a later failing episode gets a fresh budget rather than a stale anchor.
recorded object The mover identity recorded on the kopia snapshot itself (the kopiur-meta tag): the resolved effective uid/gid/fsGroup the backup ran as, plus its provenance. Produced runs stamp this at launch (from the same value written into the tag); discovered rows decode it from the tag during the catalog scan. Absent for pre-feature snapshots, foreign backups without the tag, or a tag this operator version cannot decode.
resolved object Frozen recipe values at run time (scheduled/manual).
snapshot object The kopia artifact this CR represents.
staged object The CSI staging objects the run created for copyMethod: Snapshot/Clone.
stats object Byte/file counts parsed from kopia's JSON output.
timing object Start/end/duration of the snapshot run.

status.cleanup

Field Type Default Description
credsReapedAt string When the run's projected credential Secrets were reclaimed (RFC 3339); absent until the reap has run. A projected copy is only needed while a mover Job can still load it via envFrom, but it is owner-ref'd to this CR, which long outlives that Job — so without an explicit reap it would sit in the workload namespace holding live repository credentials until the CR is pruned (#240).

status.conditions[]

Field Type Default Description
lastTransitionTime string required lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
message string required message is a human readable message indicating details about the transition. This may be an empty string.
reason string required reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
status string required status of the condition, one of True, False, Unknown.
type string required type of condition in CamelCase or in foo.example.com/CamelCase.
observedGeneration integer observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditionsx.observedGeneration is 9, the condition is out of date with respect to the current state of the instance.

status.failure

Field Type Default Description
kopiaErrorClass string required kopia error class (e.g. RepositoryUnavailable, AuthFailure).
message string required A short human-readable message: what failed, why, and how to fix it.
retryRecommended boolean required Whether retrying the same operation unchanged could succeed.
exitCode integer The process exit code, if one was reported.
stderrTail string The last lines of kopia's stderr, if any were captured (bounded by MAX_LOG_TAIL_BYTES).

status.hooks

Field Type Default Description
postCompletedAt string When the afterSnapshot list completed (RFC3339); absent until it has.
preCompletedAt string When the beforeSnapshot list completed (RFC3339); absent until it has.

status.job

Field Type Default Description
attempts integer Number of attempts so far (bounded by failurePolicy.backoffLimit).
name string Name of the mover Job.

status.recorded

Field Type Default Description
schema integer required The kopiur-meta schema version this value was written under. Writers emit the lowest schema that represents the data (currently KOPIUR_META_SCHEMA_V1); readers reject only a schema NEWER than they understand (degrading to recorded-absent, never an error).
src enum: inherited | explicit | defaults | unknown required Which layer pinned the recorded identity. Only inherited means the identity tracked the workload.
fsGroup integer The resolved pod-level fsGroup the mover ran with (the hardened default is 65532). Absent = no layer set one.
gid integer The resolved effective runAsGroup the mover ran as at backup time (container runAsGroup, else pod). Absent = image-determined.
uid integer The resolved effective runAsUser the mover ran as at backup time (container runAsUser, else pod). Absent = no layer pinned a UID, so the mover's UID was image-determined.

status.resolved

Field Type Default Description
credentialProjection object The recipe's spec.credentialProjection as it stood for this run.
The deletion path re-projects the mover's credentials, but the opt-in lives on the SnapshotPolicy — which a user may delete first. Pinning it here lets the finalizer honor the opt-in that was actually in force, instead of reading an absent recipe as "projection off" and blocking on a Secret that was never meant to be namespace-local (#255). Absent only on a Snapshot that predates the pin or never ran; a run always writes it, including enabled: false, so absent stays distinguishable from off.
repository object The repository this run targeted, frozen at run time.
sources []object The concrete PVCs + source paths backed up this run.
status.resolved.credentialProjection
Field Type Default Description
enabled boolean false Copy the repository's credential Secret(s) into the namespace of each mover Job; off by default.
status.resolved.repository
Field Type Default Description
name string required Name of the referenced Repository/ClusterRepository.
kind enum: Repository | ClusterRepository Repository Which repository CRD this points at; defaults to RepositoryKind::Repository.
namespace string Cross-namespace Repository reference; ignored/forbidden for ClusterRepository.
status.resolved.sources[]
Field Type Default Description
pvc string namespace/name of the PVC, as kopia sees it.
sourcePath string The source path kopia recorded for this PVC.

status.snapshot

Field Type Default Description
identity object required The username@hostname:path identity recorded for this snapshot.
kopiaSnapshotID string required kopia's snapshot ID — the handle the finalizer uses to delete content.
description string The kopia snapshot description (snapshot create --description), when one is recorded and non-empty. For discovered rows this is copied from the repository listing TRUNCATED to 1024 bytes (char-boundary-safe) — the value is foreign-writer-controlled and must never fail the CR write.
status.snapshot.identity
Field Type Default Description
hostname string required The final hostname kopia records, fixed at admission.
username string required The final username kopia records, fixed at admission.
sourcePath string The resolved snapshot source path, when applicable (username@hostname:path).

status.staged

Field Type Default Description
copyMethod string The resolved capture method (Snapshot or Clone) that produced this stage.
pvcName string Name of the staged PersistentVolumeClaim the mover mounts in place of the live source PVC.
ready boolean true once the stage is ready for the mover.
stagingTimeoutSeconds integer The resolved spec.staging.timeout (seconds) pinned when the stage was stamped, so the running-Job staged-PVC bind watchdog never re-resolves a policy that may have been edited or deleted mid-run. 0 = wait indefinitely.
storageClassName string StorageClass of the staged PVC — spec.staging.storageClassName when set, else the source PVC's class. Pinned for observability (e.g. confirming a CephFS shallow-clone class actually took effect).
volumeSnapshotName string Name of the VolumeSnapshot created from the source PVC (copyMethod: Snapshot only).

status.stats

Field Type Default Description
bytesNew integer Bytes newly uploaded this run (after dedup/compression).
filesFailed integer Count of source entries kopia could not read and excluded, making the snapshot incomplete.
filesModified integer Count of files changed since the previous snapshot.
filesNew integer Count of files new since the previous snapshot.
filesUnchanged integer Count of files unchanged since the previous snapshot.
sizeBytes integer Total logical size of the snapshot in bytes.

status.timing

Field Type Default Description
durationSeconds integer Wall-clock duration in seconds.
endTime string RFC3339 end time of the run.
startTime string RFC3339 start time of the run.

SnapshotSchedule

Scope: Namespaced · Short names: kopiasched · Print columns: Config, Schedule, Suspended, Age

spec

Field Type Default Description
schedule object required Cron, jitter, timezone, and concurrency for the firing cadence.
deletion object Deletion semantics for the Snapshots this schedule produced.
failedJobsHistoryLimit integer 10
min 0
Maximum number of failed Snapshot CRs from this schedule to retain (default 10; 0 keeps none).
policyRef object The single SnapshotPolicy this schedule invokes; mutually exclusive with policySelector.
policySelector core/v1 LabelSelector Label selector fanning out over SnapshotPolicy objects; mutually exclusive with policyRef.

Validation rules (enforced at admission):

  • exactly one of policyRef or policySelector

spec.schedule

Field Type Default Description
cron string required Cron expression with Jenkins-style H substitution.
concurrencyPolicy enum: Forbid | Allow | Replace Forbid How to handle a firing while a prior run is still in flight (default Forbid).
jitter string Deterministic jitter (Go-style duration), derived from (scheduleUID, slot).
runOnCreate boolean false Whether to fire immediately on create (default false).
startingDeadlineSeconds integer If a slot is missed by more than this many seconds, skip it instead of firing late.
suspend boolean Skip future firings while true.
timezone string IANA timezone the cron is evaluated in; absent uses the controller's default.

spec.deletion

Field Type Default Description
onScheduleDelete enum: Retain | Delete Retain Stamped onto every produced Snapshot at creation (spec.onScheduleDelete) and consulted by the Snapshot finalizer when the owning schedule is gone or replaced. Absent resolves to Retain.

spec.policyRef

Field Type Default Description
name string required Name of the referenced SnapshotPolicy.
namespace string Namespace of the SnapshotPolicy; absent = same namespace as the referrer.

status

Field Type Default Description
conditions []object Standard Kubernetes conditions surfacing schedule health.
consecutiveFailures integer Count of back-to-back failed runs; resets on success.
lastSchedule object Most recent firing (cron + jitter, pinned).
lastSuccessfulSchedule object The most recent firing whose Snapshot succeeded.
nextSchedule object The next firing slot the controller has computed (cron + jitter, pinned).
observedGeneration integer The metadata.generation this status reflects, for staleness detection.

status.conditions[]

Field Type Default Description
lastTransitionTime string required lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
message string required message is a human readable message indicating details about the transition. This may be an empty string.
reason string required reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
status string required status of the condition, one of True, False, Unknown.
type string required type of condition in CamelCase or in foo.example.com/CamelCase.
observedGeneration integer observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditionsx.observedGeneration is 9, the condition is out of date with respect to the current state of the instance.

status.lastSchedule

Field Type Default Description
at string The RFC3339 instant this slot fired (or is scheduled to); also accepts the scheduledAt alias.
snapshotRef object The Snapshot CR this slot produced, when one was created.
timezone string The IANA timezone the cron was evaluated in when this slot was pinned (nextSchedule only). Recorded so the controller can detect an effective-timezone change — a spec.schedule.timezone edit or a change to the target repository's scheduleDefaults.timezone — and invalidate the pinned wall-clock slot, recomputing it in the new zone. Absent on legacy pins written before this field existed (treated as "unchanged").
status.lastSchedule.snapshotRef
Field Type Default Description
name string required The Snapshot's metadata.name (same namespace as the schedule).

status.lastSuccessfulSchedule

Field Type Default Description
at string The RFC3339 instant this slot fired (or is scheduled to); also accepts the scheduledAt alias.
snapshotRef object The Snapshot CR this slot produced, when one was created.
timezone string The IANA timezone the cron was evaluated in when this slot was pinned (nextSchedule only). Recorded so the controller can detect an effective-timezone change — a spec.schedule.timezone edit or a change to the target repository's scheduleDefaults.timezone — and invalidate the pinned wall-clock slot, recomputing it in the new zone. Absent on legacy pins written before this field existed (treated as "unchanged").
status.lastSuccessfulSchedule.snapshotRef
Field Type Default Description
name string required The Snapshot's metadata.name (same namespace as the schedule).

status.nextSchedule

Field Type Default Description
at string The RFC3339 instant this slot fired (or is scheduled to); also accepts the scheduledAt alias.
snapshotRef object The Snapshot CR this slot produced, when one was created.
timezone string The IANA timezone the cron was evaluated in when this slot was pinned (nextSchedule only). Recorded so the controller can detect an effective-timezone change — a spec.schedule.timezone edit or a change to the target repository's scheduleDefaults.timezone — and invalidate the pinned wall-clock slot, recomputing it in the new zone. Absent on legacy pins written before this field existed (treated as "unchanged").
status.nextSchedule.snapshotRef
Field Type Default Description
name string required The Snapshot's metadata.name (same namespace as the schedule).

Restore

Scope: Namespaced · Short names: kopiarestore · Print columns: Phase, Source, Age

spec

Field Type Default Description
source union required Where to read data from (snapshotRef, fromPolicy, or identity).
target union required Where to write the restored data (pvc, pvcRef, or populator).
credentialProjection object Opt-in copying of the repository's credential Secret(s) into the mover's namespace (default off).
failurePolicy object Mover Job retry/deadline limits (backoffLimit, activeDeadlineSeconds).
mover object Per-run mover overrides for this restore's Job (resources, cache, securityContext).
options object kopia restore behavior (file deletion, permission/atomicity handling).
policy object What to do when the referenced snapshot doesn't exist yet, and how long to wait.
repository object The repository to read from; derived from source when omitted, required only with source.identity.

Validation rules (enforced at admission):

  • exactly one of target.pvc, target.pvcRef, target.populator

spec.source

Externally tagged — set exactly one of: fromPolicy · identity · snapshotRef.

Field Type Default Description
fromPolicy object A SnapshotPolicy CR, resolved via identity even with no Snapshot CR present (deploy-or-restore).
identity object A raw kopia identity (foreign writers / aged-out catalog); requires spec.repository.
snapshotRef object A Snapshot CR (scheduled, manual, or discovered).
spec.source.fromPolicy
Field Type Default Description
name string required Name of the SnapshotPolicy whose identity selects the snapshot.
asOf string Restore the newest snapshot at or before this RFC3339 timestamp (point-in-time).
namespace string Namespace of the SnapshotPolicy; absent = the Restore's own namespace.
offset integer 0 Which snapshot to pick: 0 = latest, 1 = previous, and so on.
spec.source.identity
Field Type Default Description
hostname string required The kopia hostname to match.
username string required The kopia username to match.
asOf string Restore the newest snapshot at or before this RFC3339 timestamp (point-in-time).
offset integer Which snapshot to pick: 0 = latest, 1 = previous, and so on.
snapshotID string Pin an exact kopia snapshot by ID.
sourcePath string The kopia source path to match; absent matches any path for the identity.
spec.source.snapshotRef
Field Type Default Description
name string required Name of the referenced object.
namespace string Namespace of the referenced object; absent = same namespace as the referrer.

spec.target

Externally tagged — set exactly one of: populator · pvc · pvcRef.

Field Type Default Description
populator object Passive populator mode: the restore is claimed by a PVC's spec.dataSourceRef.
pvc object Operator creates the PVC.
pvcRef object Write into an existing PVC.
spec.target.pvc
Field Type Default Description
name string required Name of the PVC to create.
accessModes []enum: ReadWriteOnce | ReadOnlyMany | ReadWriteMany | ReadWriteOncePod Access modes for the new PVC; empty defaults to ReadWriteOnce. Closed enum in the schema; a non-canonical value persisted before enforcement decodes as PvcAccessMode::Unknown and is rejected per-CR with the value quoted (webhook + reconciler, via validate_access_modes) instead of poisoning the typed watcher.
capacity string Requested size of the new PVC (e.g. 100Gi).
storageClassName string StorageClass for the new PVC; absent uses the cluster default.
spec.target.pvcRef
Field Type Default Description
name string required Name of the referenced object.
namespace string Namespace of the referenced object; absent = same namespace as the referrer.

spec.credentialProjection

Field Type Default Description
enabled boolean false Copy the repository's credential Secret(s) into the namespace of each mover Job; off by default.

spec.failurePolicy

Field Type Default Description
activeDeadlineSeconds integer Mover Job.spec.activeDeadlineSeconds — wall-clock cap after which a running run is killed.
backoffLimit integer Mover Job.spec.backoffLimit — retries before a failed run is marked failed.
podStartupDeadlineSeconds integer Seconds a non-starting (wedged) mover pod may sit before the run is failed; default 300s.

spec.mover

Field Type Default Description
cache object Override the repository's CacheDefaults for this recipe's movers.
inheritSecurityContextFrom union Copy the UID/GID security context from a live workload rather than hard-coding it.
Requires the workload to pin runAsUser (container or pod level): a UID that comes from the container image's USER line is invisible in the pod spec and cannot be inherited — the mover would silently run as its own image's UID instead.
May be combined with securityContext/podSecurityContext, which override it field-wise and act as the fallback when no workload pod can be resolved.
podSecurityContext core/v1 PodSecurityContext Pod security context for the mover (notably fsGroup for group-writable restore volumes). Same layering as securityContext: highest layer, merged field-wise, and combinable with inheritSecurityContextFrom.
privilegedMode boolean Opt-in, namespace-gated privileged mode; preserves UID/GID on restore.
resources core/v1 ResourceRequirements Resource requests/limits for the mover container.
securityContext core/v1 SecurityContext Container security context for the mover; merged field-wise over the hardened base, moverDefaults, and any inherited context — this is the highest layer, so every field set here wins. Combines with inheritSecurityContextFrom: fields you set override the workload's, fields you omit are inherited, and this context stands in alone when inheritance cannot resolve a pod.
ttlSecondsAfterFinished integer Per-recipe override of Job.spec.ttlSecondsAfterFinished so finished Jobs self-GC.
spec.mover.cache
Field Type Default Description
capacity string Size of the PVC backing the mover's kopia cache (e.g. 10Gi).
contentCacheSizeMb integer kopia content cache budget in MiB (--content-cache-size-mb).
metadataCacheSizeMb integer kopia metadata cache budget in MiB (--metadata-cache-size-mb).
mode enum: Ephemeral | Persistent How a mover's kopia cache volume is provisioned.
storageClassName string StorageClass for the cache PVC; absent uses the cluster default.
spec.mover.inheritSecurityContextFrom

Externally tagged — set exactly one of: pvcConsumer · snapshot · workloadSelector.

Field Type Default Description
pvcConsumer object Backup sources only: auto-derive the workload from the PVC this snapshot backs up.
snapshot object Restores only: inherit the identity RECORDED on the backup itself (Snapshot.status.recorded, decoded from the kopiur-meta kopia tag) — uid/gid/fsGroup the backup mover actually ran as. Needs no live workload pod, so it works on a rebuilt cluster and with target.populator. Rejected at admission on SnapshotPolicy/Maintenance (backups read the live workload; maintenance has no snapshot). Write it as snapshot: {} (an empty sub-object) — a bare snapshot: is null and rejected.
workloadSelector object Inherit from workload pod(s) matched by an explicit label selector (backup or restore).
spec.mover.inheritSecurityContextFrom.pvcConsumer
Field Type Default Description
container string Which container within the matched consumer pod to inherit from; absent uses the first/only.
spec.mover.inheritSecurityContextFrom.workloadSelector
Field Type Default Description
podSelector core/v1 LabelSelector required Label selector matching the workload pod(s) to read context/hooks from.
container string Which container within the matched pod; absent uses the first/only container.

spec.options

Field Type Default Description
enableFileDeletion boolean Delete files in the target that are not present in the snapshot (exact mirror); off by default. Wired to kopia's --[no-]delete-extra (previously a silent no-op — see issue #216 gap sweep).
ignoreErrors boolean --[no-]ignore-errors: ignore all restore errors and continue (kopia default false).
ignorePermissionErrors boolean Continue past permission errors during restore (default true).
overwriteDirectories boolean --[no-]overwrite-directories: overwrite existing directories in the target (kopia default true).
overwriteFiles boolean --[no-]overwrite-files: overwrite existing files in the target (kopia default true).
overwriteSymlinks boolean --[no-]overwrite-symlinks: overwrite existing symlinks in the target (kopia default true).
parallel integer
min 0
--parallel: restore parallelism (kopia default 8; 1 disables parallelism).
skipExisting boolean --[no-]skip-existing: skip files/symlinks that already exist in the target (kopia default false).
skipOwners boolean --[no-]skip-owners: skip restoring file owners (kopia default false).
skipPermissions boolean --[no-]skip-permissions: skip restoring file permissions (kopia default false).
skipTimes boolean --[no-]skip-times: skip restoring file modification times (kopia default false).
writeFilesAtomically boolean Write files atomically via a temp file + rename (default true).
writeSparseFiles boolean --[no-]write-sparse-files: attempt to write files sparsely, allocating the minimum disk space needed (kopia default false).

spec.policy

Field Type Default Description
onMissingSnapshot enum: Fail | Continue What to do when the resolved source matches no snapshot. Defaults to Fail (fail-closed) so an explicit restore can never silently no-op; choose Continue to provision an empty volume instead (deploy-or-restore).
waitTimeout string How long to wait for the source snapshot to appear before giving up (e.g. 5m).

spec.repository

Field Type Default Description
name string required Name of the referenced Repository/ClusterRepository.
kind enum: Repository | ClusterRepository Repository Which repository CRD this points at; defaults to RepositoryKind::Repository.
namespace string Cross-namespace Repository reference; ignored/forbidden for ClusterRepository.

status

Field Type Default Description
conditions []object Standard Kubernetes conditions carrying the human-readable status/reason.
failure object Structured terminal-failure detail (kopia error class, stderr tail, retry hint).
logTail string The last lines of the run's output, written by the mover at the terminal transition.
observedGeneration integer metadata.generation last reconciled, so stale status is detectable.
phase enum: Pending | Resolving | Restoring | Completed | Failed Lifecycle phase of a restore.
progress object Bytes/files restored so far, patched periodically by the mover.
resolved object The source resolved and pinned at admission; never re-resolved.
sourceKind string The pinned source kind (SnapshotRef/FromPolicy/Identity); backs the SOURCE printer column.
target object Resolved target details (the PVC written to / populator handshake).
timing object Start/end timestamps for the restore run.

status.conditions[]

Field Type Default Description
lastTransitionTime string required lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
message string required message is a human readable message indicating details about the transition. This may be an empty string.
reason string required reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
status string required status of the condition, one of True, False, Unknown.
type string required type of condition in CamelCase or in foo.example.com/CamelCase.
observedGeneration integer observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditionsx.observedGeneration is 9, the condition is out of date with respect to the current state of the instance.

status.failure

Field Type Default Description
kopiaErrorClass string required kopia error class (e.g. RepositoryUnavailable, AuthFailure).
message string required A short human-readable message: what failed, why, and how to fix it.
retryRecommended boolean required Whether retrying the same operation unchanged could succeed.
exitCode integer The process exit code, if one was reported.
stderrTail string The last lines of kopia's stderr, if any were captured (bounded by MAX_LOG_TAIL_BYTES).

status.progress

Field Type Default Description
bytesRestored integer Total bytes restored so far.
filesRestored integer Total files restored so far.

status.resolved

Field Type Default Description
identity object The resolved kopia identity (username@hostname:path) of the snapshot.
kopiaSnapshotID string The exact kopia snapshot manifest id the source resolved to; pinned once.
pinnedAt string Timestamp at which the source was pinned (RFC3339).
repository object The repository the snapshot lives in, resolved from the source.
resolution enum: Snapshot | NoSnapshot Which outcome the source resolution pinned, once and never re-resolved.
snapshotRef object The concrete Snapshot CR the source resolved to, when applicable.
status.resolved.identity
Field Type Default Description
hostname string required The final hostname kopia records, fixed at admission.
username string required The final username kopia records, fixed at admission.
sourcePath string The resolved snapshot source path, when applicable (username@hostname:path).
status.resolved.repository
Field Type Default Description
name string required Name of the referenced Repository/ClusterRepository.
kind enum: Repository | ClusterRepository Repository Which repository CRD this points at; defaults to RepositoryKind::Repository.
namespace string Cross-namespace Repository reference; ignored/forbidden for ClusterRepository.
status.resolved.snapshotRef
Field Type Default Description
name string required Name of the referenced object.
namespace string Namespace of the referenced object; absent = same namespace as the referrer.

status.target

Field Type Default Description
pvcPrime string Populator handshake (passive / pvc-create modes).
pvcRef object The PVC actually written to (created or pre-existing).
status.target.pvcRef
Field Type Default Description
name string required Name of the referenced object.
namespace string Namespace of the referenced object; absent = same namespace as the referrer.

status.timing

Field Type Default Description
endTime string When the restore reached a terminal phase (RFC3339).
startTime string When the mover began restoring (RFC3339).

Maintenance

Scope: Namespaced · Short names: kopiamaint · Print columns: Repository, Owner, Age

spec

Field Type Default Description
ownership object required Maintenance ownership lease holder and takeover policy.
repository object required Reference to the Repository or ClusterRepository to maintain.
schedule object required quick (cheap) and full (--full, reclamation) maintenance crons.
credentialProjection object Opt-in projection of the repository's credential Secret(s) into this run's namespace (default off).
failurePolicy object How a failed maintenance run is retried and bounded (backoff, deadline).
mover object Mover (Job pod) overrides for the maintenance run.

spec.ownership

Field Type Default Description
owner string required Stable lease holder identity (e.g. kopia-operator/nas-primary).
ownerAliases []string Previous lease strings still recognized as SELF (a migration path): when kopia's currently-recorded maintenance owner matches the owner derived from one of these aliases, a run treats the lease as its own — it claims it and re-stamps owner, upgrading the recorded owner to the current format. The operator populates this when a repository's managed Maintenance moves to a cluster-qualified lease (identityDefaults.cluster), so the transition never yields the lease to what merely looks like a foreign owner.
takeoverPolicy enum: Never | PromptCondition | Force Never What to do when the lease is already held by a different owner.

spec.repository

Field Type Default Description
name string required Name of the referenced Repository/ClusterRepository.
kind enum: Repository | ClusterRepository Repository Which repository CRD this points at; defaults to RepositoryKind::Repository.
namespace string Cross-namespace Repository reference; ignored/forbidden for ClusterRepository.

spec.schedule

Field Type Default Description
full object required Cron and jitter for kopia maintenance run --full (content reclamation).
quick object required Cron and jitter for kopia maintenance run (quick, cheap index/log work).
timezone string IANA timezone both crons are evaluated in; absent means the controller default.
spec.schedule.full
Field Type Default Description
cron string required The cron expression, parsed by croner; may contain an H placeholder for deterministic jitter.
jitter string Optional deterministic jitter window as a Go-style duration string (e.g. 30m).
timezone string IANA timezone the cron is evaluated in (e.g. America/Chicago); absent uses the enclosing schedule's timezone, else the controller default (UTC).
spec.schedule.quick
Field Type Default Description
cron string required The cron expression, parsed by croner; may contain an H placeholder for deterministic jitter.
jitter string Optional deterministic jitter window as a Go-style duration string (e.g. 30m).
timezone string IANA timezone the cron is evaluated in (e.g. America/Chicago); absent uses the enclosing schedule's timezone, else the controller default (UTC).

spec.credentialProjection

Field Type Default Description
enabled boolean false Copy the repository's credential Secret(s) into the namespace of each mover Job; off by default.

spec.failurePolicy

Field Type Default Description
activeDeadlineSeconds integer Mover Job.spec.activeDeadlineSeconds — wall-clock cap after which a running run is killed.
backoffLimit integer Mover Job.spec.backoffLimit — retries before a failed run is marked failed.
podStartupDeadlineSeconds integer Seconds a non-starting (wedged) mover pod may sit before the run is failed; default 300s.

spec.mover

Field Type Default Description
cache object Override the repository's CacheDefaults for this recipe's movers.
inheritSecurityContextFrom union Copy the UID/GID security context from a live workload rather than hard-coding it.
Requires the workload to pin runAsUser (container or pod level): a UID that comes from the container image's USER line is invisible in the pod spec and cannot be inherited — the mover would silently run as its own image's UID instead.
May be combined with securityContext/podSecurityContext, which override it field-wise and act as the fallback when no workload pod can be resolved.
podSecurityContext core/v1 PodSecurityContext Pod security context for the mover (notably fsGroup for group-writable restore volumes). Same layering as securityContext: highest layer, merged field-wise, and combinable with inheritSecurityContextFrom.
privilegedMode boolean Opt-in, namespace-gated privileged mode; preserves UID/GID on restore.
resources core/v1 ResourceRequirements Resource requests/limits for the mover container.
securityContext core/v1 SecurityContext Container security context for the mover; merged field-wise over the hardened base, moverDefaults, and any inherited context — this is the highest layer, so every field set here wins. Combines with inheritSecurityContextFrom: fields you set override the workload's, fields you omit are inherited, and this context stands in alone when inheritance cannot resolve a pod.
ttlSecondsAfterFinished integer Per-recipe override of Job.spec.ttlSecondsAfterFinished so finished Jobs self-GC.
spec.mover.cache
Field Type Default Description
capacity string Size of the PVC backing the mover's kopia cache (e.g. 10Gi).
contentCacheSizeMb integer kopia content cache budget in MiB (--content-cache-size-mb).
metadataCacheSizeMb integer kopia metadata cache budget in MiB (--metadata-cache-size-mb).
mode enum: Ephemeral | Persistent How a mover's kopia cache volume is provisioned.
storageClassName string StorageClass for the cache PVC; absent uses the cluster default.
spec.mover.inheritSecurityContextFrom

Externally tagged — set exactly one of: pvcConsumer · snapshot · workloadSelector.

Field Type Default Description
pvcConsumer object Backup sources only: auto-derive the workload from the PVC this snapshot backs up.
snapshot object Restores only: inherit the identity RECORDED on the backup itself (Snapshot.status.recorded, decoded from the kopiur-meta kopia tag) — uid/gid/fsGroup the backup mover actually ran as. Needs no live workload pod, so it works on a rebuilt cluster and with target.populator. Rejected at admission on SnapshotPolicy/Maintenance (backups read the live workload; maintenance has no snapshot). Write it as snapshot: {} (an empty sub-object) — a bare snapshot: is null and rejected.
workloadSelector object Inherit from workload pod(s) matched by an explicit label selector (backup or restore).
spec.mover.inheritSecurityContextFrom.pvcConsumer
Field Type Default Description
container string Which container within the matched consumer pod to inherit from; absent uses the first/only.
spec.mover.inheritSecurityContextFrom.workloadSelector
Field Type Default Description
podSelector core/v1 LabelSelector required Label selector matching the workload pod(s) to read context/hooks from.
container string Which container within the matched pod; absent uses the first/only container.

status

Field Type Default Description
conditions []object Standard Kubernetes conditions surfacing maintenance health.
full object Last/next-run state for the full maintenance schedule.
manualRun object State of the most recent annotation-requested out-of-band run; absent until one is requested.
observedGeneration integer The metadata.generation this status reflects, for staleness detection.
ownership object Current lease holder, if the lease has been claimed.
quick object Last/next-run state for the quick maintenance schedule.

status.conditions[]

Field Type Default Description
lastTransitionTime string required lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
message string required message is a human readable message indicating details about the transition. This may be an empty string.
reason string required reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
status string required status of the condition, one of True, False, Unknown.
type string required type of condition in CamelCase or in foo.example.com/CamelCase.
observedGeneration integer observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditionsx.observedGeneration is 9, the condition is out of date with respect to the current state of the instance.

status.full

Field Type Default Description
consecutiveFailures integer Count of back-to-back failed runs of this kind; resets on success.
lastContentReclaimedBytes integer Bytes of storage reclaimed by the most recent run of this kind.
lastHandledAt string RFC3339 instant the controller last observed this kind's per-slot Job reach terminal success.
lastRunAt string RFC3339 instant of the most recent run of this kind.
nextScheduledAt string RFC3339 instant of the next scheduled run of this kind (cron + jitter, pinned).

status.manualRun

Field Type Default Description
completedAt string RFC3339 instant the run reached a terminal phase.
mode enum: quick | full Which maintenance kind a manual (annotation-requested) run performs; the wire values are the run-mode annotation values. Defaults to quick.
phase enum: Running | Succeeded | Failed Lifecycle of a manual run. Closed enum.
requestedAt string The run-requested annotation value this status reflects (RFC3339).

status.ownership

Field Type Default Description
claimedAt string RFC3339 instant the lease was claimed.
owner string The current lease holder's identity (matches Ownership.owner).

status.quick

Field Type Default Description
consecutiveFailures integer Count of back-to-back failed runs of this kind; resets on success.
lastContentReclaimedBytes integer Bytes of storage reclaimed by the most recent run of this kind.
lastHandledAt string RFC3339 instant the controller last observed this kind's per-slot Job reach terminal success.
lastRunAt string RFC3339 instant of the most recent run of this kind.
nextScheduledAt string RFC3339 instant of the next scheduled run of this kind (cron + jitter, pinned).

RepositoryReplication

Scope: Namespaced · Short names: kopiarepl · Print columns: Source, Destination, Schedule, Last, Age

spec

Field Type Default Description
destination union required The backend to mirror to; must differ from the source's backend (webhook-enforced).
kopia repository sync-to is a blob-level copy: the destination inherits the source repository's format and encryption password verbatim, so there is no separate destination password to configure. The destination backend's own access credentials (e.g. S3 keys) ride its auth.secretRef, which — like the source's — must live in this CR's namespace.
schedule object required Cron and deterministic jitter for the replication runs.
sourceRef object required Reference to the Repository or ClusterRepository to mirror from.
mover object Mover (Job pod) overrides for the replication run.
suspend boolean Pause this replication; a suspended replication runs no syncs (default false).
sync object Tuning knobs for the underlying kopia repository sync-to invocation (issue #216). None reproduces today's behavior: sequential copy (--parallel unset), additive sync (no --delete), kopia's own --must-exist/--times/--update defaults, and no throughput cap.

spec.destination

Externally tagged — set exactly one of: azure · b2 · filesystem · gcs · gdrive · rclone · s3 · sftp · webDav.

Field Type Default Description
azure object Azure Blob Storage.
b2 object Backblaze B2.
filesystem object A local filesystem path, backed by a PVC the operator mounts into the mover.
gcs object Google Cloud Storage.
gdrive object Google Drive via kopia's native gdrive provider (service-account JSON). kopia marks this provider experimental / not maintained, and a native gdrive repository is not interchangeable with an rclone-backed Drive remote.
rclone object Any rclone remote (kopia shells out to rclone), broadening reach to providers without a native kopia backend.
s3 object Amazon S3 or any S3-compatible object store (MinIO, RustFS, Ceph RGW, …).
sftp object SFTP server.
webDav object WebDAV endpoint.
spec.destination.azure
Field Type Default Description
container string required Blob container holding the kopia repository.
auth object Access credentials (Secret ref / workload identity).
prefix string Blob-name prefix within the container; empty/absent means the container root.
storageAccount string Storage-account name (when not inferred from credentials).
spec.destination.azure.auth
Field Type Default Description
secretRef object Secret holding the backend's static access credentials (mutually exclusive with workloadIdentity).
workloadIdentity object Use a cloud-federated ServiceAccount instead of static keys (mutually exclusive with secretRef).
spec.destination.azure.auth.secretRef
Field Type Default Description
name string required Name of the Secret.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.
spec.destination.azure.auth.workloadIdentity
Field Type Default Description
serviceAccountName string required Name of the ServiceAccount the mover pod runs as, resolved in the Job's own namespace.
spec.destination.b2
Field Type Default Description
bucket string required B2 bucket holding the kopia repository.
auth object Access credentials (application key ID/key Secret); Secret-only.
prefix string Object-name prefix within the bucket; empty/absent means the bucket root.
spec.destination.b2.auth
Field Type Default Description
secretRef object Secret holding the backend's access credentials, read by well-known keys.
spec.destination.b2.auth.secretRef
Field Type Default Description
name string required Name of the Secret.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.
spec.destination.filesystem
Field Type Default Description
path string required Mount path inside the mover pod where kopia writes the repository (e.g. /repo).
volume union What backs path: a PVC or an inline NFS export; absent for a path already on the node/image.
spec.destination.filesystem.volume

Externally tagged — set exactly one of: nfs · pvc.

Field Type Default Description
nfs object An inline NFS export mounted directly (no PVC).
pvc object A PersistentVolumeClaim mounted read-write at the repo path.
spec.destination.filesystem.volume.nfs
Field Type Default Description
path string required Exported path on the NFS server (e.g. /export/kopia or /mnt/eros/Media).
server string required NFS server hostname or IP (e.g. nas.lan or expanse.internal).
spec.destination.filesystem.volume.pvc
Field Type Default Description
name string required Name of the PersistentVolumeClaim to mount (in the mover's namespace).
spec.destination.gcs
Field Type Default Description
bucket string required GCS bucket holding the kopia repository.
auth object Access credentials (service-account key Secret / workload identity).
prefix string Object-name prefix within the bucket; empty/absent means the bucket root.
spec.destination.gcs.auth
Field Type Default Description
secretRef object Secret holding the backend's static access credentials (mutually exclusive with workloadIdentity).
workloadIdentity object Use a cloud-federated ServiceAccount instead of static keys (mutually exclusive with secretRef).
spec.destination.gcs.auth.secretRef
Field Type Default Description
name string required Name of the Secret.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.
spec.destination.gcs.auth.workloadIdentity
Field Type Default Description
serviceAccountName string required Name of the ServiceAccount the mover pod runs as, resolved in the Job's own namespace.
spec.destination.gdrive
Field Type Default Description
folderId string required Google Drive folder ID that holds the kopia repository.
credentialsSecretRef object Secret holding the Google service-account JSON used to reach the folder, read by the well-known key KOPIA_GDRIVE_CREDENTIALS. Absent means kopia falls back to ambient credentials (GOOGLE_APPLICATION_CREDENTIALS or instance metadata).
spec.destination.gdrive.credentialsSecretRef
Field Type Default Description
name string required Name of the Secret.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.
spec.destination.rclone
Field Type Default Description
remotePath string required rclone path in remote:path form (the remote name must exist in the supplied rclone config).
configSecretRef object Secret holding the rclone.conf that defines the remote referenced by remote_path.
startupTimeout string How long kopia waits for its embedded rclone serve to come up before failing the connect, as a Go duration (e.g. 2m). kopia's default is 15s; raise it for slow remotes whose repository metadata/indexes load through the rclone/WebDAV bridge and take longer than the default budget.
spec.destination.rclone.configSecretRef
Field Type Default Description
name string required Name of the Secret.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.
spec.destination.s3
Field Type Default Description
bucket string required Bucket holding the kopia repository.
auth object Access credentials (Secret ref / workload identity).
endpoint string S3 endpoint host. Omit for AWS; set it for MinIO/RustFS/other S3-compatible stores.
prefix string Key prefix under the bucket, letting several repositories share one bucket (e.g. clusters/prod/). Empty/absent means the bucket root.
region string S3 region. Required by AWS and some compatible providers.
tls object TLS overrides for self-signed CAs or HTTP-only endpoints.
spec.destination.s3.auth
Field Type Default Description
secretRef object Secret holding the backend's static access credentials (mutually exclusive with workloadIdentity).
workloadIdentity object Use a cloud-federated ServiceAccount instead of static keys (mutually exclusive with secretRef).
spec.destination.s3.auth.secretRef
Field Type Default Description
name string required Name of the Secret.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.
spec.destination.s3.auth.workloadIdentity
Field Type Default Description
serviceAccountName string required Name of the ServiceAccount the mover pod runs as, resolved in the Job's own namespace.
spec.destination.s3.tls
Field Type Default Description
caBundleRef object CA bundle (PEM) used to verify the endpoint's certificate, sourced from a ConfigMap.
disableTls boolean Disable TLS entirely and talk plain HTTP; maps to kopia's --disable-tls.
insecureSkipVerify boolean Skip TLS certificate verification (still uses TLS); maps to kopia's --disable-tls-verification.
spec.destination.s3.tls.caBundleRef
Field Type Default Description
configMapName string Name of the ConfigMap holding the value (e.g. a CA bundle).
key string Which key inside the ConfigMap to read.
spec.destination.sftp
Field Type Default Description
host string required SFTP server hostname or IP.
path string required Remote path on the server that holds the kopia repository.
auth object Credentials (SSH private key / known-hosts) sourced from a Secret; Secret-only.
port integer
min 0; max 65535
TCP port; defaults to 22 when absent.
username string SSH username to connect as.
spec.destination.sftp.auth
Field Type Default Description
secretRef object Secret holding the backend's access credentials, read by well-known keys.
spec.destination.sftp.auth.secretRef
Field Type Default Description
name string required Name of the Secret.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.
spec.destination.webDav
Field Type Default Description
url string required WebDAV collection URL holding the kopia repository.
auth object HTTP basic-auth credentials sourced from a Secret; Secret-only.
spec.destination.webDav.auth
Field Type Default Description
secretRef object Secret holding the backend's access credentials, read by well-known keys.
spec.destination.webDav.auth.secretRef
Field Type Default Description
name string required Name of the Secret.
namespace string Namespace of the Secret; absent = same namespace as the referrer. A ClusterRepository is cluster-scoped and has no namespace of its own, so when IT reads the Secret (to connect, to bootstrap, or to run its repository server) an absent namespace means the operator's namespace (KOPIUR_NAMESPACE). A workload mover (Snapshot/Restore/Maintenance) still needs the Secret in its OWN namespace — envFrom is namespace-local — so put it there, or use credentialProjection, which needs this namespace set EXPLICITLY to know what to copy. Set it whenever anything other than the operator itself reads the Secret.

spec.schedule

Field Type Default Description
cron string required The cron expression, parsed by croner; may contain an H placeholder for deterministic jitter.
jitter string Optional deterministic jitter window as a Go-style duration string (e.g. 30m).
timezone string IANA timezone the cron is evaluated in (e.g. America/Chicago); absent uses the enclosing schedule's timezone, else the controller default (UTC).

spec.sourceRef

Field Type Default Description
name string required Name of the referenced Repository/ClusterRepository.
kind enum: Repository | ClusterRepository Repository Which repository CRD this points at; defaults to RepositoryKind::Repository.
namespace string Cross-namespace Repository reference; ignored/forbidden for ClusterRepository.

spec.mover

Field Type Default Description
cache object Override the repository's CacheDefaults for this recipe's movers.
inheritSecurityContextFrom union Copy the UID/GID security context from a live workload rather than hard-coding it.
Requires the workload to pin runAsUser (container or pod level): a UID that comes from the container image's USER line is invisible in the pod spec and cannot be inherited — the mover would silently run as its own image's UID instead.
May be combined with securityContext/podSecurityContext, which override it field-wise and act as the fallback when no workload pod can be resolved.
podSecurityContext core/v1 PodSecurityContext Pod security context for the mover (notably fsGroup for group-writable restore volumes). Same layering as securityContext: highest layer, merged field-wise, and combinable with inheritSecurityContextFrom.
privilegedMode boolean Opt-in, namespace-gated privileged mode; preserves UID/GID on restore.
resources core/v1 ResourceRequirements Resource requests/limits for the mover container.
securityContext core/v1 SecurityContext Container security context for the mover; merged field-wise over the hardened base, moverDefaults, and any inherited context — this is the highest layer, so every field set here wins. Combines with inheritSecurityContextFrom: fields you set override the workload's, fields you omit are inherited, and this context stands in alone when inheritance cannot resolve a pod.
ttlSecondsAfterFinished integer Per-recipe override of Job.spec.ttlSecondsAfterFinished so finished Jobs self-GC.
spec.mover.cache
Field Type Default Description
capacity string Size of the PVC backing the mover's kopia cache (e.g. 10Gi).
contentCacheSizeMb integer kopia content cache budget in MiB (--content-cache-size-mb).
metadataCacheSizeMb integer kopia metadata cache budget in MiB (--metadata-cache-size-mb).
mode enum: Ephemeral | Persistent How a mover's kopia cache volume is provisioned.
storageClassName string StorageClass for the cache PVC; absent uses the cluster default.
spec.mover.inheritSecurityContextFrom

Externally tagged — set exactly one of: pvcConsumer · snapshot · workloadSelector.

Field Type Default Description
pvcConsumer object Backup sources only: auto-derive the workload from the PVC this snapshot backs up.
snapshot object Restores only: inherit the identity RECORDED on the backup itself (Snapshot.status.recorded, decoded from the kopiur-meta kopia tag) — uid/gid/fsGroup the backup mover actually ran as. Needs no live workload pod, so it works on a rebuilt cluster and with target.populator. Rejected at admission on SnapshotPolicy/Maintenance (backups read the live workload; maintenance has no snapshot). Write it as snapshot: {} (an empty sub-object) — a bare snapshot: is null and rejected.
workloadSelector object Inherit from workload pod(s) matched by an explicit label selector (backup or restore).
spec.mover.inheritSecurityContextFrom.pvcConsumer
Field Type Default Description
container string Which container within the matched consumer pod to inherit from; absent uses the first/only.
spec.mover.inheritSecurityContextFrom.workloadSelector
Field Type Default Description
podSelector core/v1 LabelSelector required Label selector matching the workload pod(s) to read context/hooks from.
container string Which container within the matched pod; absent uses the first/only container.

spec.sync

Field Type Default Description
deleteExtra boolean --delete: prune destination-only blobs so the mirror is an exact copy (kopia default false — additive sync, never removes destination content). Named deleteExtra, not kopia's bare delete: a delete: true key on backup-adjacent YAML is dangerously ambiguous at a glance.
CAUTION: with this true, blobs present at the destination but absent from the source are deleted on every run.
maxDownloadSpeedBytesPerSecond integer --max-download-speed: cap read throughput from the source, in bytes/sec (kopia default: unlimited).
maxUploadSpeedBytesPerSecond integer --max-upload-speed: cap write throughput to the destination, in bytes/sec (kopia default: unlimited).
mustExist boolean --[no-]must-exist: fail the sync instead of initializing the destination's repository-format blob (kopia default false — sync-to may create the destination layout on first run).
parallel integer
min 0
--parallel: number of concurrent blob-copy workers (kopia default 1 — sequential, the root cause of #216's multi-week seed times to R2).
times boolean --[no-]times: synchronize blob modification times to the destination, when the destination backend supports it (kopia default true).
update boolean --[no-]update: update blobs already present at the destination when the source copy is newer (kopia default true).

status

Field Type Default Description
conditions []object Standard Kubernetes conditions (Ready, Reconciling, Stalled).
destinationBackend string The destination backend kind, for the DESTINATION print column.
lastReplicated string RFC3339 timestamp of the most recent successful replication run.
lastReplicatedBlobs integer Blobs replicated by the last successful run (best-effort).
lastReplicatedBytes integer Bytes replicated by the last successful run (best-effort from kopia output).
nextScheduledAt string RFC3339 timestamp of the next scheduled replication run (cron + jitter, pinned).
observedGeneration integer metadata.generation last reconciled, for staleness detection / kstatus.
phase enum: Pending | Replicating | Succeeded | Failed | Suspended Lifecycle phase of a replication.

status.conditions[]

Field Type Default Description
lastTransitionTime string required lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
message string required message is a human readable message indicating details about the transition. This may be an empty string.
reason string required reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.
status string required status of the condition, one of True, False, Unknown.
type string required type of condition in CamelCase or in foo.example.com/CamelCase.
observedGeneration integer observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditionsx.observedGeneration is 9, the condition is out of date with respect to the current state of the instance.