"Speaking up takes courage. Staying silent shouldn't be the safer option."
A secure, self-hosted internal reporting channel — because every employee deserves protection.
OpenWhistle is a self-hosted whistleblower platform that fulfils the mandatory reporting channel requirements under the German Hinweisgeberschutzgesetz (HinSchG) and EU Directive 2019/1937. Any company with 50 or more employees and all public authorities are legally required to provide an internal reporting channel. OpenWhistle provides a fully open source solution — free of charge, zero vendor lock-in, and privacy-first by design.
🌐 Live demo: demo.openwhistle.net 📖 Documentation: openwhistle.net/docs.html
- Full anonymity — No IP addresses logged at any layer. An employee submitting from the office network leaves no trace.
- Two-factor whistleblower access — Case number + secret UUID4 PIN with brute-force protection. No accounts, no email — nothing to tie the report back to a person.
- Multi-step submission wizard — Guided 5–6 step form with back/next navigation and Redis-backed session state. Anonymous or confidential mode selectable at step 1.
- Anonymous / confidential mode — Anonymous leaves no personal data. Confidential encrypts name, contact info, and optional secure email with Fernet; only the assigned admin can decrypt.
- Multi-location / branch selection — Optional location selector shown when the operator has configured active branches or offices; full admin management UI included.
- Bidirectional communication — Required by HinSchG §17. The whistleblower can reply to admin messages using only their case number and PIN.
- HinSchG SLA tracking — 7-day acknowledgement and 3-month feedback deadlines with days remaining shown in both the admin dashboard and the whistleblower status page.
- Role-based access control —
ADMINandCASE_MANAGERroles. Case managers can process their assigned reports; only admins manage users, categories, and deletions. - Case assignment — Assign reports to any active staff member; "My Cases" dashboard filter for case managers.
- Status workflow —
received → in_review → pending_feedback → closed; only valid transitions allowed server-side. - 4-eyes deletion — Hard deletion requires two different admins (request + confirm); same-admin confirm returns HTTP 409. GDPR Art. 17 compliant.
- Immutable audit log — Every admin action recorded with timestamp and username; CSV export; required by HinSchG §12 Abs. 3.
- Internal notes — Admin-only notes on cases; never visible to the whistleblower.
- Case linking — Link related cases with bidirectional normalization constraint.
- Custom categories — DB-driven report categories; full management UI at
/admin/categories. - PDF export — Full case export including SLA compliance section (HinSchG §17).
- Dashboard statistics — SLA compliance rate, status distribution, category breakdown.
- "Signal" design system — documented, token-driven identity (
DESIGN.md); app + site, light + dark. - Mandatory MFA — TOTP (compatible with any authenticator app) required for every admin account. No exceptions, no bypass.
- Object-level authorization — Every report endpoint enforces per-record access: case managers see only their assigned reports, admins are scoped to their organisation. Role assignment enforces privilege tiers (only superadmins grant superadmin; no self-role-change; the last admin cannot be demoted away).
- Hardened HTTP security — Strict, per-response nonce-based Content-Security-Policy (no
unsafe-inline), consolidated single-source security headers (HSTS,X-Frame-Options, nosniff), and strict username validation. - OIDC / SSO support — Optional single sign-on via any OpenID Connect provider (Keycloak, Authentik, Azure AD, Google, …).
- File attachments — Whistleblowers can attach evidence files (PDF, images, Word, Excel, CSV, TXT — up to 10 MB each, 5 per report).
- Internationalisation — English, German, and French UI; language picker in the nav bar; all 388+ translation keys present in every locale.
- WCAG 2.1 AA — Skip-to-content link, ARIA labels, live regions, visible focus indicators, and keyboard-accessible language picker.
- Setup wizard — Web-based first-run wizard creates the initial admin account with TOTP setup. No manual database steps.
- IP leakage detection — The admin dashboard warns when upstream proxies forward IP headers.
- Hard deletion — Reports can be permanently deleted including all messages, attachments, and Redis session data. DSGVO-compliant.
- DSGVO compliant — All resources are self-hosted. No external CDN calls, no tracking.
- Multi-registry Docker — Published to GHCR, Docker Hub, and Quay.io on every release.
- Health-check v2 —
/healthreports database and Redis status; suitable for Kubernetes liveness and readiness probes. - Version & update check — the admin System page shows the installed version and,
when
UPDATE_CHECK_ENABLED=true, whether a newer release is available on GitHub. Opt-in and off by default; a daily background job caches the result and no instance data is sent out. - Structured JSON logging —
LOG_FORMAT=jsonproduces structured log output for aggregation pipelines;LOG_FORMAT=textfor human-readable development output. - Slack / Teams webhooks —
NOTIFY_WEBHOOK_TYPEselects Block Kit (Slack) or Adaptive Card (Teams) payload formats so no custom integration work is needed. - SLA reminders — Background scheduler automatically sends reminders when the 7-day and 3-month HinSchG deadlines approach; Redis dedup keys prevent duplicate notifications.
- S3-compatible storage — Optional
STORAGE_BACKEND=s3routes new attachments to any S3-compatible bucket (AWS, MinIO, Hetzner Object Storage) instead of PostgreSQL BLOBs. - LDAP / Active Directory login — Admin accounts can authenticate via corporate LDAP; first login auto-provisions the user; TOTP enrollment still required.
- Helm chart — Official
charts/openwhistle/Helm chart for Kubernetes deployments. - Ansible role — Official
ansible/roles/openwhistle/Ansible role for bare-metal / VM deployments with Docker CE, systemd unit, and optional Certbot TLS. - Encrypted report storage — All report descriptions and messages are encrypted at-rest using per-report envelope encryption (HKDF-SHA256 MEK + Fernet DEK); the key is never stored in the database; pre-encryption rows are transparently readable (backward compat).
- Data retention (GDPR / HinSchG) —
RETENTION_ENABLED=trueactivates automatic deletion of closed reports afterRETENTION_DAYSdays (default 1095 = 3 years); satisfies GDPR Art. 5(1)(e) and HinSchG §12 Abs. 3; each deletion recorded in the audit log. - Multi-tenancy —
MULTI_TENANCY_ENABLED=truelets a single deployment serve multiple independent organisations with isolated data, per-tenant categories, locations, and users. - Superadmin role — New
superadminrole aboveadminfor managing organisations in multi-tenant deployments; existing admin permissions are unchanged. - Telephone channel compliance guide — Admin page (
/admin/telephone-channel) provides a HinSchG §16 compliance checklist, implementation options, and the §10 recording prohibition notice for operators setting up a verbal reporting channel.
A live demo is available at demo.openwhistle.net
| Role | Username | Password | TOTP Code |
|---|---|---|---|
| Admin | demo |
demo |
000000 |
Demo case numbers and PINs are shown after logging in to the demo admin account. The demo resets automatically every hour.
git clone https://github.com/openwhistle/OpenWhistle.git
cd OpenWhistle
cp .env.example .env # Set a strong SECRET_KEY
docker compose up -d
# Open http://localhost:4009/setup to create the first admin accountAccessing from other devices on the same network? Add
SECURE_COOKIES=falseto your.env(ordocker-compose.yml) when the app is served over plain HTTP. Browsers refuse to sendSecurecookies over HTTP, causing session failures on remote devices. Always keepSECURE_COOKIES=true(the default) behind HTTPS in production.
For full installation instructions, environment variable reference, reverse proxy configuration, and administration guide, see openwhistle.net/docs.html.
Pre-built multi-arch images (linux/amd64, linux/arm64) are published to three registries:
| Registry | Image |
|---|---|
| GitHub Container Registry | ghcr.io/openwhistle/openwhistle |
| Docker Hub | kermit1337/openwhistle |
| Quay.io | quay.io/jp1337/openwhistle |
All GHCR images are signed with Cosign (keyless, Sigstore).
OpenWhistle is designed to comply with:
Disclaimer: OpenWhistle is a technical tool. Operators are responsible for ensuring their deployment meets all applicable legal requirements in their jurisdiction.
Contributions are welcome. Please open an issue before submitting a pull request.
OpenWhistle is released under the GNU General Public License v3.0.
OpenWhistle is developed in free time. If you find it useful, consider supporting the project.