Citrix SecurSpaces™

Back up the database

Back up the Citrix SecurSpaces™ database before upgrades, migrations, and major configuration changes, and on a recurring schedule in production. If you use HashiCorp Vault for secrets, back up Vault on the same schedule.

On-premises and self-managed (internal Percona MongoDB)

Important:

Backups are disabled by default on the internal database. If you run it in production, enabling, scheduling, and restore-testing them is your responsibility. See The SecurSpaces database.

Use Percona Backup for MongoDB (PBM) as your primary, scheduled backup mechanism. Use a manual mongodump only as a secondary, point-in-time snapshot before a specific change.

Primary: Percona Backup for MongoDB (PBM)

PBM is the backup tool built into the Percona Operator. It supports on-demand and scheduled logical and physical backups and point-in-time recovery to an external object store (Amazon S3, Azure Blob Storage, Google Cloud Storage, or any S3-compatible store).

The chart with Percona Operator 1.23.0 ships PBM 2.15.0. Backups remain disabled by default. Configure them in your Helm values with perconaServerMongoDB.backup, including enabled, storage, schedules, retention, and point-in-time recovery (PITR). Configure the database Kubernetes service account through perconaServerMongoDB.serviceAccount. The chart renders these settings into the Percona resources.

Keep backup settings in the values used for subsequent Helm upgrades. If you previously edited spec.backup directly, carry those settings into perconaServerMongoDB.backup before applying the new chart. Do not rely on custom-resource edits as the source of configuration for future upgrades.

For an existing deployment on operator 1.20.1, first complete the stepwise upgrade to 1.23.

Follow the Percona Operator backup documentation for the authoritative reference:

Example: enable PBM and back up to Amazon S3

This worked example follows the Percona Operator storage guide. Replace <release> with your SecurSpaces Helm release name and <namespace> with your SecurSpaces namespace. Run kubectl get psmdb -n <namespace> to confirm your cluster name — for SecurSpaces it is <release>-psmdb-db.

1. Create a Secret with your S3 credentials. Save as backup-s3-secret.yaml (the values are base64-encoded automatically when you use stringData):

apiVersion: v1
kind: Secret
metadata:
  name: sds-backup-s3
type: Opaque
stringData:
  AWS_ACCESS_KEY_ID: "<your-access-key-id>"
  AWS_SECRET_ACCESS_KEY: "<your-secret-access-key>"
<!--NeedCopy-->
kubectl apply -f backup-s3-secret.yaml -n <namespace>
<!--NeedCopy-->

2. Enable backups and define the storage in your Helm values. Add the following to the values file used for your deployment. The storage entry references the Secret created above:

perconaServerMongoDB:
  backup:
    enabled: true
    storages:
      s3-primary:
        type: s3
        s3:
          bucket: <your-backup-bucket>
          region: <your-region>        # for example, eu-central-1
          prefix: sds/strong-network   # optional sub-folder in the bucket
          credentialsSecret: sds-backup-s3
<!--NeedCopy-->

Apply the values using your normal Helm upgrade command and the same chart version. For example:

helm upgrade <release> ./ninjahchart-<version>.tgz -n <namespace> -f <your-values.yaml>
<!--NeedCopy-->

Note On AWS EKS you can grant bucket access with an IAM role for the service account (IRSA) and omit credentialsSecret. For Azure Blob or Google Cloud Storage, use the azure or gcs storage type instead of s3. For keyless GCS access, see GCS Workload Identity.

3. Take an on-demand backup. Create a PerconaServerMongoDBBackup resource that references your cluster and storage. Save as sds-backup.yaml:

apiVersion: psmdb.percona.com/v1
kind: PerconaServerMongoDBBackup
metadata:
  name: sds-backup-2026-07-02
  namespace: <namespace>
spec:
  clusterName: <release>-psmdb-db
  storageName: s3-primary
  type: logical                        # logical is the default; physical is also supported
<!--NeedCopy-->
kubectl apply -f sds-backup.yaml
<!--NeedCopy-->

4. Verify the backup completed. Track the backup resource until STATUS is ready:

kubectl get psmdb-backup -n <namespace>
<!--NeedCopy-->
NAME                   CLUSTER              STORAGE      DESTINATION                          TYPE      STATUS   AGE
sds-backup-2026-07-02  <release>-psmdb-db   s3-primary   s3://<bucket>/sds/strong-network/… logical   ready    2m
<!--NeedCopy-->

