Backup & restore

The two-sentence summary: back up the monitoring database, and — if you set your own Encryption:Key — back up that key with it. The database holds everything the product knows; the encryption key is the only artifact that cannot be recreated, because without it the encrypted columns in that database can never be read again.

What to back up

What Why Default location
Monitoring database All configuration, server inventory, alert rules, history, audit log, encrypted secrets Wherever your monitoring SQL Server lives
Encryption:Key, if you set one The AES-256 key that decrypts connection strings and notification secrets. Lose it and those columns are unrecoverable appsettings.json, an environment variable, or your secret store — wherever you put it
License file RSA-signed license envelope Path from appsettings.json:Licensing:LicenseFilePath (default license.lic next to the binary)
appsettings.json + any environment-specific overlay Connection string and bootstrap config Next to the binary, or /app in the container
HTTPS certificate Your CA-issued certificate, if you installed one SecuritySettings:CertificatePath, or the certificate folder
DataProtection keys folder Convenience only — see below Windows: %LOCALAPPDATA%\SqlServerHealthMonitor\DataProtection-Keys
Linux: ~/.local/share/SqlServerHealthMonitor/DataProtection-Keys

Skip bin/, obj/ and wwwroot/lib/ — the installer reproduces them.

Which key actually matters

Two different key systems are in play, and only one of them is critical.

The encryption key (Encryption:Key) is the critical one. Connection strings to monitored servers and notification secrets (Microsoft 365 credentials, PagerDuty routing key, Teams webhook) are stored under an enc:v2: envelope: AES-256-GCM with a fixed key. That key comes from Encryption:Key if you configured one, otherwise from a default built into the application. Using the built-in default means there is nothing extra to back up — but it also means anyone holding a copy of the binary can decrypt a stolen database, so the encryption protects a leaked database-only backup and nothing more. If that is not good enough for you, set your own 32-byte base64 key — and from that moment on, treat it exactly like a database backup. There is no recovery path if it is lost.

The DataProtection keys folder is no longer critical. The framework still uses it for authentication cookies, antiforgery tokens, the self-signed HTTPS certificate, and for reading any leftover enc:v1: payloads from older versions. Losing it logs everyone out and regenerates the self-signed certificate — annoying, not fatal. Your encrypted columns survive, because they are enc:v2: under the fixed key. Older documentation (and older versions of this page) described this folder as the artifact that must never be lost; that has not been true since the move to enc:v2:.

On startup the application re-encrypts any row that is still enc:v1: or bare plaintext onto the current envelope. A row it cannot decrypt is left untouched and logged, never overwritten — so a missing legacy key costs you that one value, not the column.

Backup cadence

  • Database — the same cadence as your other production databases, typically nightly FULL plus hourly LOG.
  • Encryption key, license, appsettings.json — once per change. They are tiny, and they change only when you change them.
  • DataProtection keys folder — optional. Including it in a weekly pass saves your users a forced re-login after a host rebuild.

Restore procedures

After losing the monitoring database

  1. Restore the database to the same or a different SQL Server.
  2. Update ConnectionStrings:DefaultConnection if the server or database name changed.
  3. Make sure the same Encryption:Key is configured as before — or none, if you were using the built-in default.
  4. Restart. Encrypted columns decrypt immediately.

After losing the DataProtection keys folder (database intact)

  1. Restart. New keys are generated.
  2. Everyone is signed out and has to log in again.
  3. If you were using the self-signed certificate, a new one is generated — clients that pinned or manually trusted the old one need to trust the new one.
  4. Monitoring, connection strings and notification secrets are unaffected.

After losing your own Encryption:Key (database intact)

This is the worst case, and it only applies if you configured a key of your own.

  1. The application starts, but every value encrypted under the lost key fails to decrypt. Connection strings come back empty, so every monitored server shows as unreachable; notification channels fail.
  2. The startup pass logs each row it could not decrypt and leaves the ciphertext in place. Nothing is silently destroyed — but nothing can be read, either.
  3. Recovery is manual re-entry:
    • /Servers → edit each server → paste the connection string again → Save.
    • /Settings/Notifications → re-enter each channel's secret → Save.
  4. Set a new Encryption:Key (or drop the setting to fall back to the built-in default) before re-entering anything, so the new values are written under a key you still have.

There is no shortcut. That is why the key belongs in your backup plan.

After losing everything

  1. Fresh install per deployment.
  2. Restore the monitoring database.
  3. Restore appsettings.json including Encryption:Key, or follow the manual re-entry above if the key is gone.

Verifying your backup covers the key

If Encryption:Key is set in appsettings.json, confirm the file itself is in the backup set — not just the database:

Select-String -Path "C:\Apps\SqlServerHealthMonitor\appsettings.json" -Pattern '"Key"'

If the key comes from an environment variable or a secret store instead, confirm that store is backed up and that you can actually read the value back. A key you cannot retrieve is a key you have lost.

Disaster-recovery rehearsal

Once a year, or before any major upgrade:

  1. Restore the monitoring database and appsettings.json to a staging host.
  2. Point the staging instance at a non-production network so it cannot page anyone for real.
  3. Confirm:
    • the dashboard loads;
    • the server list connects — which proves the connection strings decrypted;
    • the test buttons under /Settings/Notifications succeed — which proves the channel secrets decrypted.
  4. Tear down staging.

If the connection test fails on a restored copy while it works in production, your backup is missing the encryption key. Fix that before you need it.