Citrix Secure Developer Spaces™

Administer the Citrix Secure Developer Spaces™ database

Citrix Secure Developer Spaces™ (SDS) stores its platform configuration and state in a MongoDB database. This database is the system of record for your deployment. If it is lost or corrupted, the platform cannot operate, even when every other component is healthy. This article explains what the database stores, how large to expect it to grow, why it is critical, and how to back it up and restore it for both self-managed and hosted MongoDB deployments.

This article is for platform administrators who deploy and operate SDS. It assumes you are familiar with Kubernetes, Helm, and your MongoDB hosting model.

What the database stores

The SDS database (default name strong-network) holds the metadata and state that define your platform. It does not store the contents of developer workspaces. Workspace file systems, Docker volumes, and source code live on Kubernetes Persistent Volume Claims (PVCs) and in your version control system, not in MongoDB.

The database stores, among other things:

  • Organizations, projects, and settings — organization, project, platform, and region configuration, section ordering, and setup checklists.

  • People and access — users, groups, roles, permissions, and identity-provider mappings.

  • Workspace definitions and state — workspace specifications, lifecycle status, schedules, SSH sessions, and the metadata that links a workspace to its project, owner, and persistent volumes.

  • Data mounts — data buckets and workspace mount-point definitions.

  • Integrations — connections to source control and other external services, plus their OAuth and access tokens.

  • Credentials and secrets — API keys and stored credentials. By default these are encrypted and stored in the database. If you configure HashiCorp Vault, secrets are stored in Vault instead of the database (see the next section).

  • Audit and event data — audit-trail and event-log records, plus usage, reporting, and compliance aggregates used by Insights and SIEM integration.

Note The exact collection layout is an internal implementation detail and can change between releases. Treat the database as an opaque unit for backup and restore — always back up and restore the whole database, not individual collections.

Where secrets live: database vs. HashiCorp Vault

By default, SDS encrypts secrets and credentials and stores them in the database, using an internal encryption key supplied at install time.

If you configure HashiCorp Vault (platform.hashicorpVault in the Helm values), SDS stores secrets in Vault instead of the database.

This distinction matters for backups: when you use Vault, a database backup alone does not capture your secrets — you must also back up Vault. When you do not use Vault, the database backup contains the (encrypted) secrets, and you must protect both the backup and the encryption key.

Why the database is critical

The database is the single source of truth for platform configuration and state. SDS services are stateless by design and read their configuration from MongoDB on startup and during operation. As a result:

  • No database, no platform. If MongoDB is unavailable, SDS services cannot start or serve requests, even when Kubernetes, networking, and storage are healthy.
  • Configuration loss is unrecoverable without a backup. Organizations, projects, users, integrations, and workspace metadata exist only in the database. Losing it means rebuilding your platform configuration from scratch.
  • Workspace access depends on it. Even though workspace file systems live on PVCs, the metadata that maps a developer to their workspace and its volumes lives in the database. Without that metadata, existing workspaces cannot be reattached.

For these reasons, treat the database as a tier-1, business-critical asset: run it with redundancy, back it up on a schedule, and test your restore procedure.

How the database is deployed

SDS supports three MongoDB hosting models. Your backup strategy depends on which one you use.

Hosting model When it is used Who operates MongoDB
Internal MongoDB (Percona) Default for self-managed and on-premises deployments. SDS deploys MongoDB into your cluster using the Percona Operator. You
External / hosted MongoDB Recommended for production. SDS connects to an externally managed deployment such as MongoDB Atlas. The managed service provider
Bitnami MongoDB (legacy) Older internal deployments before the move to Percona. Being phased out. You

The bundled internal database is Percona Server for MongoDB 7.0, deployed and managed by the Percona Operator for MongoDB as a PerconaServerMongoDB custom resource.

By default the internal deployment uses:

  • A single-member replica set (rs0, size 1). For production, increase the replica-set size to at least 3 for high availability.
  • A 10 GiB persistent volume for data.
  • Resource requests of 500m CPU / 1 GiB memory and limits of 2000m CPU / 4 GiB memory.

Recommendation For production, Citrix recommends a managed MongoDB service such as MongoDB Atlas, or an internal Percona replica set with at least three members. A single-member replica set has no redundancy and is suitable only for proof-of-concept (PoC) deployments.

Sizing estimation

Because the database holds metadata and not workspace contents, it stays small relative to your workspace storage. The largest growing category is audit and event data, which SDS persists in the same database. This data does not grow without bound: SDS applies a MongoDB TTL index so audit events and website activity logs automatically expire after 360 days. As a result, the database tends toward a steady state of roughly one year of audit and event data plus your (relatively static) configuration.

The following estimate is for an environment of 100 developers using 100 workspaces. Treat these as planning figures: use them to size your initial deployment, but verify actual usage during your PoC and in production, because some environments have a higher footprint.

