OpenWhistle Information Security Policy Template
Version: 1.0.0 Classification: Template — Adapt for your organisation before use
1. Purpose and Scope
This document describes the information security policy that applies to the operation of the OpenWhistle whistleblowing platform. It applies to all personnel with access to the system, its underlying infrastructure, and the data it processes.
2. Roles and Responsibilities
| Role | Responsibilities |
|---|---|
| System Owner | Overall accountability for the platform; approves policy changes |
| Superadmin | Manages organisations and platform-level configuration |
| Admin | Manages cases, users, categories; can delete with 4-eyes approval |
| Case Manager | Processes assigned cases; no user management |
| Infrastructure Team | Hosts the platform; manages backups, patching, TLS certificates |
| Data Protection Officer | Reviews data processing; maintains GDPR compliance records |
3. Data Classification
| Class | Description | Examples |
|---|---|---|
| Restricted | Personally identifying or sensitive report content | Report text, confidential identity, messages |
| Internal | Admin-only metadata | Admin notes, audit log, case assignments |
| Public | Non-identifying, aggregate | Statistics (no case details) |
All report data is Restricted and subject to the controls in section 4.
4. Technical Security Controls
4.1 Encryption at Rest
- All report descriptions and messages are encrypted at-rest using envelope encryption (Fernet: AES-128-CBC with HMAC-SHA256; a per-report DEK wrapped with an HKDF-SHA256 MEK).
- The Master Encryption Key (MEK) is derived from
ENCRYPTION_KEY(orSECRET_KEYwhile that is unset) using HKDF-SHA256 and is never stored. It exists only in memory during request processing. - Per-report Data Encryption Keys (DEKs) are stored encrypted alongside the
report. Without
ENCRYPTION_KEY, DEKs cannot be decrypted. - Confidential whistleblower identity (name, contact) is encrypted separately with Fernet using a key derived from the same root.
4.2 Encryption in Transit
- All HTTP traffic must be served over TLS 1.2+. The Ansible role obtains and
renews a Let's Encrypt certificate; the Docker Compose stack creates a
self-signed one (
tls-init) until you mount your own. SECRET_KEYandENCRYPTION_KEYmust be passed via a secrets manager or Docker/Kubernetes secret — never in a plain-text.envfile in production.
4.3 Authentication and Access Control
- All admin accounts require TOTP multi-factor authentication (no exceptions, no bypass). TOTP enrollment is enforced at first login.
- Passwords are hashed with bcrypt (cost factor ≥ 12).
- Login attempts are rate-limited (
MAX_LOGIN_ATTEMPTS, default 10, failures lock the username forLOGIN_LOCKOUT_MINUTESafter the last one; kept in Redis). - Role-based access control (
superadmin>admin>case_manager) is enforced at the FastAPI dependency layer on every protected endpoint.
4.4 Anonymity Preservation
- No IP addresses are logged at any layer (Nginx, application, or database). This is a core design constraint — do not add IP logging middleware.
- Whistleblower sessions use a Redis key tied to a random session token. The token names one report and ends on logout, when the report is deleted, or two hours after sign-in; viewing the page does not extend it.
4.5 Data Deletion
- Hard deletion of a report requires approval by two different admins (4-eyes principle, HTTP 409 if the same admin, or an account one of them made, confirms). A superadmin can reset another account and act as it.
- Every deletion leaves one audit entry with the case number
(
report.delete_confirmed,report.auto_deleted); the report's own entries are deleted with it. - The data retention scheduler permanently deletes closed reports older than
RETENTION_DAYSdays and writes anreport.auto_deletedaudit entry.
5. Incident Response
- Detection — Monitor the structured JSON logs for authentication failures, unexpected 5xx errors, or anomalous access patterns.
- Containment — Rotate
ENCRYPTION_KEYif a breach is suspected: set the new key, move the old one toENCRYPTION_KEY_PREVIOUS, then runscripts/rotate_encryption_key.py, which re-wraps every DEK. RotateSECRET_KEYtoo: it signs sessions, so every admin signs in again. - Notification — If personal data is involved, notify the supervisory authority within 72 hours (GDPR Art. 33).
- Post-mortem — Document root cause and remediation in the audit log.
6. Backup and Recovery
- The PostgreSQL database must be backed up at least daily with point-in-time recovery (WAL archiving) enabled.
- Redis contains ephemeral session data only. Redis persistence (
appendonly yes) is optional; sessions will be invalidated on restart without it. ENCRYPTION_KEYmust be stored in a separate, offline location. Its loss makes encrypted report content irrecoverable.- Recovery Time Objective (RTO): define based on your organisation's requirements.
- Recovery Point Objective (RPO): define based on your organisation's requirements.
7. Patch Management
- Platform container images are published for every release on GHCR, Docker Hub, and Quay.io. Apply updates within [define your SLA] of a security release.
- GitHub Dependabot is enabled on the OpenWhistle repository for dependency vulnerability scanning.
- Operating system patches must be applied on the host according to your organisation's standard patch management policy.
8. Audit and Review
- The OpenWhistle audit log records all admin actions with timestamps and usernames. The log is append-only from the application layer.
- Access to the PostgreSQL database (direct or via admin tools) should be restricted and logged at the infrastructure level.
- This policy must be reviewed at least annually and after any significant change to the platform or its threat landscape.
9. Compliance References
| Regulation | Relevant Clause | How OpenWhistle Addresses It |
|---|---|---|
| GDPR Art. 5(1)(f) | Integrity and confidentiality | Encryption at rest, access control, audit log |
| GDPR Art. 5(1)(e) | Storage limitation | Data retention scheduler |
| GDPR Art. 17 | Right to erasure | 4-eyes deletion, retention scheduler |
| GDPR Art. 25 | Data protection by design | No IP logging, anonymity-first architecture |
| GDPR Art. 32 | Security of processing | Encryption at rest and in transit, MFA |
| HinSchG §8 | Confidentiality obligation | Role-based access, TOTP MFA |
| HinSchG §11 Abs. 5 | Deletion 3 years after the procedure ends | Default RETENTION_DAYS=1095 |
| HinSchG §16 | Telephone channel requirement | Admin guidance at /admin/telephone-channel |
This document is a template. Replace bracketed placeholders with your organisation's specific values before use.