Scope: This report assesses the Arkhivio Backup Framework as a data-processor tool for file backup operations against the EU General Data Protection Regulation (GDPR). It covers technical and architectural controls only. Organisational policies, staff training, risk assessments, DPIAs, and legal contracts remain the responsibility of the operating organisation. This document does not constitute a legal compliance certification.
All S3 transfers use HTTPS via boto3 (TLS 1.2+). MongoDB connections use TLS when MONGO_OPTIONS includes the appropriate flags. config.py emits a WARNING log event at startup if TLS appears disabled on a non-local connection — the misconfiguration is surfaced before any data is processed.
S3 credentials stored in MongoDB are encrypted with Fernet AES-128-CBC + HMAC (crypto_utils.py) — the database alone cannot reach storage. Backup data encryption is delegated to the S3 bucket: SSE-KMS with a customer-managed key must be enabled on the bucket. No framework code change is required; this is a one-time bucket configuration.
aws s3api put-bucket-encryption. Select AWS Key Management Service key (SSE-KMS) and choose a customer-managed key (CMK) created in AWS KMS. No changes to this codebase.mongod.conf with security.enableEncryption: true and configure a KMIP key management server.Web dashboard enforces role-based access control (auth.py): admin — full CRUD on jobs and buckets; operator — read-only dashboards, history, monitor. Two authentication backends: local (timing-safe secrets.compare_digest) and Active Directory (ldap3 LDAP bind + memberOf group lookup). Sessions are signed with HMAC-SHA256 via itsdangerous. Startup validation (_validate_config()) raises RuntimeError before the server accepts connections if authentication is misconfigured.
CRC32 checksum computed for every file at scan time, stored in MongoDB and in the S3 object's x-amz-meta-crc32 header. audit.py provides three independent checks on demand: (1) file catalogue existence, (2) S3 metadata CRC match without downloading, (3) random file download with full CRC re-computation. All checks produce structured JSON output suitable as audit evidence.
S3-only disaster recovery path (restore_onlys3.py) requires only S3 credentials — no framework binary, no MongoDB needed. Every backed-up file is a plain object at {host}/{absolute/path}, listable and downloadable with aws s3 cp, rclone, or any S3 browser. S3 versioning, Object Lock (WORM), and cross-region replication can be independently enabled on the bucket.
Minimal data model: MongoDB stores only file metadata (path, size, mtime, CRC32) — no file content. S3 credentials masked in all API responses (_serialize_bucket() strips access_key and secret_key). Encryption key loadable from 6 secrets-manager integrations (AWS SM, Azure KV, GCP, IBM, HashiCorp Vault, OpenBao), keeping secrets entirely off disk.
The tooling for deletion exists and is tested: delete.py removes specific files from S3 and marks them deleted in MongoDB. The gap is procedural, not technical — the framework has no built-in mechanism to locate all objects belonging to a specific data subject. The operator must maintain a mapping of data-subject identity → backed-up file paths in their application layer, then invoke delete.py with those paths. No code change to the framework is required.
python delete.py --paths <file> (or deleter.py programmatically) → confirm deleted_in_s3=True in MongoDB for each record.log_event() function in logger.py can emit this record directly.Every backed-up file is a raw, unmodified object at a predictable S3 path. The files.json.gz inventory published after every run lists all files with path, size, mtime, and CRC32 in an open JSON schema. No proprietary format, no deduplication index, and no framework binary are required to read or copy the data.
Every operation emits a structured UTC-timestamped JSON log event (logger.py). CRC mismatches, S3 drift, and reconciler anomalies are detected and logged with distinct event names. The gap is that no alerting pipeline is built in — connecting the log stream to Loki, Splunk, CloudWatch, or Prometheus (all documented in ALERTING.md) and defining incident-response runbooks is an operational step. S3 Access Logs and AWS CloudTrail should also be enabled on the bucket.
LOG_FILE=/var/log/backup/backup.log in .env, then configure a log shipper (Filebeat, Fluent Bit, CloudWatch agent) to forward to your SIEM. Step-by-step guides for ELK, Loki, Splunk, and CloudWatch are in LOG_INTEGRATION.md.ALERTING.md as a starting point. Define threshold alerts on events upload_error, reconciler_mismatch, and repeated auth failures within a time window — these are the primary indicators of a potential breach.DeleteObject and GetObject API calls outside approved IAM principals.The framework itself is self-hosted Python and does not require a DPA. A DPA must be signed with each cloud provider used to store personal data: AWS (Standard Contractual Clauses / DPA for S3), Cloudflare (R2 DPA), MongoDB Atlas (Atlas DPA). All three providers offer standard DPA addenda.
Actions required before a production deployment handling personal data under GDPR.
| # | Action | How resolved | Where | Regulation |
|---|---|---|---|---|
| 1 | Enable SSE-KMS with a customer-managed key on the S3 bucket | EXT | AWS / Cloudflare console | Art. 32(1)(a) |
| 2 | Enable TLS on MongoDB connection (MONGO_OPTIONS=tls=true&tlsCAFile=…) |
OPS | .env |
Art. 32(1)(a) |
| 3 | Store BACKUP_SECRET_KEY in a secrets manager, not a flat file. Set SECRETS_PROVIDER in .env to activate one of the 6 built-in integrations. |
OPS | .env / secrets provider |
Art. 25 |
| 4 | Forward log output to an immutable log store (CloudWatch Logs, Splunk, Loki). Set LOG_FILE in .env and configure a log shipper per LOG_INTEGRATION.md. |
OPS | .env / log shipper |
Art. 33 |
| 5 | Maintain a data-subject → file-path register in your application layer. On erasure requests, pass paths to delete.py and emit a log_event("erasure_fulfilled", …) record. |
OPS | Application layer | Art. 17 |
| 6 | Connect log stream to a SIEM and define alert rules per ALERTING.md. Enable AWS CloudTrail data events and S3 Access Logs on the bucket. Write a 72-hour breach-notification runbook. |
OPS | SIEM / AWS console | Art. 33 |
| 7 | Sign DPA with AWS, Cloudflare, and/or MongoDB Atlas | EXT | Legal / provider portals | Art. 28 |
| Capability | How it supports GDPR |
|---|---|
| Plain S3 objects — no proprietary format | Art. 17 erasure is a targeted S3 delete; Art. 20 portability is a direct download. No format conversion and no vendor tool needed at any point. |
| Fernet encryption of credentials | A MongoDB breach alone cannot expose S3 data. Encryption key optionally held in 6 external secrets managers, completely off disk. |
| Minimal data in MongoDB | Only metadata (path, size, mtime, CRC32) — no file content ever stored in the catalogue. Reduces PII surface to path names only. |
| Structured JSON logs with UTC timestamps | Machine-parseable, directly ingestible by every major SIEM. Immutable when forwarded to CloudWatch or Splunk. Timestamps from datetime.now(timezone.utc). |
| Named audit events on all write operations | audit_job_created/updated/deleted and audit_bucket_created/updated/deleted record the actor, resource, and time for every privileged action — satisfies Art. 5(2) accountability principle. |
| 3-check integrity audit | Provides verifiable, on-demand evidence that personal data is intact and recoverable. JSON output is embeddable in DPIA or audit responses. |
| S3-only disaster recovery | Satisfies Art. 32(1)(c) availability and resilience requirement. No dependency on the framework or its database during a crisis. |