Get the App
Secure Drop
Anonymous · Encrypted · No login required
Your message is sealed and anonymous. We cannot identify you. No account or login is needed.
Your message
Max 3 files, 10 MB each
Secure Channel
Anonymous · Bidirectional · Encrypted
Start an anonymous conversation. You'll receive a thread code to check for replies later.
Your message
Max 3 files, 10 MB each
Thread Code
Enter your thread code above to check for replies.
🔍 Technical Transparency

What We See.
What We Don't.

This is not a marketing page. This is a technical specification of exactly what data City of Hats collects, what our servers can and cannot access, and where our encryption boundaries are.

Last updated: April 2026

We believe security should be proven, not claimed.

City of Hats is a young platform. We launched on app stores in March 2026. We are not yet open-source. We have not yet completed an independent audit. We are transparent about that, and we are actively working to close those gaps. In the meantime, here is a detailed account of what our system actually does.
Our commitment: We will publish the full report of our first independent cryptographic audit on this page. No redactions.

What We Protect Against — and What We Don't

No system is invulnerable. Stating what we defend against — and where our boundaries are — is more credible than claiming absolute security.

Designed to Protect Against

  • ✅ Passive network surveillance
  • ✅ Server-side data access (we cannot read E2E messages)
  • ✅ Identity correlation through phone numbers or email
  • ✅ Future quantum attacks (hybrid PQ key exchange)
  • ✅ Key compromise exposing past messages (forward secrecy)
  • ✅ Message-length analysis (metadata padding)

Not Yet Formally Evaluated Against

  • ⚠ Nation-state adversaries
  • ⚠ Compromised user devices (OS-level attacks)
  • ⚠ Advanced targeted attacks
  • ⚠ Large-scale traffic analysis (timing, frequency patterns)
Honest advice: Users with high-risk threat models should combine multiple secure tools and practices. No single app is a complete security solution.

Encryption Architecture

All hat-to-hat messages, calls, and file transfers use client-side end-to-end encryption. The server never holds decryption keys for user conversations.
🔄

Double Ratchet Protocol

Same protocol family as Signal. Every message uses a unique key. Compromise of one key does not expose past or future messages (forward secrecy + future secrecy).

🌍

Post-Quantum Hybrid

Key exchange uses X25519 + ML-KEM-768 (Kyber). Even if a quantum computer breaks classical key exchange in the future, messages remain protected.

🔐

AES-256-GCM

All message payloads, file content, and call signaling are encrypted with AES-256-GCM authenticated encryption. Headers are also encrypted to prevent metadata leakage.

👥

Group Sender Keys

Group messages use a sender key protocol with HMAC chain ratchet and ECDSA signatures. Each sender maintains their own key chain distributed over encrypted 1:1 channels.

Protocol Stack
Key Exchange  →  X25519 + ML-KEM-768 (hybrid post-quantum)
Ratchet  →  Double Ratchet (Signal protocol family)
Symmetric Cipher  →  AES-256-GCM
Key Derivation  →  HKDF-SHA-256
Message Auth  →  HMAC-SHA-256
Signatures  →  ECDSA P-256 (groups)
Passphrase KDF  →  PBKDF2
Runtime  →  Web Crypto API (browser-native)
PQ Library  →  @noble/post-quantum (ML-KEM-768)
Verify our claims. The full cryptographic source code, protocol specification, and architecture documentation are published under MIT license:
github.com/City-of-Hats/coh-crypto-spec →

What Our Servers Can and Cannot See

This table documents exactly what data exists on our servers. We distinguish between what is encrypted (opaque to us) and what is visible.
Data Type Server Access Details
Message Content ✕ Cannot See All hat-to-hat messages are end-to-end encrypted client-side. Server stores opaque ciphertext only.
File Attachments ✕ Cannot See Files are encrypted client-side before upload. Server stores encrypted blobs.
Voice & Video Calls ✕ Cannot See Calls use peer-to-peer WebRTC with encrypted signaling. Server facilitates connection setup only.
Dead Drops / EchoDrops ✕ Cannot See Content encrypted client-side. Decryption key is in the URL fragment (never sent to server) or derived from a passphrase.
GhostFrame Payloads ✕ Cannot See Steganographic content embedded and encrypted client-side before upload.
Private Keys ✕ Cannot See ECDH and post-quantum private keys are generated and stored on-device only. Never transmitted to server.
Hat Codes ✓ Visible Hat identifiers are stored to route messages. They are pseudonymous and not linked to real identity.
Channel Pair IDs ✓ Visible A record that Hat A and Hat B have a channel. Required for message routing.
Timestamps ✓ Visible Message send/receive timestamps. Required for ordering and expiration logic.
Public Keys ✓ Visible ECDH and ML-KEM public keys are published to enable key exchange. This is by design — public keys are meant to be public.
Push Notification Tokens ⚠ Metadata Only Device push tokens are stored to deliver notifications. Notification content uses generic text, not message content.
Honest disclosure: Like all messaging platforms (including Signal), we must store some routing metadata to deliver messages. Hat codes are pseudonymous — no phone number, email, or identity is required. But we do know that Hat A sent a message to Hat B at a given time.

Two Encryption Paths — Explained Honestly

