# Backups and recovery

URL: /deploy/backup-and-restore

Know what each store holds and how it is protected, and read the last backup and tested restore on Hosting. After any restore, prove that the evidence, the audit trail and the findings are unchanged.



Foxborne runs on your infrastructure, so your own backup service takes the backups and runs the restores. **Hosting** shows when the last backup ran and when a restore was last tested. After a restore, three checks prove that the evidence, the audit trail and the findings are what they were.

## What each store holds [#what-each-store-holds]

| Store                  | What it holds                                                 | How it is protected                                                                  | In the example                        |
| ---------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------ | ------------------------------------- |
| Original files         | Files exactly as they arrived, hashed with SHA-256 on arrival | Written once. Foxborne cannot modify or delete an original. Encrypted with your key. | Object Lock, compliance mode, 7 years |
| PostgreSQL 16          | Events, notes, reports and the audit log                      | Storage encrypted with your key                                                      | Multi-AZ                              |
| Reports and case files | Every excerpt quoted exactly, with the SHA-256 of its file    | Encrypted with your key                                                              | Kept 10 years                         |
| Basemaps and elevation | Site elevation and imagery your team uploads                  | Encrypted with your key                                                              | Kept until replaced                   |
| Audit log              | Every import, view, edit, export and administrative change    | Append-only and hash-chained. Streamed to your SIEM over syslog with TLS.            | Never deleted                         |
| Backups                | Copies taken by your backup service                           | Encrypted with your key                                                              | AWS Backup vault, daily, kept 35 days |

Events are derived from the originals: the same file and parser version always give the same event IDs. Notes and report edits are written by people, so the database backups are what protect them.

## The example's backups [#the-examples-backups]

| Item                            | Example value                                                                                                    |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| Vault                           | AWS Backup vault `hfr-foxborne`                                                                                  |
| Encryption                      | Customer key                                                                                                     |
| Schedule and retention          | Daily, kept 35 days                                                                                              |
| **Nodes** footer on **Hosting** | **Last backup 7 h ago. Restore tested on 12 Sep 2026.**                                                          |
| Audit log                       | A **System** entry, **Backup completed**, on **Backup vault**, with the detail **Snapshot of 18.4 GB, verified** |

Backups and restores run in your backup service, the AWS Backup vault in the example. Test a restore on your own schedule, and check its result with the steps below.

<Callout type="warning" title="Backups need the key too">
  The example encrypts its backups with the same customer key as the originals. Disabling that key leaves the backups unreadable along with everything else it protects.
</Callout>

## Before you start [#before-you-start]

* You need the **Admin** role to open **Hosting**. The audit log is open to admins and auditors.
* You have a restored deployment or a restore test running on your schedule.
* You can read your SIEM's copy of the audit stream.
* You have one approved report and read access to the originals it cites.

## Confirm integrity after a restore [#confirm-integrity-after-a-restore]

<Steps>
  <Step title="Check Hosting">
    Open **Hosting**. Confirm that **Version** carries **Signature verified** and that the **Encryption key** panel names your key. Each row under **Nodes** should read **Healthy**.
  </Step>

  <Step title="Verify the audit chain">
    Open **Audit log** and select **Verify chain**. Foxborne recomputes each hash from the entry and the hash before it, so a missing or altered entry breaks the chain.

    When every entry matches, the note reads **Chain intact** with the count of entries verified and the time of the latest. The check itself is recorded, as **Verified audit chain**.
  </Step>

  <Step title="Compare with your SIEM">
    The restored audit log ends where the backup was taken. Your SIEM received the audit stream over syslog with TLS, so it also holds the entries written after that point.

    Find the newest restored entry in the SIEM's copy. Anything after it happened after the backup, and the restored log does not hold it. An export taken before the restore serves too: **Export** includes each entry's hash and the hash before it, so it can be verified offline.
  </Step>

  <Step title="Check a report against its originals">
    Pick an approved report and check its excerpts against the original files, as in [Verify a report against the originals](/investigate/verify). Each excerpt names its file and that file's SHA-256, so anyone holding the original can check each line.

    The report's footer says the same: &#x2A;*Every excerpt can be checked against its SHA-256.**
  </Step>

  <Step title="Run the rules again">
    Open a run that has findings, such as R-0931 in the example dataset, and select **Run rules again**. Rules are deterministic and each finding names its rule version and threshold, so a rerun gives the same answer.

    The message should read &#x2A;*Rules ran again. Results are identical to the previous run.** The audit log records **Ran rules again** on the run.
  </Step>
</Steps>

## Check the result [#check-the-result]

A clean restore shows all of these:

* **Chain intact** after **Verify chain**, with the entry count and the time of the latest entry.
* The newest restored entry present in your SIEM, with every later entry accounted for there.
* Every SHA-256 in the report matching the original it names.
* **Rules ran again. Results are identical to the previous run.** on each run you check.

## Troubleshoot [#troubleshoot]

**Last backup is older than your schedule.** **Hosting** shows when the last backup completed. Check the backup job in your backup service, AWS Backup in the example.

**Recent audit entries are missing.** That is expected after a restore, because they were written after the backup was taken. Your SIEM holds them.

**A SHA-256 does not match.** The excerpt cannot be verified against that file. Confirm you hashed the file from the originals store, where each original is written once and never changed, before anyone relies on the report.

## Next [#next]

* [Audit log](/security/audit-log) explains the hash chain and the export.
* [Verify a report against the originals](/investigate/verify) walks through the hash check.
* [Encryption and keys](/security/keys) covers the customer key.
* [Retention, holds and redaction](/security/retention) covers retention policy and legal holds.
* [Monitor a deployment](/deploy/operations) covers the **Hosting** signals day to day.
