Skip to content

Backup and restore

A usable backup contains both operator configuration and generated instance state. Losing the dynamic state changes the SAML certificate and invalidates all browser sessions.

What to back up

DataTypical locationSensitivity
Static YAML/etc/passbeyond/<instance>.yamlSensitive when it contains passthrough tokens or internal topology
Dynamic JSON/var/lib/passbeyond/<instance>.jsonSecret: JWT key, SAML private key, certificate, cache
Local IdP metadataOperator-selected pathTrust configuration; may reveal internal endpoints
Edge proxy configurationnginx, Apache, Caddy, or platform configurationSecurity-relevant routing and TLS settings

The executable and package can be reinstalled and normally do not need file-level backup.

Consistent systemd backup

Remote metadata refresh can write the dynamic file every 30 minutes. Stop the instance for a simple consistent copy, or use an atomic filesystem/volume snapshot.

bash
sudo systemctl stop passbeyond@myapp.service
sudo install -d -m 0700 /root/passbeyond-backup/myapp
sudo cp --preserve=mode,ownership,timestamps \
  /etc/passbeyond/myapp.yaml \
  /root/passbeyond-backup/myapp/
sudo cp --preserve=mode,ownership,timestamps \
  /var/lib/passbeyond/myapp.json \
  /root/passbeyond-backup/myapp/
sudo systemctl start passbeyond@myapp.service

Include a local IdP metadata file and edge proxy configuration when used. Confirm the service returns before ending the maintenance window.

Encrypt backup storage, restrict access, record checksums separately, and test restoration. Never commit backups to Git or attach them to an issue.

Container volume backup

Use a storage-native snapshot when available. Otherwise stop the container and copy the mounted host directory or named volume with a trusted backup tool.

Preserve numeric ownership for UID/GID 65532. Do not use an archive workflow that prints file contents or environment variables to CI logs.

Validate without revealing secrets

Check that the expected dynamic keys exist without printing their values:

bash
sudo jq -e '
  .settings["instance-id"] and
  .settings["jwt-secret"] and
  .settings["saml-signing-key-private"] and
  .settings["saml-signing-key-public"]
' /var/lib/passbeyond/myapp.json >/dev/null

Also record the public certificate fingerprint before and after backup:

bash
curl --fail --silent --show-error \
  https://myapp.example.com/saml/certificate.crt \
  | openssl x509 -noout -fingerprint -sha256 -dates

Restore an instance

1. Install PassBeyond

Install the same reviewed version used when the backup was taken, or confirm the target version is compatible before restoring.

2. Stop the instance

bash
sudo systemctl stop passbeyond@myapp.service

3. Restore files

bash
sudo install -d -o passbeyond -g passbeyond -m 0750 /var/lib/passbeyond
sudo install -d -o root -g passbeyond -m 0750 /etc/passbeyond
sudo install -o root -g passbeyond -m 0640 \
  /secure-backup/myapp.yaml \
  /etc/passbeyond/myapp.yaml
sudo install -o passbeyond -g passbeyond -m 0600 \
  /secure-backup/myapp.json \
  /var/lib/passbeyond/myapp.json

Restore local IdP metadata with permissions readable by the service account.

4. Verify paths and start

Confirm configPath points to the restored JSON and domain still matches the IdP application:

bash
sudo systemctl start passbeyond@myapp.service
sudo journalctl -u passbeyond@myapp.service -n 100 --no-pager

Verify the public certificate fingerprint, metadata endpoint, login, backend headers, and logout.

Restore to another host

Preserve the public DNS name, static configuration, and dynamic state when the IdP registration and existing sessions should remain valid. Update:

  • private listener and backend addresses;
  • edge proxy trustedProxies and firewall rules;
  • internal DNS or container networks;
  • file paths and ownership.

Do not run old and new hosts concurrently against the same writable dynamic JSON. Cut over the public route only after the new host passes private checks.

Restore under a new domain

A new domain changes Entity ID, ACS/SLO URLs, redirect validation, and cookie scope. Treat it as a new Service Provider registration. Reusing the old state can also retain a certificate whose identifying URI contains the old domain.

Prefer a new instance with new dynamic state, register its metadata at the IdP, test it, and then migrate users.

Recovery when dynamic state is lost

If no valid backup exists, PassBeyond generates new JWT and SAML material at the next start. Consequences:

  • all sessions become invalid;
  • the IdP must trust the new SP certificate for signed requests;
  • encrypted assertions must target the new certificate;
  • cached IdP metadata is unavailable until refreshed.

Follow Certificate and key rotation and treat unexpected state loss as a security and availability incident.

Backup policy checklist

  • [ ] Every instance's YAML and unique dynamic JSON are included.
  • [ ] Local IdP metadata and edge proxy configuration are included when applicable.
  • [ ] Backups are encrypted and access is audited.
  • [ ] Retention and secure destruction are defined.
  • [ ] Restore tests verify fingerprint, login, headers, and logout.
  • [ ] The recovery team knows that the dynamic file must never be shared publicly.

Released under the MIT License.