Not all content in City of Hats uses the same encryption path. We are transparent about when the server can and cannot access content.

Client-Side E2E (Default)

Used for all hat-to-hat messages, calls, dead drops, GhostFrames, and EchoDrops.

  • ✅ Encrypted on your device before sending
  • ✅ Decrypted only on the recipient's device
  • ✅ Server stores opaque ciphertext
  • ✅ We cannot decrypt even if compelled

Server-Side Encryption (Limited)

Used only for system-generated content: platform announcements and the CHECK intelligence bot.

  • ⚠ Server generates and encrypts this content
  • ⚠ Server holds encryption keys for these paths
  • ℹ This applies only to bot/system messages
  • ✅ User-to-user chat is never on this path
Why two modes? The CHECK intelligence bot needs to generate security reports server-side (it queries external databases). Platform announcements are broadcast to all users. These are not private conversations — they are system messages. All user-to-user communication uses client-side E2E exclusively.

What We Log

We believe in disclosing exactly what is logged, rather than making broad "no logs" claims.
Category What Is Logged Retention
IP Addresses (App) Rate limiting uses a one-way SHA-256 hash of IP addresses. The raw IP is not stored in the database. Standard web server access logs may temporarily contain IPs. Hashed: persistent. Access logs: rotated regularly.
IP Addresses (Website) The marketing website (cityofhats.com) collects visitor analytics including IP and approximate geolocation. This is separate from the messaging application. Not linked to messaging identity.
Message Content Not logged. Not accessible. E2E ciphertext is stored for delivery, then subject to user-configured expiration. User-controlled (burn timers, auto-expiry).
Error / Crash Logs Server-side error logs for debugging. These contain error types and stack traces, not message content. Rotated regularly.
Rate Limit Events Recorded with hashed identifiers to prevent abuse. No message content. Rolling window.
Account Data If you sign in with Auth0 (Google/Apple), your authentication provider shares an email. Anonymous (hat-only) accounts have no linked email. Until account deletion.

Where Your Keys Live

Private keys never leave your device. Here is exactly how key material is handled.
Key Type Storage Location Server Access
ECDH Private Key Device only (browser localStorage) Never transmitted
ML-KEM Secret Key Device only (browser localStorage) Never transmitted
Double Ratchet State Device only. Optional encrypted backup to server (encrypted with key derived from private key). Encrypted backup only
Group Sender Keys Device only (browser localStorage) Never transmitted
ECDH Public Key Published to server for key exchange Visible (by design)
ML-KEM Public Key Published to server for key exchange Visible (by design)
Known limitation: Because this is a web/PWA application, private keys are stored in browser localStorage. This is standard for web-based encrypted messengers, but it means device security (screen lock, full-disk encryption) is critical. The optional PIN feature wraps stored keys with PBKDF2-derived encryption for additional protection.

Law Enforcement and Legal Requests

City of Hats Inc. is incorporated in Ontario, Canada and operates under Canadian law.
  • We cannot provide message content. E2E encrypted messages are stored as ciphertext. We do not hold decryption keys. Even if compelled by law, we cannot decrypt user-to-user messages.
  • What we could provide if legally compelled: Hat codes, channel pair records, timestamps, public keys, and account email (if the user signed in with a provider). This is the same metadata that any encrypted messaging service stores.
  • Anonymous accounts have minimal data. Users who create hat-only accounts without signing in have no email, no phone number, and no identity information on our servers. The hat code is the only identifier.
  • We will publish a transparency report. We intend to publish aggregate statistics on legal requests received and data provided, consistent with applicable law.
  • Warrant canary: City of Hats maintains a warrant canary. If it is ever removed, that indicates we have received a secret legal order.

What We Are Doing Next

We are building toward full verifiable trust. Here is our public roadmap.

Technical Transparency Page

This page. A detailed, honest specification of what our system does. Published April 2026.

📦

Open-Source Crypto Layer

We will publish the encryption protocol implementation (Double Ratchet, post-quantum hybrid, group sender keys) as open source for independent verification.

🔍

Independent Security Audit

A reputable third-party firm will audit our cryptographic implementation. The full report will be published here, unredacted.

📊

Transparency Reports

Regular reports on legal requests received, data disclosed, and system uptime. Published on this page.

You Do Not Have to Trust Us

City of Hats includes built-in tools for you to verify that encryption is working as described.
  • Safety Numbers. Each channel displays a unique safety number derived from both parties' public keys. Compare out-of-band to verify no man-in-the-middle attack has occurred.
  • Key Change Alerts. If a contact's encryption keys change (new device, reinstall), you receive an alert. This prevents silent key substitution.
  • Audit Log Chain. Cryptographic audit logs use hash chains so that tampering with the log is detectable.
  • E2E Indicator. Every encrypted channel displays a lock icon with "E2E" to confirm client-side encryption is active for that conversation.
  • Open Cryptographic Specification. Our full protocol design — key exchange, Double Ratchet, post-quantum hybrid, group encryption — is published publicly. Review it yourself: github.com/City-of-Hats/coh-crypto-spec

Questions or Concerns?

If you are a security researcher, journalist, or have questions about our privacy practices, we welcome the conversation.

admin@cityofhats.com

City of Hats Inc. · Toronto, Canada · Incorporated in Ontario