The operator creates a transient Job for each due or manually requested backup. The Job authenticates to OpenBao,
streams a Raft snapshot to object storage, and records the result on status.backup. Snapshot bytes do not pass
through the controller.
Before you begin
Prepare two independent identities:
- An OpenBao identity that can read
sys/storage/raft/snapshot. Prefer a JWT role bound to the generated<cluster>-backup-serviceaccount; usetokenSecretRefonly as a compatibility path. - An object-storage identity. Use
credentialsSecretRef, workload-identity metadata, or S3roleArn.
When self-init OIDC bootstrap is enabled, an empty jwtAuthRole resolves to openbao-operator-backup and the operator
creates the policy and role during initial bootstrap. Otherwise, configure jwtAuthRole or tokenSecretRef explicitly.
Hardened clusters also require explicit, port-scoped spec.network.egressRules and an explicit storage identity. See
Configure network policy.
Configure an S3 backup
This is the preferred minimal shape when self-init OIDC bootstrap is enabled:
Schedule an S3 snapshot
spec:
backup:
schedule: "0 3 * * *"
target:
provider: s3
endpoint: https://s3.amazonaws.com
bucket: openbao-backups
region: us-east-1
pathPrefix: clusters
credentialsSecretRef:
name: s3-backup-credentials
retention:
maxCount: 14
maxAge: 336hschedule is a five-field cron expression. The default provider is s3, but set it explicitly so intent remains
clear.
| Provider | Required target fields | Secret keys |
|---|---|---|
| S3 | endpoint, bucket; region defaults to us-east-1 | accessKeyId, secretAccessKey; optional sessionToken, region, caCert |
| GCS | bucket; optional gcs.project and endpoint | credentials.json |
| Azure | bucket, azure.storageAccount; optional azure.container and endpoint | accountKey or connectionString |
For platform workload identity, set target.workloadIdentity.serviceAccountAnnotations and, when required,
target.workloadIdentity.podLabels. For S3 web identity, target.roleArn also projects an STS token and configures the
Job explicitly.
Use a static OpenBao token only when needed
If JWT auth is unavailable, create a same-namespace Secret whose token value can read the Raft snapshot endpoint,
then reference it:
Reference a backup token
spec:
backup:
tokenSecretRef:
name: openbao-backup-tokenjwtAuthRole takes precedence when both fields are present. Rotate and revoke a static token as a high-sensitivity
credential.
Delegate configuration safely
The identity that changes the OpenBaoCluster needs:
geton each referenced Secretusecloudidentitieson the cluster when it setsroleArnor workload-identity metadatausecustomexecutableson the cluster when it overridesspec.backup.image(usehelperimagesremains a compatibility alias)
Admission rejects loopback and link-local storage endpoints. Hardened clusters also reject insecure TLS and ambient storage identity.
Trigger and verify a backup
The operator does not create a CronJob. Trigger an immediate backup by changing the one-shot annotation value:
Request a manual backup
kubectl -n <namespace> annotate openbaocluster <name> \
openbao.org/trigger-backup="$(date -u +%Y-%m-%dT%H:%M:%SZ)" --overwriteThe controller clears the annotation after accepting the request. It skips a duplicate request while another backup Job is active.
Inspect backup readiness and outcome
kubectl -n <namespace> get openbaocluster <name> \
-o jsonpath='{range .status.conditions[?(@.type=="BackupConfigurationReady")]}{.status}{" "}{.reason}{"\n"}{.message}{"\n"}{end}'
kubectl -n <namespace> get openbaocluster <name> -o jsonpath='{.status.backup}' | jq
kubectl -n <namespace> get jobs -l openbao.org/cluster=<name>A successful run advances lastBackupTime, lastBackupName, lastBackupSize, and lastBackupDuration. Failure
details are in lastFailureReason, lastFailureMessage, and lastFailureTime. Confirm the object independently in
storage before relying on it.
Set retention and pre-upgrade snapshots
maxCount: 0 and an empty maxAge mean unlimited retention. The operator applies retention after a successful
upload and never turns a retention error into a failed snapshot.
Enable spec.upgrade.preUpgradeSnapshot: true to require a snapshot before either upgrade strategy. Blue-green also
accepts spec.upgrade.blueGreen.preUpgradeSnapshot, but the top-level field keeps one policy across strategies. The
upgrade does not continue if its required snapshot fails.
A backup is complete only after you restore it into an isolated target and validate the recovered data.