OpenBao Backup Using AWS S3 or MinIO

This guide explains how to configure and manage automated OpenBao Raft snapshot backups using AWS S3 or MinIO. It applies to the Connect-specific connect-openbao cluster deployed with automated backup functionality.


Prerequisites

  • Kubernetes cluster access with kubectl configured and appropriate permissions to:

    • Read secrets in the OpenBao namespace (required for manual unseal keys backup).

    • View job logs and status (required for backup verification).

    • Access the namespace where connect-openbao is deployed.

  • MinIO is deployed and running — see the installation configuration in the Foundation MinIO Operator and Foundation MinIO Tenant.

  • Kubernetes secret for S3 access and TLS certificates:

    • If using AWS S3 → create a secret named aws-secret containing the access credentials.

    • If using MinIO → enable the code block below to copy the MinIO credentials, TLS certificates, and CA secrets from the foundation-cluster-zerotrust namespace into the namespace where connect-openbao is deployed.

      secretManager:
        ## Enable SecretManager
        enabled: true
        ## Set external secret manager/provider (only required if secrets are stored in an external provider)
        secretProvider: ""
        ## Secrets. Entries can be defined as yaml or stringified yaml, helm templating is supported.
        ## Map key is used for id on merges and as documentation. To remove existing entries, set key to null.
        ## Each entry configures secret to be managed/copied to Release namespace.
        ## Source secret is defined in .name and .namespace.
        ## Destination secret is defined in .template.
        ## Reference to source secret key must be in .template.value field.
        ## Value field supports templating, managed by the operator (must be escaped to avoid conflicts with helm templates).
        secrets:
          minio-accesskey:
            name: minio1-secret
            namespace: '{{ .Values.global.foundation.zeroTrustNamespace }}'
            template:
              key: accesskey
              name: '{{ include "connect-openbao.fullname" . }}-minio1-creds'
              namespace: '{{ .Release.Namespace }}'
              value: '{{`{{ index . "accesskey" }}`}}'
          minio-secretkey:
            name: minio1-secret
            namespace: '{{ .Values.global.foundation.zeroTrustNamespace }}'
            template:
              key: secretkey
              name: '{{ include "connect-openbao.fullname" . }}-minio1-creds'
              namespace: '{{ .Release.Namespace }}'
              value: '{{`{{ index . "secretkey" }}`}}'
          minio-ca:
            name: minio1-tls
            namespace: '{{ .Values.global.foundation.zeroTrustNamespace }}'
            template:
              key: ca.crt
              name: '{{ include "connect-openbao.fullname" . }}-minio1-tls'
              namespace: '{{ .Release.Namespace }}'
              value: '{{`{{ index . "ca.crt" }}`}}'
          minio-tls-key:
            name: minio1-tls
            namespace: '{{ .Values.global.foundation.zeroTrustNamespace }}'
            template:
              key: tls.key
              name: '{{ include "connect-openbao.fullname" . }}-minio1-tls'
              namespace: '{{ .Release.Namespace }}'
              value: '{{`{{ index . "tls.key" }}`}}'
          minio-tls-crt:
            name: minio1-tls
            namespace: '{{ .Values.global.foundation.zeroTrustNamespace }}'
            template:
              key: tls.crt
              name: '{{ include "connect-openbao.fullname" . }}-minio1-tls'
              namespace: '{{ .Release.Namespace }}'
              value: '{{`{{ index . "tls.crt" }}`}}'

OpenBao Backup Components

  • Raft snapshots: Capture a complete, point-in-time backup of the OpenBao Raft storage backend. Each snapshot includes all secrets, policies, authentication methods, and system configurations stored in OpenBao.

  • Unseal keys backup: Stores a reference copy of the first unseal key from the unseal secret alongside each snapshot. This reference helps verify and identify the correct unseal keys to use during restore operations. Note: Only the first key is stored for security reasons, the full unseal key set is not included.

  • Automated retention: Supports configurable retention period on snapshot objects managed via MinIO object lifecycle policies. Old snapshot backups are automatically deleted after the defined retention period. Note: Retention management is currently supported only for MinIO deployments.

Critical: Manual Unseal Keys Backup

You must manually backup the complete unseal secret.

Backups from connect-openbao Helm chart store only the first unseal key as a verification reference. For a complete restore, you must have all unseal keys.

Step 1: Export the complete unseal secret

# Export the complete unseal secret to a secure location
kubectl get secret connect-openbao-unseal-login -o yaml > openbao-unseal-keys-backup.yaml

# Or get just the encoded unseal keys data
kubectl get secret connect-openbao-unseal-login -o go-template='{{range $k,$v := .data}}{{$v|base64decode}}{{"\n"}}{{end}}'

Step 2: Store securely

  • Save the openbao-unseal-keys-backup.yaml file in a secure location.

  • This file contains all five unseal keys required to unseal OpenBao during a restore.

  • DO NOT store this file in the same location as your automated backups.

  • Use a password manager, encrypted storage, or a secure vault.

Configure OpenBao Backups

S3 Common Configuration

The following configuration applies to backup operations. All parameters must be set exactly as specified for S3/MinIO connectivity to work correctly.

  • s3CommonConfig.endpoint: S3/MinIO endpoint URL.

  • s3CommonConfig.region: S3/MinIO region.

  • s3CommonConfig.bucket: Target S3/MinIO bucket for backups.

  • s3CommonConfig.auth.accessKey: Access key for authentication.

  • s3CommonConfig.auth.secretKey: Secret key for authentication.

  • s3CommonConfig.externalCa.enabled: Set to true if using a custom CA certificate.

  • s3CommonConfig.externalCa.cert: Certificate file name (e.g., ca.crt).

  • s3CommonConfig.auth.secretName and s3CommonConfig.externalCa.secretName: Required if you provide your own Kubernetes secret (instead of relying on the SecretManager-generated one).

  • s3CommonConfig.forceAwsStyle: Set to true when using MinIO.