5. (Recommended) Add a schedule and point-in-time recovery. For ongoing protection, add a backup task and enable PITR in the same perconaServerMongoDB.backup section of your values file. Keep the storage definition from the previous step:

perconaServerMongoDB:
  backup:
    enabled: true
    pitr:
      enabled: true                    # continuous point-in-time recovery
    tasks:
      - name: daily-s3
        enabled: true
        schedule: "0 2 * * *"          # every day at 02:00 (cron)
        storageName: s3-primary
        retention:
          type: count
          count: 7                     # retain the 7 most recent scheduled backups
          deleteFromStorage: true
<!--NeedCopy-->

Apply the updated values with your Helm upgrade command and confirm new backups appear on schedule. As a best practice, store backups in a different failure domain from the cluster — a separate cloud region or account — so that a cluster or region failure does not also destroy your backups.

Note Reapplying the same Helm values preserves the backup configuration. In GKE validation, a second Helm upgrade with unchanged values caused no restarts and backups continued.

GCS Workload Identity

Percona Operator 1.23.0 supports keyless backups to Google Cloud Storage (GCS) using Workload Identity Federation for GKE. Use the native gcs storage type and omit gcs.credentialsSecret so PBM uses Application Default Credentials. No service account JSON key or HMAC key is required.

Prepare GKE and bucket access

You need a GKE cluster with Workload Identity enabled, the GKE metadata server enabled on the node pools running the database and operator pods, a GCS backup bucket, and permission to manage that bucket’s IAM policy. See Google’s Workload Identity setup guide.

Use perconaServerMongoDB.serviceAccount in the chart values to configure the database service account. Inspect the target chart for its service-account options before setting them:

helm show values ./ninjahchart-<version>.tgz
<!--NeedCopy-->

Grant bucket access to both Kubernetes service accounts: the one used by the database pods and the one used by the Percona operator. PBM needs access for backup and restore; the operator also needs access to delete expired backups from GCS. Discover the accounts from the running pods rather than assuming names:

kubectl get pods -n <namespace> \
  -o custom-columns='POD:.metadata.name,SERVICE_ACCOUNT:.spec.serviceAccountName'
<!--NeedCopy-->

The following example grants bucket-level object access directly to the two Kubernetes service-account principals. Replace the placeholders with the GKE cluster project’s ID and number, your namespace, bucket, and the actual account names. roles/storage.objectUser allows object reads, writes, listing, and deletion.

PROJECT_ID="<gke-project-id>"
PROJECT_NUMBER="<gke-project-number>"
NAMESPACE="<namespace>"
GCS_BUCKET="<backup-bucket>"
DATABASE_KSA="<database-service-account>"
OPERATOR_KSA="<operator-service-account>"
POOL="projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog"

for KSA in "$DATABASE_KSA" "$OPERATOR_KSA"; do
  gcloud storage buckets add-iam-policy-binding "gs://${GCS_BUCKET}" \
    --member="principal://iam.googleapis.com/${POOL}/subject/ns/${NAMESPACE}/sa/${KSA}" \
    --role="roles/storage.objectUser"
done
<!--NeedCopy-->

This direct-principal configuration does not require a Google service account key or service-account impersonation. If the operator runs in a different namespace, use that namespace in its IAM principal. If you change the database service account in Helm values, grant access to the new account as well.

Configure backups in Helm values

Merge this example into your deployment values alongside perconaServerMongoDB.serviceAccount. It enables logical backups every 10 minutes, continuous PITR oplog capture, and retention of two scheduled backups. Adjust the schedule and retention to your recovery requirements:

perconaServerMongoDB:
  backup:
    enabled: true
    storages:
      gcs-wi:
        type: gcs
        gcs:
          bucket: <backup-bucket>
          prefix: sds/mongodb
    pitr:
      enabled: true
    tasks:
      - name: gcs-every-10-minutes
        enabled: true
        schedule: "*/10 * * * *"
        storageName: gcs-wi
        type: logical
        retention:
          type: count
          count: 2
          deleteFromStorage: true
<!--NeedCopy-->

Apply the values with your normal Helm upgrade command after completing the Percona 1.23 upgrade. If migrating from key-based GCS access, remove credentialsSecret from the storage’s gcs settings in your values and verify it is absent from the resulting custom resource. A configured credentials Secret takes precedence over Workload Identity.