Data category Approximate footprint Notes
Organizations, projects, settings < 50 MB Effectively fixed; scales with project count, not workspace count.
Users, groups, roles < 50 MB Scales with user count.
Workspace and template metadata < 100 MB Scales with workspace and template-version count.
Credentials and API keys < 50 MB Lower if HashiCorp Vault is used for secrets.
Audit, event, usage, and reporting records 1–5 GB (steady state) Largest category, but bounded: events and activity logs auto-expire after 360 days via a TTL index. Depends on activity level.
Indexes and overhead 25–50% of data size MongoDB indexes plus working-set overhead.

Working estimate: core configuration and metadata for 100 developers and 100 workspaces is on the order of a few hundred MB. With a year of audit and event data plus indexes, plan for 2–6 GB of actual data.

Provisioning guidance:

  • Storage: Provision at least 20 GiB for the data volume to leave headroom for growth, the replication oplog, indexes, and temporary space used during compaction and restore. The 10 GiB default is sufficient only for small or short-lived PoC environments.
  • Memory: Size MongoDB memory so the working set (frequently accessed documents plus indexes) fits in the WiredTiger cache. For this scale, the default 4 GiB memory limit is a reasonable starting point; monitor cache pressure and increase if needed.
  • Growth control: Audit events and activity logs auto-expire after 360 days, so in-database audit data reaches a steady state after about a year. This retention period is fixed and not configurable. For longer-term retention, forward events to your SIEM (the in-database copy still expires at 360 days).

Note These are planning figures for a typical workload of this size. Every environment is different, and some have a higher footprint. Use these values for initial sizing, then monitor actual database size and growth during your PoC and in production, and adjust provisioning accordingly.

Back up the database

Always back up the 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)

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).

SDS ships PBM as part of the internal Percona deployment, so backups are fully available — you just have to turn them on. In the default SDS configuration, backups are disabled (backup.enabled: false in the PerconaServerMongoDB custom resource, with the PBM image already present). Enabling PBM is a supported operation: you configure a backup storage target and set backup.enabled: true on the PerconaServerMongoDB resource. This is done at the Percona custom-resource level rather than through a dedicated SDS Helm value, and exposing these settings as Helm values is not planned — editing the custom resource is the supported method. A helm upgrade does not revert these custom-resource backup edits.

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 SDS Helm release name and <namespace> with your SDS namespace. Run kubectl get psmdb -n <namespace> to confirm your cluster name — for SDS 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 on the Percona custom resource. Edit the SDS PerconaServerMongoDB resource and set spec.backup.enabled: true and a storage entry that references the Secret:

kubectl edit psmdb <release>-psmdb-db -n <namespace>
<!--NeedCopy-->
spec:
  backup:
    enabled: true                      # was false in the default SDS deployment
    image: "percona/percona-backup-mongodb:2.8.1"
    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-->

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 gcp storage type instead of s3 — see the Percona storage guide.

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 on the same spec.backup section:

spec:
  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
        keep: 7                        # retain the 7 most recent scheduled backups
<!--NeedCopy-->

Apply the change with another kubectl edit psmdb (or kubectl apply) 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 The SDS chart does not expose these backup settings as Helm values, and exposing them is not planned. You configure PBM directly on the PerconaServerMongoDB custom resource as shown above. A helm upgrade does not revert these custom-resource backup edits, so your PBM configuration persists across SDS upgrades.

Secondary: logical snapshot with mongodump

mongodump / mongorestore are the official MongoDB database tools, and SDS 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 SDS 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).

SDS 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 SDS 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.

Restore the database

The right procedure depends on your hosting model. In all cases, plan for a maintenance window: restoring requires the platform to be quiesced so services do not write to the database mid-restore.

Step 1: Quiesce the platform

Scale the SDS services down so nothing writes to the database during the restore. The MongoDB deployment itself stays running.

# Stop the SDS application services (leave MongoDB running)
kubectl scale deployment \
  <release>-central-service <release>-workspace-api <release>-coordinator \
  <release>-frontend <release>-proxy \
  --replicas=0 -n <namespace>
<!--NeedCopy-->

Note These are the five service Deployments on a primary SDS platform. An external region deployment runs only <release>-workspace-api and <release>-proxy. Confirm what is present with kubectl get deploy -n <namespace> before scaling.

Step 2: Restore the data

Internal Percona MongoDB — from a PBM backup

Use the Percona Operator restore workflow: create a PerconaServerMongoDBRestore resource that references the backup by name (or a point in time) and wait for the operator to complete the restore. Save as sds-restore.yaml:

apiVersion: psmdb.percona.com/v1
kind: PerconaServerMongoDBRestore
metadata:
  name: sds-restore-2026-07-02
  namespace: <namespace>
