Cord
Join the beta
Cord is a private messaging app built from the ground up to remove identifiers like phone numbers and email addresses.
Instead of linking you to personal information, Cord connects devices through a secure alphanumeric code known as a Cord ID.
Every message, file, or image shared through Cord is end-to-end encrypted (E2EE), ensuring that only participants in a conversation can read its contents — not Cord, not servers, and not intermediaries.
Cord is a private, pseudonymous messenger built without phone numbers or emails. Every device generates random cryptographic identifiers locally (32‑byte User IDs and UUIDv4 Device IDs), and messages are encrypted end-to-end with the Signal Protocol before they ever leave the device. Cord’s servers see encrypted blobs plus rotating routing tokens—not personal identifiers.
End-to-End Encryption
-
Protocol: libsignal_protocol_dart (X25519 + Double Ratchet) protects every message, file, and image. Sessions and identity keys live in the OS keychain/keystore.
-
Security properties: Forward secrecy, post-compromise security, and deniable authentication all inherit directly from Signal’s design.
-
Delivery: Sender encrypts locally → sealed envelope → routed over TLS 1.3 → recipient decrypts locally. Cord’s infrastructure never sees plaintext.
Metadata Protection
-
Sealed Sender: A second XChaCha20-Poly1305 layer hides the sender’s identity; servers only view the recipient’s rotating PPID plus a nonce.
-
PPIDs (Pseudonymous Routing IDs): Each device derives unique, pairwise IDs from shared keys and daily epoch salts. Servers map PPIDs to device IDs to deliver messages, but IDs rotate every 24 h and are hashed per cord.
-
Relationship visibility: The backend must know which devices belong to which cord to deliver pushes, but those cord IDs are stored as SHA‑256 hashes and PPIDs expire automatically (see retention below).
-
No contact upload: The app never reads address books or phone numbers.
Identity & Device Linking
-
No phone numbers, emails, or usernames. Devices join cords through codes or QR scans.
-
Device IDs: 128‑bit UUIDv4 plus 32‑byte device secrets, all generated with CSPRNGs and signed by the user’s Ed25519 key.
-
QR verification: Built-in “Verify Identity” shows/scrubs Signal-style safety numbers so users can confirm sessions out of band.
Data Minimization & Retention
Data--------------------------Stored------------Duration
messages_v2 sealed envelopes--Supabase----------PostgresUser-chosen expiry per conversation, capped at 30 days
(server enforces ≤30d)
PPID routing entriesSupabase--Postgres----------Up to 7 days to cover offline devices; older entries deleted automatically
Audit/diagnostic logsSupabase-Postgres----------24 h
Signal sessions & keysDevice--keychain/keystore-Until the user revokes the device
Secure Infrastructure
-
Database: Supabase Postgres with row-level security: devices read only their cords/messages; PPID lookups happen through Edge Functions (clients cannot query ppid_map directly).
-
Edge Functions: Stateless Deno scripts (enqueue, route, register-device-and-ppid, cleanup). All inbound traffic is TLS 1.3; functions rely on Supabase service-role keys kept in env vars.
-
Hosting: TLS 1.3 end-to-end; optional certificate pinning client-side.
-
Media: Files are EXIF-stripped and encrypted client-side with XChaCha20-Poly1305 before uploading to Supabase Storage under opaque names.
Client Security
-
Keys/sessions stay in flutter_secure_storage (Keychain/Keystore). SharedPreferences only holds non-sensitive caches.
-
Backups are disabled for encrypted data; Android manifest sets allowBackup="false" and fullBackupContent="false".
-
Push notifications are content-free (“New activity available”); notification logic keeps bodies generic and never exposes message snippets.
-
Local data is wiped when retention timers expire or when the user taps “Scrub data.”
Open Cryptography
Key exchange & messagingSignal Protocol (X25519, HKDF, AES-256-CBC, HMAC-SHA256)
Sealed sender envelopes
XChaCha20-Poly1305 AEAD
PPID derivationHKDF-SHA256 over device secrets + epoch salts
SignaturesEd25519 (device registration, linking)
Media encryption
XChaCha20-Poly1305 + SHA-256 hashes
All primitives come from audited libraries (libsignal_protocol_dart, cryptography, ed25519_edwards, crypto). There are no proprietary ciphers.
Transparency & Audits
-
An external assessment is planned; summaries will be published once third-party review is complete.
-
Logs: A GitHub CI workflow scans for sensitive logging, banned analytics SDKs, and contact-access code. Results are visible in the repo.
-
No analytics/tracking SDKs: The build fails if firebase_analytics, Mixpanel, Segment, etc., are added; marketing/advertising SDKs aren’t included.
Security Principles
-
Privacy by design: Zero phone/email identifiers, minimal metadata, encrypted storage everywhere.
-
User control: Per-cord retention, local scrub controls, device revocation, and QR-based session verification.
-
Open standards: Signal-compatible crypto, RFC-documented AEADs/HKDF. No proprietary algorithms.
-
No ads, no tracking: No analytics SDKs, ad networks, or behavioral profiling.
Learn More
-
Signal Protocol Technical Overview
-
HKDF (RFC 5869)
-
XChaCha20-Poly1305 (RFC 8439 / libsodium variant)
Cord Privacy Policy Last Updated: December 2025
Introduction
Cord is a private-by-design messenger. This policy explains what information we collect, how we use it, the third parties involved, and how you can exercise your rights.
Data We Collect
We collect only the technical data we need to deliver encrypted messages:
CategoryDetails
Encrypted messagesCiphertext envelopes (Signal + sealed sender). Stored server-side until they expire or are delivered. We cannot decrypt them.
Routing metadata (PPIDs)Rotating pseudonymous IDs that map to a device within a specific cord. Generated per device pair, rotated roughly every 24 hours, and stored up to 7 days to handle offline delivery.
Device information
Random device identifiers (UUIDv4 plus cryptographic public keys) that are not tied to phone numbers, emails, contacts, or hardware IDs.
Security/audit logs
Minimal event logs (e.g., device registered, push token updated) retained 24 hours to detect abuse.
Beta email (optional)If you sign up for a beta, we keep the email address you provide until the beta ends or you request deletion. You may use an anonymous email provider.
We do not collect phone numbers, email addresses (outside beta signup), names, usernames, contact lists, location data, hardware identifiers (IMEI, MAC, advertising IDs), analytics or usage tracking data, or behavioral telemetry.
All encryption keys (Signal identity keys, sessions, and media keys) are generated on the device and stored only in the device’s secure keystore/Keychain.
How We Use the Data
-
Message delivery: Temporarily store encrypted envelopes and routing tokens so recipients can retrieve them, including across multiple devices.
-
Routing: Use PPIDs and hashed cord IDs to determine which device should receive a message without exposing phone numbers or personal identifiers.
-
Security & reliability: Maintain 24‑hour audit logs and 7‑day PPID caches to troubleshoot abuse, replay attacks, or offline delivery.
-
Service operation: Device identifiers allow multi-device linking, push-token registration, and revocation.
We do not inspect plaintext message content, build social graphs, monetize or sell data, or use any analytics/advertising SDK.
Third-Party Infrastructure
-
Supabase (Postgres + Edge Functions): Hosts encrypted envelopes, routing tables, and audit logs. Supabase processes data strictly under our instructions; it cannot decrypt content.
-
Firebase Cloud Messaging (FCM): Sends push notifications that contain only opaque envelope IDs (“New activity available”). FCM never receives plaintext or personal identifiers.
-
Apple/Google push infrastructure: Used indirectly via FCM/APNs for notification delivery.
We do not share data with advertising networks, data brokers, or analytics providers.
Data Retention
Data TypeLocationRetention
Encrypted message envelopesSupabase (messages_v2)User-requested expiry per conversation, capped at 30 days server-side. Messages older than the cap are deleted automatically even if the conversation is set to “Never” locally.
Routing metadata (PPIDs)Supabase (ppid_map)Up to 7 days to allow offline delivery; expired entries are cleared automatically.
Audit/security logsSupabase (audit_log)24 hours.
Push tokens & device recordsSupabase (devices, fcm_tokens)Until the device is revoked or deleted.
Local message historyDevice storageControlled by your per-conversation timer (10 minutes to 90 days or “Never”). Local caches can be scrubbed manually in the app.
Encryption keys/sessionsDevice secure storageUntil you remove the device or uninstall the app; not uploaded to our servers.
Your Rights & Controls
Because Cord does not maintain personal accounts, we generally cannot identify you unless you give us a beta email. Still, you have the following controls:
-
Access: You can inspect the data stored on your device (message history, settings). Server-side, we can confirm whether your random device ID still has undelivered envelopes.
-
Deletion:
-
Delete individual messages or cords inside the app (which also deletes associated PPIDs for that cord).
-
Use “Scrub data” in settings (or uninstall) to wipe all local keys and caches.
-
Contact us at cordmessaging@protonmail.ch with your device ID if you need us to force-delete undelivered envelopes or beta signup data.
-
Device management: Link/unlink devices and rotate your device identifier at any time; doing so invalidates old routing entries.
Security Measures
-
End-to-End Encryption: Implemented via the Signal Protocol (libsignal_protocol_dart) with forward secrecy, post-compromise security, and deniable authentication.
-
Metadata Hardening: Sealed sender envelopes (XChaCha20-Poly1305) hide sender identity from the server; per-device PPIDs prevent correlating different cords.
-
Secure Storage: Keys and sessions live in Keychain/Keystore (flutter_secure_storage); backups are disabled (android:allowBackup="false").
-
Transport Security: All client–server traffic uses TLS 1.3 with optional certificate pinning.
-
No analytics or trackers: Build scripts fail if banned SDKs (Firebase Analytics, Mixpanel, etc.) are added.
Children’s Privacy
Cord is not directed to children under 13, and we do not knowingly collect personal information from them. If you believe a child has provided data, contact us and we will delete it.
Changes
We may update this policy as features evolve. When we do, we will:
-
Update the “Last Updated” date.
-
Highlight material changes in the app or website.
Continued use of Cord after updates constitutes acceptance.
Contact
For privacy questions or deletion requests, email:
cordmessaging [@] protonmail.com
We aim to respond within 30 days.
© 2025 Cord Messaging – All rights reserved.