9.9 KiB
Legal Document and Customer Data Storage Policy
Owner: Germaine Brown, IT Pro Partner
Status: Draft for review and approval
Effective date: Pending approval
Supersedes: none (first formal storage policy)
Source of truth: /root/itpp-backup-storage-recommendation.md (2026-08-15)
1. Purpose and scope
This policy defines how IT Pro Partner stores, retains, protects, and disposes of long-term legal documents and customer data in Wasabi S3 object storage. It turns the SME storage recommendation into binding, actionable rules.
Scope covers all data under IT Pro Partner control across current and future legal entities (ITPP parent, TransitPin, Model Ortho) and applies to every bucket, prefix, IAM policy, and retention rule created after approval.
Out of scope: application databases in active production, the existing legacy backup layer (hermes-vps-backups, itpropartner-*, mikrotik-ccr-backups), and any on-premises file shares. Those keep operating until migrated per the action checklist.
2. Data classification
Every object stored under this policy is assigned exactly one class. The class determines bucket, retention, immutability, and encryption.
| Class | Examples | Bucket | Immutability | Encryption |
|---|---|---|---|---|
| Legal / signed documents | DocuSeal NDAs, MSAs, quotes, SOWs, completion certificates, embedded audit trail | *-legal |
Compliance, locked ON | AES-256 + client-side |
| Customer / tenant data | TransitPin tenant SQLite DBs, routes, drivers, children, registrations | *-ops (tenant prefix) |
Object Lock governance on monthlies only | AES-256, SSE-C for EU PII |
| Operational / IP | Hudu dumps, scripts, architecture docs, configs, Caddyfile, env | *-ops |
Object Lock governance on monthly/yearly | AES-256, SSE-C for configs/ and env/ |
| DR / full-server images | Hetzner standby sync, full tarballs | *-ops/dr/ |
Object Lock governance on latest full only | AES-256 |
3. Storage bucket organization
Primary split is bucket-per-legal-entity, not per-app and never per-tenant. Within each entity, two buckets are required: one operational (-ops) and one legal (-legal), because Wasabi Compliance mode and Object Lock are mutually exclusive per bucket. Legal records need bucket-wide WORM; operational backups need lifecycle-expirable objects. One bucket cannot serve both.
| Bucket | Entity | Purpose | Immutability | Region |
|---|---|---|---|---|
itpp-ops |
ITPP parent | Internal IP, Hudu dumps, scripts, configs, DR, server backups | Object Lock governance on monthly only | us-east-1 |
itpp-legal |
ITPP parent | DocuSeal signed contracts + audit trail | Compliance, locked ON | us-east-1 |
transitpin-ops |
TransitPin | Tenant DB + app data, per-tenant prefix | Object Lock governance on monthly only | eu-central-1 |
transitpin-legal |
TransitPin | Client MSAs/SOWs, completion certificates | Compliance, locked ON | us-east-1 |
modelortho-ops |
Model Ortho | Consulting records, client data | Object Lock governance | eu-central-1 if EU clients |
modelortho-legal |
Model Ortho | Signed engagement letters | Compliance, locked ON | us-east-1 |
Prefix rules:
- Level 1 = data class or app:
app/<name>/,legal/,configs/,ip/. - Level 2 = tenant (multi-tenant apps only):
app/transitpin/tenants/<tenant-id>/. - Level 3 = retention tier:
daily/,weekly/,monthly/,archive/.
Migration note: bucket names are immutable on Wasabi. Do not rename. Copy to the new entity bucket, then delete the source. Migrate high-value prefixes (legal, tenant data) first.
4. Retention schedule
Retention follows a GFS (grandfather-father-son) cadence.
| Record type | Retention window | Notes |
|---|---|---|
| Legal contracts (NDA, MSA, Quote, SOW) | Duration of contract + 7 years | Computed per contract end date |
| Key / founding contracts | Permanent | Never expire or delete |
| Completion certificates and audit trail | Life of record | 50+ years for insurance-class; use PDF/A |
| IRS financial and tax records | 7 years | Payroll and tax exports go to itpp-ops |
| Daily operational snapshots | 14 days | Applies to daily/ prefixes |
| Weekly operational snapshots | 8 weeks | Applies to weekly/ prefixes |
| Monthly operational snapshots | 13 months | Applies to monthly/ prefixes |
| Yearly configs / IP snapshots | 7 years | Applies to configs/ and ip/ |
| DR full-server images | Last 3 fulls + 90-day window | itpp-ops/dr/ |
5. Immutability rules
| Rule | Requirement |
|---|---|
-legal buckets |
Wasabi Compliance mode, locked ON. Bucket-wide WORM on every object. |
-ops buckets |
Object Lock in governance mode on monthly (and yearly) snapshots only. |
-ops daily snapshots |
No immutability. |
-ops bucket itself |
Never apply Compliance lock. You keep paying for undeletable objects. |
| Object Lock enablement | Must be enabled at bucket creation. Cannot be added to an existing bucket. |
| Compliance lock unlock | Only Wasabi support can unlock once locked ON. Treat as irreversible. |
Rationale: governance mode on ops blocks ransomware and accidental deletion while still allowing deliberate correction. Compliance lock on legal is the WORM guarantee a contract dispute needs.
6. Encryption
| Item | Rule |
|---|---|
| Encryption at rest | Wasabi AES-256 automatic and free on every object. No action required. |
| EU customer PII | Add SSE-C or client-side encryption before upload. |
| Legal records | Add client-side encryption (belt and suspenders over default AES-256). |
configs/ and env/ prefixes |
Add SSE-C (contains secrets). |
| SSE-KMS | Not available on Wasabi. Do not attempt. Use SSE-C or client-side encryption. |
7. GDPR and EU data residency
| Rule | Requirement |
|---|---|
| EU customer PII storage | Must go to the eu-central-1 bucket (s3.eu-central-1.wasabisys.com). |
| TransitPin child route data | Special category (Art. 9). Store in eu-central-1 only. Never in US region. |
| US storage of EU personal data | Requires SCCs plus a Transfer Impact Assessment before transfer. |
| Legal-bucket region | EU legal documents follow the contract entity's region, not the PII rule. |
No GDPR residency mandate exists, but transfers to the US are tightly regulated. Default is to keep EU PII in the EU region and avoid the transfer burden.
8. Access control
| Rule | Requirement |
|---|---|
| IAM policy scope | One IAM user and policy per legal entity. |
| Policy structure | Two statement blocks: bucket-level and object-level. |
| Cross-entity access | Denied by default. No shared credentials across entities. |
| Divestiture | Hand over the entity's bucket plus its IAM user credentials only. |
| Backup controller | Only the backup controller writes archive/legal tiers, never application servers. |
9. Backup vs archive separation
| Tier | Purpose | RPO | Retention | Immutability |
|---|---|---|---|---|
| Operational backup | Fast restore, short retention | 15 min live sync | 14 days daily | None, or governance on monthly rollup |
| Long-term archive | Cold, ransomware-safe copy | Monthly rollup | 13 months + yearly 7 years | Object Lock governance/compliance |
| Legal hold | Contract evidence | On signature | Contract life + 7 years | Compliance, locked ON |
Archive and legal tiers are never written directly by application servers. Only the backup controller copies into them.
10. Disposal and deletion
| Rule | Requirement |
|---|---|
| Legal records | Deletion is a deliberate, authorized event after retention lapses. Never lifecycle auto-expire. |
| Operational daily/weekly | Lifecycle rules may expire objects past their window. |
| Compliance-locked objects | Cannot be deleted until retention lapses. Plan storage cost accordingly. |
| Deletion authorization | Owner (Germaine Brown) approval required before deleting any legal record. |
| Deletion record | Log the deletion event (object key, date, reason, approver). |
11. Roles and responsibilities
| Role | Responsibilities |
|---|---|
| Owner (Germaine Brown) | Approves policy, approves legal-record deletions, approves new entities and buckets. |
| Backup controller / admin | Creates buckets, enables versioning and Object Lock at creation, runs archive and lifecycle jobs. |
| Application developers | Never write directly to archive or legal tiers. Export SQLite via sqlite3 .backup, never raw WAL sync. |
| DPO / compliance (if retained) | Maintains SCCs and TIAs for US storage of EU data, reviews residency annually. |
| Auditor | Annual review of bucket, IAM, and retention configuration against this policy. |
12. Action checklist
Complete in order. This is the immediate work to operationalize the policy.
- Create the six buckets with versioning enabled, using the exact names and regions in section 3.
- Enable Object Lock at creation on every
-opsbucket; enable and lock Compliance mode on every-legalbucket. - Create one IAM user per legal entity with a two-statement policy scoped to its two buckets.
- Create the
transitpin-opsbucket in eu-central-1 and route all TransitPin EU tenant PII there. - Sign SCCs and complete a Transfer Impact Assessment for any remaining US-region storage of EU personal data.
- Point the DocuSeal signed-document pipeline at
itpp-legal/contracts/as the first consumer of the legal bucket. - Embed the DocuSeal audit trail inside the signed PDF before upload, and store PDFs as PDF/A.
- Add
archive-monthly.shto copy each app's latest monthly snapshot to the archive prefix with Object Lock. - Add a lifecycle rule to expire
daily/objects older than 14 days in the-opsbuckets. - Export payroll and tax records to
itpp-opswith a 7-year monthly archive. - Replicate each
-legalbucket to a second Wasabi region via Object Replication. - Migrate existing high-value prefixes (legal, tenant data) from the legacy buckets first; leave the rest until later.
- Schedule an annual review of buckets, IAM, and retention against this policy.