spec:
  clusterName: <release>-psmdb-db
  backupName: sds-backup-2026-07-02        # the PerconaServerMongoDBBackup to restore
<!--NeedCopy-->
kubectl apply -f sds-restore.yaml
kubectl get psmdb-restore -n <namespace>   # wait for STATUS: ready
<!--NeedCopy-->

For point-in-time restores and full options, see the Percona restore documentation: https://docs.percona.com/percona-operator-for-mongodb/backups-restore.html

Internal Percona MongoDB — from a mongodump archive

Target the primary replica-set member:

# Identify the current primary
kubectl get psmdb
kubectl exec -it <pod>-rs0-0 -- mongosh \
  --authenticationDatabase admin --username <admin-user> --password <admin-password>

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

# Restore the strong-network database into the quiesced platform
kubectl exec -it <primary-pod> -- mongorestore \
  --nsInclude='strong-network.*' \
  --username <admin-user> --password <admin-password> \
  --authenticationDatabase admin \
  --gzip --archive=/tmp/strong-network-backup.gz
<!--NeedCopy-->

If you are restoring into a freshly provisioned database (for example, after moving from a single MongoDB pod to a Percona replica set), you may also need to recreate the application database user so SDS can connect:

kubectl exec -it <primary-pod> -- mongosh \
  --authenticationDatabase admin --username <admin-user> --password <admin-password> \
  --eval "db.createUser({user: '<app-user>', pwd: '<app-password>', roles: [{ db: 'strong-network', role: 'readWrite' }], mechanisms: ['SCRAM-SHA-1']});" \
  strong-network
<!--NeedCopy-->

Hosted MongoDB — restore with the provider tooling

Restore the snapshot or point in time using the provider’s console or CLI, then note the connection endpoint of the restored deployment (it is often a new host):

Step 3: Point SDS at the restored database

SDS reads its MongoDB connection settings from Helm values, which the chart renders into MONGO_DB_HOST, MONGO_DB_PORT, MONGO_DB_NAME, MONGO_DB_USER, and MONGO_DB_PASSWORD environment variables on the service pods. You change the target database by updating those values and running helm upgrade.

If you restored to a hosted service or a new endpoint (external MongoDB):

  1. In your Helm values file, make sure SDS is in external-MongoDB mode and update the connection details:

    mongodbAuth:
      source: "external"
    
    platform:
      deployPerconaMongoDB: false
      deployBitnamiMongoDB: false
      externalMongodb:
        hostName: "<restored-cluster-host>"     # new endpoint from the restore
        port: "27017"
        protocol: "mongodb+srv"                 # or "mongodb"
        additionalParameters: "retryWrites=true&w=majority"
        authMechanism: "SCRAM"                  # or "MONGODB-X509"
        auth:
          database: "strong-network"
          username: "<db-user>"
          password: "<db-password>"
    <!--NeedCopy-->
    

    For certificate-based (X.509) authentication, set the certificate fields instead of username/password. See Configure external MongoDB with X.509 authentication.

  2. Apply the change:

    helm upgrade <release> <chart> -n <namespace> -f <your-values.yaml>
    <!--NeedCopy-->
    

If you restored the internal Percona database in place:

The service endpoint is unchanged (<release>-psmdb-db-rs0.<namespace>.svc.cluster.local), so you usually do not need to change connection values. If credentials changed, update the <release>-psmdb-secrets Secret accordingly.

Step 4: Bring the platform back up and validate

# Scale the services back up (use your normal replica counts)
kubectl scale deployment \
  <release>-central-service <release>-workspace-api <release>-coordinator \
  <release>-frontend <release>-proxy \
  --replicas=1 -n <namespace>

# Or force a fresh rollout so pods pick up new connection settings
kubectl rollout restart deployment -n <namespace>
<!--NeedCopy-->

Then validate the platform:

  1. Confirm services start and connect to the database (check pod logs for MongoDB connection errors).
  2. Sign in and confirm organizations, projects, users, and workspaces are present.
  3. Confirm existing workspaces can be reattached.
  4. If you use HashiCorp Vault, confirm secrets resolve correctly.

Important A backup you have never restored is not a backup. Test your full restore procedure regularly in a non-production environment so you can rely on it during an incident.

Best practices

  • Run MongoDB with redundancy in production — a 3-member Percona replica set or a managed service — never a single member.
  • Enable continuous / point-in-time backups, not only periodic snapshots.
  • Store backups off-cluster and in a separate failure domain.
  • Encrypt backups at rest and in transit, and restrict access to backup storage.
  • Back up HashiCorp Vault alongside the database when Vault stores your secrets.
  • Always back up before upgrades, migrations, and major configuration changes.
  • Monitor database size. In-database audit data auto-expires after 360 days; forward events to your SIEM if you need retention beyond that window.
  • Test restores on a schedule and document the runbook.