Business Continuity & Disaster Recovery Plan¶
Purpose. What Soon does when something large breaks — the loss of the production database, an AWS region, the source code, or access to the accounts that run the company. Satisfies A.5.29 (information security during disruption), A.5.30 (ICT readiness for business continuity) and SOC 2 CC9.1.
Status: DRAFT. Targets in §2 are set and agreed (2026-08-13). The recovery times in §5 are design estimates until the first restore test measures them — that test is tracked in Linear S-412, and its record replaces the estimates.
1. What this plan protects¶
Soon is a workforce-management SaaS. Customers use it to know who is working when — so a long outage does not merely inconvenience them, it can stop a contact centre or a warehouse shift from being staffed. That is the reason availability is a security property here and not just an SLA number.
Scope: the production platform in AWS eu-west-1, the data it holds, and the systems Soon needs in order to run the recovery — which are not the same list, and §6 exists because people forget the second one.
2. Targets¶
Agreed 2026-08-13, and published to customers in the Availability Management Policy.
| Target | What it means in practice | |
|---|---|---|
| Uptime | 99.5% | ≈3.6 hours of unplanned downtime per month |
| RTO — recovery time objective | 8 hours | Maximum time to restore service after a major failure |
| RPO — recovery point objective | 24 hours | Maximum acceptable data loss |
The RPO is conservative and should tighten. Point-in-time recovery is enabled on the production database with 30 days of retention, so the technical recovery point is minutes, not a day. The 24-hour figure stands only until a restore test proves the shorter one. Revisit it at the first annual review.
3. What we are protecting against¶
Ranked by the combination of likelihood and how badly it would hurt.
| # | Scenario | Likelihood | Impact | Primary defence |
|---|---|---|---|---|
| D-1 | Production database lost or corrupted | Low | Critical | Multi-AZ + PITR (30 days) + isolated cross-account copy |
| D-2 | Accidental destructive change (bad migration, wrong DELETE) |
Medium | Critical | PITR to a point before the change; change management |
| D-3 | AWS availability-zone failure | Low | High | Multi-AZ failover, automatic |
| D-4 | AWS region failure (eu-west-1) | Very low | Critical | Backup copy in eu-central-1; rebuild from IaC |
| D-5 | AWS account compromise or deletion | Low | Critical | Isolated log-archive account, SCP-protected; MFA; separate backup vault |
| D-6 | GitHub organisation compromise or loss | Low | High | §6 — this is the gap |
| D-7 | Google Workspace compromise | Low | High | §6 — takes Slack and mail with it |
| D-8 | Ransomware on an endpoint | Medium | Medium | BYOD baseline; no production data at rest on laptops |
| D-9 | Key-person unavailability | Medium | Medium | §7 |
D-2 is the one most likely to actually happen. Region failures make better stories, but a mistaken migration against production is the realistic disaster for a four-person company, and it is the scenario the recovery procedure in §4 is written around.
4. Recovery procedure — production database¶
The core scenario. Run by Melvin or Thomas; Olaf handles communication.
Step 0 — declare. Anyone can declare. Post in Slack #Security, open a Linear issue
labelled security, and start a timeline. From this moment, write down what you do and
when — the timeline is both the recovery aid and the evidence.
Step 1 — establish what happened and stop it continuing. A corrupted database that is still being written to gets worse every minute. Take the application offline before restoring if the cause is still active.
Step 2 — choose the recovery point. For corruption or a bad change, use point-in-time recovery to a timestamp immediately before the event, not the last nightly snapshot — the difference is usually hours of customer data.
Step 3 — restore to a NEW instance. Never restore over the live one. Restoring alongside preserves the evidence and lets you compare.
aws rds restore-db-instance-to-point-in-time \
--source-db-instance-identifier rds-soon-soon-prod \
--target-db-instance-identifier rds-soon-soon-recovery \
--restore-time <ISO-8601 timestamp> \
--region eu-west-1
Step 4 — verify before cutting over. Row counts on the largest tables, the most recent records, and a login through the application. A restore that completes is not a restore that worked.
Step 5 — cut over by repointing the application, then confirm health.
Step 6 — communicate. Customers are told through the status page and email per the Incident Response Procedure. As a GDPR processor, if personal data was lost or exposed the Personal Data Breach Notification Procedure runs in parallel — it has its own clock.
Step 7 — keep the damaged instance until the cause is understood, then record the timings in the plan's review.
Region loss (D-4)¶
Longer and less rehearsed, and honesty is better than a pretend runbook: recovery means
restoring the backup copy held in eu-central-1 and rebuilding the platform from
soon-terraform. IaC covers the network, ECS/Fargate services, load balancers, ECR, IAM
roles and CloudWatch — so the rebuild is largely mechanical. CloudTrail and
account-level configuration are not yet codified and would be reconstructed by hand.
Expect materially longer than the 8-hour RTO. Reducing that gap is the argument for
finishing the Terraform import.
5. Recovery expectations¶
| Scenario | Expected recovery | Data loss | Basis |
|---|---|---|---|
| D-3 AZ failure | Minutes | None | Automatic Multi-AZ failover |
| D-1 / D-2 database restore | Within RTO | Minutes, via PITR | Estimate — to be measured by S-412 |
| D-4 region loss | Exceeds RTO | Up to the copy interval | Rebuild from IaC + eu-central-1 copy |
| D-6 / D-7 account loss | Hours to days | Varies | §6 |
6. The systems needed to run a recovery¶
The scenario that ends a company is rarely the database. It is losing the things you need in order to fix the database.
| System | What its loss costs | Position |
|---|---|---|
| AWS production account | Everything | MFA, separate log-archive account, SCP guardrails |
| GitHub | Source code and every deployment path | Distributed clones exist on developer machines, which is a mitigation but not a backup. An organisation-level backup is not in place |
| Google Workspace | Mail, Drive (contracts, DPAs, HR records) — and it is the identity provider for Slack, so losing it removes the incident channel at the same moment | MFA on all accounts. No independent export in place |
| Enpass | Every shared credential | Vault sync; each holder has a local copy |
| Terraform state | The ability to rebuild | Held in AWS; covered by account protections |
Out-of-band contact is a real requirement, not a formality. Slack authenticates through Google Workspace. A Workspace compromise therefore takes out the channel we would use to coordinate the response to a Workspace compromise. Every founder keeps the other three's personal phone numbers offline, and the fallback channel is SMS or phone.
Open actions from this section: an organisation-level GitHub backup, and a scheduled Google Workspace export. Both are gaps this plan names rather than hides.
7. People¶
Four founders, fully remote, no offices — so physical continuity is not a concern, but key-person risk is real.
| Role in a disruption | Primary | Deputy |
|---|---|---|
| Declare and coordinate | Olaf | Thomas |
| Database and infrastructure recovery | Melvin | Thomas |
| Application recovery | Thomas | Melvin |
| Customer communication | Olaf | Alessandro |
No single person holds sole access to anything required for recovery. Credentials are in Enpass, and AWS access is role-based rather than tied to an individual's keys.
8. Testing¶
| Test | Frequency | Owner | Evidence |
|---|---|---|---|
| Database restore test | Annual, minimum | Melvin | Timings + verification screenshots |
| DR tabletop (scenario walkthrough) | Annual | Olaf | Minutes |
| Automated backup configuration checks | Daily | soon-grc | CHK-BACKUP-01 |
A test that surfaces nothing was not really a test. Record what did not work as carefully as what did — an auditor reads a flawless first tabletop as one that was performed on paper.
9. After an event¶
Every invocation produces: the timeline, the measured recovery time against the 8-hour RTO, the actual data loss against the 24-hour RPO, what worked, what did not, and corrective actions raised under the Nonconformity & Corrective Action Procedure. This plan is updated at the same time, not "later".
Related documents¶
- Availability Management Policy — where the targets are set
- Backup Policy · Incident Response Procedure
- Personal Data Breach Notification Procedure
- Cloud & Infrastructure Security Policy — IaC coverage
- Risk Assessment Report — R-15
Change log¶
| Version | Date | Author | Comments |
|---|---|---|---|
| 0.1 | 2026-08-22 | ISMS | First version. Targets carried from the Availability Management Policy; nine disaster scenarios ranked; the database recovery runbook written around accidental destructive change as the realistic case; region loss described honestly including the un-codified CloudTrail gap; §6 names the recovery-enabling systems, the Workspace/Slack single point of failure and the two missing backups. |