openbao:
  s3CommonConfig:
    endpoint: "https://minio.foundation-cluster-zerotrust:443"  # S3/MinIO URL
    region: "us-east-1" # Region name
    bucket: "foundation-pf" # Bucket name
    auth:
      # secretName: minio1-creds # Kubernetes secret containing the credentials. Leave this commented out if you are using the SecretManager block as specified in the prerequisites.
      accessKey: accesskey # Access key
      secretKey: secretkey # Secret key
    externalCa:
      enabled: true # Enable custom CA for TLS
      # secretName: minio1-tls # Kubernetes secret containing the TLS certificate. Leave this commented out if you are using the SecretManager block as specified in the prerequisites.
      cert: ca.crt # Certificate file name
    forceAwsStyle: "true" ## Required 'true' only for S3 MinIO

S3 Backup Configuration

The following configuration is required to enable backups for an OpenBao cluster:

  • s3BackupConfig.enabled: Set to true to enable backups.

  • s3BackupConfig.schedule: Define the backup schedule as a cron expression (configure as per requirement).

  • s3BackupConfig.backupPath: Specify the S3 bucket path where backups are stored. This value should be unique for each deployment.

  • Optional: s3BackupConfig.retention: Define the number of days to retain backups (MinIO only).

openbao:
  s3BackupConfig:
    enabled: true ## Set to false to disable backups for this cluster.
    schedule: "0 */6 * * *"  ## Cron schedule for backup jobs (every 6 hours)
    backupPath: "openbao-backup" ## S3 path to store backups
    retention: "180"  # Number of days to retain backups (supported only when using MinIO)

Add the S3 common configuration and backup configuration to the values.yaml file, then redeploy the connect-openbao release to enable backups.

Verification

After applying the backup configuration, verify that backups are stored correctly in S3/MinIO. Additionally, verify that the object lifecycle policy is properly configured for the backup path (e.g., openbao-backup) to ensure automated retention management.

MinIO Console UI

Sign in to the S3/MinIO console. Under the specified bucket (e.g. foundation-pf), you should see the following:

  • Snapshots: stored under foundation-pf/openbao-backup/snapshots/ with timestamped filenames

  • Unseal keys: stored under foundation-pf/openbao-backup/unseal-keys/

  • Object lifecycle policy: Verify that a lifecycle policy exists on the bucket that automatically removes objects from the backup path after the retention period specified in openbao.s3BackupConfig.retention

    MinIO Connect Openbao backup of snapshots
    MinIO Connect Openbao Backup of unseal key

Command Line Verification

View Backup History:

Verify that the scheduled backup CronJob exists and review its run history. The CronJob status displays the schedule and the last scheduled time. The jobs list shows currently running, failed, and successful jobs. By default, only the last three successful or failed jobs are listed. Each finished job has a time-to-live value of 300 seconds.

# Check CronJob status
kubectl -n foundation-env-default get cronjob connect-openbao-backup

# Check recent backup job runs
kubectl -n foundation-env-default get jobs -l app.kubernetes.io/name=connect-openbao

Check backup job logs:

Review the logs from backup job runs to confirm successful completion or to diagnose any failures.

# Get logs from the most recent backup job
kubectl -n foundation-env-default logs -l app.kubernetes.io/name=connect-openbao

Example successful backup log output:

{"level":"INFO","timeMillis":1762852323827,"pod":"connect-openbao-backup-29380872-cmfts","message":"Starting OpenBao backup to s3://foundation-pf/openbao-backup"}
{"level":"INFO","timeMillis":1762852323855,"pod":"connect-openbao-backup-29380872-cmfts","message":"Taking OpenBao snapshot..."}
{"level":"INFO","timeMillis":1762852323895,"pod":"connect-openbao-backup-29380872-cmfts","message":"Snapshot created successfully (Size: 24450 bytes)"}
{"level":"INFO","timeMillis":1762852324863,"pod":"connect-openbao-backup-29380872-cmfts","message":"Snapshot uploaded: s3://foundation-pf/openbao-backup/snapshots/2025-11-11_09-12-03-connect-openbao.snap"}
{"level":"INFO","timeMillis":1762852325778,"pod":"connect-openbao-backup-29380872-cmfts","message":"First unseal key uploaded: s3://foundation-pf/openbao-backup/unseal-keys/2025-11-11_09-12-03-connect-openbao.txt"}
{"level":"INFO","timeMillis":1762852325785,"pod":"connect-openbao-backup-29380872-cmfts","message":"Backup of snapshot and unseal-key completed successfully"}

Verify unseal key backup integrity:

Compare the first unseal key from your backup in Critical: Manual Unseal Keys Backup with the contents of MinIO backup foundation-pf/openbao-backup/<date+time>connect-openbao.txt to ensure they match.

Backup Job Configuration

You can customize the backup and retention jobs in the jobs section of the values.yaml file:

jobs:
  ## Configurations for s3 backup job
  backup:
    ...
    ...

  ## Configurations for s3 retention job (MinIO bucket lifecycle)
  retention:
    ...
    ...