Verify backups, retention, and restore

  1. Create the on-demand PerconaServerMongoDBBackup shown in the S3 example above, using a unique name and storageName: gcs-wi. Wait for ready and confirm that the backup is present in the bucket.
  2. Confirm scheduled backups complete and continuous oplog chunks appear for PITR. PITR requires a completed base backup and oplog coverage for the chosen recovery time.
  3. Confirm retention deletes expired backups from both Kubernetes and GCS. If objects remain in GCS, check bucket permissions for the operator’s service account as well as the database account.
  4. Keep the same backup values for subsequent Helm upgrades and verify backups continue afterward.
  5. Test restoring into a replacement deployment, including a restore to a chosen second when using PITR. See Restore the database.

This flow was validated on GKE with direct bucket grants to both Kubernetes service accounts, on-demand and scheduled backups, PITR, retention count 2, and a repeated Helm upgrade. Recovery was also validated after deleting the deployment and volumes, reinstalling, and restoring to a chosen second; the recovered data matched and the platform was operational.

For authentication and storage details, see Percona’s GCS backup guide.

Secondary: logical snapshot with mongodump

The Percona upgrade kit takes a mongodump archive automatically before changing versions and includes matching restore and delete scripts. Keep this pre-upgrade archive until platform validation is complete. It is separate from your scheduled PBM backups and PITR storage.

mongodump / mongorestore are the official MongoDB database tools, and SecurSpaces uses them in its own replica-set migration procedure, so this is a supported method — not a workaround.

It is safe for ad hoc, quiesced snapshots (for example, immediately before an upgrade) when you follow these rules:

  • Quiesce writes before you dump, or dump from a secondary member. mongodump is only guaranteed consistent across collections when the database is not being written to. The simplest way to get a clean snapshot is to scale the SecurSpaces services to 0 first (the same quiesce step used in the restore procedure), then dump. mongodump cannot produce a cross-collection point-in-time snapshot of a single database on a live system — for online, point-in-time backups, use PBM instead.
  • Store the archive off-cluster and protect it (it contains encrypted secrets unless you use Vault).
  • Restore only into a quiesced platform (see the restore section), and never use destructive flags such as --drop against a live, in-use database.

It is not a replacement for scheduled, point-in-time disaster recovery — PBM (internal) or your managed service’s backups remain the primary strategy. Use mongodump to capture a known-good snapshot before a risky change.

# Identify the Percona pods
kubectl get psmdb
kubectl get pods -l app.kubernetes.io/name=percona-server-mongodb

# Confirm which pod is primary (look for "[direct: primary]" in the prompt)
kubectl exec -it <pod>-rs0-0 -- mongosh \
  --authenticationDatabase admin --username <admin-user> --password <admin-password>

# Dump the strong-network database from the primary (quiesce writes first)
kubectl exec -it <primary-pod> -- mongodump \
  --db strong-network \
  --username <admin-user> --password <admin-password> \
  --authenticationDatabase admin \
  --gzip --archive=/tmp/strong-network-backup.gz

# Copy the archive off the pod
kubectl cp <primary-pod>:/tmp/strong-network-backup.gz strong-network-backup.gz
<!--NeedCopy-->

For tool reference, see the MongoDB documentation for mongodump: https://www.mongodb.com/docs/database-tools/mongodump/

Hosted MongoDB services

When you use a managed MongoDB service, the provider supplies the backup tooling. Enable and configure it according to your recovery objectives (RPO/RTO).

SecurSpaces supports hosted MongoDB services on all three major hyperscalers (AWS, Azure, and Google Cloud). MongoDB Atlas is available on all three and is the option the SecurSpaces deployment guides reference. Use Atlas Cloud Backups with continuous (point-in-time) backup enabled:

If you use a cloud-native, MongoDB-compatible service instead of Atlas, enable its backup feature using the provider documentation below.

Platform Service Official backup documentation
AWS Amazon DocumentDB, or MongoDB Atlas on AWS Backing up and restoring in Amazon DocumentDB · Atlas Cloud Backups
Azure Azure Cosmos DB for MongoDB, or MongoDB Atlas on Azure Online backup and on-demand restore (Cosmos DB) · Reliability in Azure Cosmos DB for MongoDB (vCore)
GCP MongoDB Atlas on Google Cloud Atlas Cloud Backups. Google Cloud has no first-party managed MongoDB.

General guidance for hosted services:

  • Turn on continuous / point-in-time backup, not just daily snapshots, to minimize data loss.
  • Set a retention period that meets your compliance and recovery requirements.
  • Periodically test restoring a snapshot into a non-production cluster.
Back up the database