Security baseline + AES at rest + eIDAS Advanced + GDPR scaffolding
- Storage tree hardened to 700 directories / 600 files; app umask set to 0077.
- Original PDFs, signed PDFs, signature and initials PNGs, ID uploads encrypted at rest with Fernet (AES-128-CBC + HMAC-SHA256). Versioned ciphertext header so future key rotation can read legacy files.
- Master key now lives at /etc/zingzee-sign/master.key (mode 600).
- Per-sender accounts: SQLite-backed senders table, bcrypt password hashes, optional TOTP MFA via pyotp. Admin CLI: scripts/create_sender.py.
- Studio session cookie SameSite tightened to Strict.
- SlowAPI rate limiter applied to /studio/login, /customer/login, /s/{token}, /s/{token}/access-code, /s/{token}/sms-check, and the new KBA + ID-upload endpoints.
- Append-only hash-chained audit log at storage/audit/events.jsonl. Daily archive copy to storage/audit_archive/.
- Upload validation: MIME magic-byte sniff (rejects non-PDF), 50 MB per-file cap, 200 MB per-envelope cap, filename sanitisation.
- eIDAS Advanced: per-envelope assurance_level field (simple, advanced_sms, advanced_kba, advanced_id) with per-mode signer flow gates. RFC 3161 timestamp helper using freeTSA.org by default; documented upgrade path to a qualified TSA.
- GDPR scaffolding: DSAR export and delete endpoints (admin-gated), public sub-processor list, internal RoPA, signable DPA template flagged for legal review.
- Public FAQ at /faq with the honest compliance matrix.