1. Introduction
Konstruct is a privacy-first, end-to-end encrypted messenger built on the Signal Protocol. This policy explains exactly what data we collect, why we collect it, and what we do not collect. We have designed Konstruct from the ground up to minimize the data we hold about you.
Core Principle: We collect the absolute minimum data necessary to route encrypted messages. Your message content is end-to-end encrypted — our servers cannot read it, and we do not attempt to.
2. Information We Collect
2.1 Account Identifier
Konstruct requires no phone number, email address, password, or real name.
- User ID: A random UUID generated by the server when your account is created. It is not derived from your keys or from anything else about you, and nothing about you can be recovered from it.
- Device ID: A 32-character hash of your device's public Identity Key. Unlike the User ID it is deterministic — anyone who already holds that public key can compute it — which is why it is used for linking your own devices and for invite links, not as your account identity.
- Username (optional): a public alias others can find you by if you turn on discoverability. The server stores only a keyed hash of it, not the name itself. It can be changed or removed at any time.
No personally identifiable information is required to create an account or use Konstruct.
2.2 Cryptographic Key Bundle
To enable the Signal Protocol key exchange, your device generates and uploads the following public keys to the server. Your corresponding private keys never leave your device and are stored in the platform's protected key storage (iOS Keychain, Android Keystore).
| Key | Type | Stored on server | Purpose |
|---|---|---|---|
| Identity Public Key | X25519 (long-term) | Yes, permanently | Authenticates your device; used in X3DH handshake |
| Signed PreKey | X25519 (medium-term) | Yes, rotated periodically | Used in X3DH key agreement |
| One-Time PreKeys (OTPKs) | X25519 (ephemeral) | Yes, until consumed | Consumed one-per-session for Perfect Forward Secrecy |
| Private keys | — | Never | All private keys remain on your device only |
The server tracks how many One-Time PreKeys remain and requests your device to replenish them when the supply runs low. Once an OTPK is used to establish a session, it is permanently deleted from the server.
2.3 Pending Message Queue
When you send a message, it is encrypted on your device before transmission. The server holds the encrypted message in the recipient's mailbox. It does not delete a message because a device says it was received: mailboxes are trimmed by retention only — each has a size cap, and anything older than about 7 days is deleted. A message that has already been delivered can therefore remain on our server — encrypted and unreadable to us — for up to about 7 days.
What is stored in the mailbox (until it expires):
- Encrypted message payload (opaque binary blob — we cannot read this)
- Sender User ID is omitted on the sealed-sender path (always on for eligible traffic — see Stealth below); only recipient-recoverable sealed cert travels instead
- Recipient User ID
- Message ID (UUID)
- Timestamp
- Message sequence number (required for the Double Ratchet algorithm)
- Ephemeral public key (part of the Signal Protocol ratchet step — not a secret)
If your device is offline, messages wait in your mailbox until your next connection. A message not fetched within about 7 days is deleted unread.
Stealth (sealed sender): always on for eligible user traffic (messages, receipts, call signaling, etc.; a few control paths are excluded by design). Your device omits the Sender User ID from the envelope and seals a signed sender certificate to the recipient's identity key — only the recipient can recover who sent the message; the server cannot. Privacy Pass anonymous tokens can accompany sealed sends for anti-spam; server-side token enforcement is still rolling out. Stealth does not hide message timing, size, or your IP address from the network layer.
2.4 Contact Relationships
When you add a contact (via QR code or invite link), the server stores a record of that relationship to determine message routing and stream subscription. This allows Konstruct to notify you when a known contact comes online and to subscribe you to their message stream. The record is blinded: both sides are stored as a keyed hash (HMAC-SHA256) of the account id, never as the ids themselves, so a database leak does not hand anyone a readable social graph. Be precise about what that is worth — the key belongs to the server, so this protects the graph from a leak, not from us.
2.5 Push Notification Tokens
On iOS, to deliver real-time message notifications when the app is in the background (Android uses no push service — the app keeps its own connection):
- Apple APNs device token: Stored on the server and used solely to send a "new message" wake-up signal.
- Apple PushKit VoIP token: Stored separately and used solely to wake the app for an incoming voice call invitation. Like the APNs token, it carries no message or call content.
- No message content is ever included in push notifications. The notification contains only a generic signal that causes your device to connect and fetch the encrypted message, or — for calls — to present the incoming call.
2.6 Session Authentication
- Session tokens: an access token (valid 24 hours) and a refresh token (valid 90 days) authenticate your connection; both are revoked when you sign out or delete the account.
2.7 Voice and Video Calls
Voice and video calls are end-to-end encrypted. Call setup — the WebRTC session description (SDP) and ICE connectivity candidates — is exchanged over the same end-to-end-encrypted message path as your chats, so our servers cannot read it. Call audio and video use WebRTC's DTLS-SRTP; because the media-encryption keys are exchanged and authenticated inside that end-to-end-encrypted signaling, the media is encrypted end-to-end between the two devices — neither our servers nor any relay we use can decrypt it. Our server is told whether a call starts as a voice or a video call, so that the recipient's phone rings the right way; turning the camera on or off during a call is not sent to it. A relay can tell video from voice by the volume of the encrypted traffic it forwards.
To connect a call, the two devices exchange candidate network addresses (standard WebRTC ICE) to find a direct path. When a direct connection is not possible, encrypted media is relayed through a TURN server: the relay forwards only encrypted media it cannot read, but it does see the participants' network addresses. This connection metadata is necessary to route the call and is not linked to message content. On iOS, incoming calls are woken via the PushKit VoIP token described in 2.5; the push carries no call content. On Android a call arrives over the app's own connection, with no push. The TURN server runs in the Netherlands.
2.8 Media Attachments
When you send a photo, video, file, or voice message, the attachment is compressed and encrypted on your device (AES-256-GCM under a fresh per-file key) before it is uploaded. The decryption key travels only inside the end-to-end-encrypted message to the recipient — it is never sent to, or held by, the media server. The server stores only the opaque encrypted blob, identified by a random media ID, and cannot read its contents.
Encrypted media objects are automatically deleted after approximately 7 days from upload (independent of whether they were downloaded); the recipient's device fetches and decrypts them within that window. We store no plaintext media; about each object the server knows only the encrypted blob, its ID, its padded size class, a hash of the ciphertext, and its upload and expiry times.
2.9 What We Do NOT Collect
The following are explicitly not collected or stored:
- Phone number
- Email address
- Password
- Real name
- Message content (end-to-end encrypted — we cannot access it)
- Message history (only the encrypted mailbox described in 2.3, which we cannot read)
- Location data
- Typing indicators or read receipts beyond delivery confirmation
- Third-party analytics or tracking SDKs
2.10 IP Addresses and Connection Metadata
Connecting to any online service exposes your IP address to its servers at the network layer — this is unavoidable, and Konstruct is no exception. However, we do not write your raw IP address to our databases. Rate limits on device registration and proof-of-work challenges use only a salted, one-way hash of the address. To rate-limit message sending and key-bundle fetches, the server briefly holds the address itself (for IPv6, its /64 network) in an in-memory counter that expires within about a minute. We keep no IP-to-account mapping.
We do not use your address, or its hashed tag, to build behavioural profiles, link it to your message content, or share it for advertising. But a salted hash reduces exposure rather than perfectly anonymising it — because the IPv4 address space is small, a party holding the secret salt could still test candidate addresses. It removes the raw address from everything we store; it is not a guarantee that your network origin can never be determined by our infrastructure.
If you want to keep your network address off the path entirely, turn on censorship protection in Settings, or use a VPN or Tor — though the endpoint that terminates your connection still sees the apparent source address of that connection.
3. Traffic Analysis Protection
Konstruct implements padding and, on iOS, randomised send-timing jitter to make it harder for a network observer — or our server — to infer what you send from its size or exact timing. Messages are padded to fixed-size chunks. Attachments (photos, videos, voice notes, files, profile pictures) are padded to size classes, so the server stores a size range rather than the exact size of a file — a file grows by at most 12 %, usually about 3 % (the smallest files are padded up to 4 KB) — and is never told what type of file it is. These mitigations are active by default and require no configuration.
We deliberately do not send scheduled dummy/cover traffic. Constant cover traffic needs an always-on connection and timed sends, which drains battery and data; a mobile client cannot sustain it, and forcing it would trade real usability for marginal metadata hardening. Padding and send-jitter (above) are our mobile answer; constant cover traffic could only ever run on an always-online desktop client and remains a possible desktop-only option, never a mobile promise. We would rather ship no cover traffic than claim one that isn't running.
Separately, censorship protection is a network-level obfuscation layer that helps your connection blend in with ordinary HTTPS traffic when direct TLS is blocked. It is a censorship-circumvention mechanism, not a metadata-hiding one — it does not by itself prevent a network observer who can already see your connection from inferring message timing or size.
4. Anti-Spam: Proof of Work
To prevent spam without a phone number or email, Konstruct requires your device to perform a small Proof of Work computation at registration, and when sending after a rate limit has been exceeded. This is a client-side computation that imposes a negligible cost on legitimate use but makes large-scale spam computationally expensive. No personal data is involved.
5. How We Use Your Data
| Data | Purpose |
|---|---|
| User ID | Authenticate your device and route messages |
| Public key bundle | Enable Signal Protocol E2EE key exchange |
| Pending message queue | Hold encrypted messages until delivery |
| Contact relationships | Route messages and stream subscriptions |
| APNs token | Deliver background push notifications |
| PushKit VoIP token | Wake the app for incoming call invitations |
| Session token | Authenticate gRPC connection |
We do not use any collected data for advertising, profiling, analytics, or any purpose beyond operating the messaging service.
6. Data Storage and Security
6.1 Infrastructure
- Hosting: VPS at DigitalOcean (Netherlands)
- Persistent storage: PostgreSQL database (account data, key bundles, contact relationships)
- Ephemeral storage: Redis (session tokens, pending message queues)
- Jurisdiction: Netherlands / European Union — GDPR applies
6.2 Encryption
- In transit: Client–server messaging uses a gRPC bidirectional stream over QUIC on iOS when available, with automatic fallback to gRPC over HTTP/2 + TLS (Android uses HTTP/2 + TLS; the edge is Caddy on port 443, TLS 1.2 or 1.3). Control and auth RPCs use the same encrypted transport stack
- At rest: message and media content is stored only as ciphertext under keys held on devices; database backups are encrypted before they leave the server (Section 7.1)
- End-to-end: Signal-Protocol-based — X3DH / PQXDH key agreement (X25519 combined with the post-quantum ML-KEM-1024) and a Double Ratchet with ChaCha20-Poly1305 AEAD. A device's prekeys are signed twice — with Ed25519 and with a hybrid Ed25519 + ML-DSA-65 (post-quantum) signature — and no session is established without both; the hybrid key itself is still vouched for by an Ed25519 signature. Media attachments are encrypted with AES-256-GCM under a per-file key.
6.3 What Is Stored on Your Device
Your device stores the complete message history locally in storage protected by the operating system (iOS data protection; on Android, the app's private storage, with keys in the Android Keystore). This includes:
- Full conversation history
- Media attachments
- Contact list and display names
- Crypto session state (Keychain / Keystore)
- Draft messages
This data is under your control. Deleting the app removes all local data permanently.
6.4 Data Retention
| Data type | Retention |
|---|---|
| Pending messages | Deleted by retention: mailbox size cap, and at most ~7 days — not upon delivery |
| Media attachments (encrypted) | Auto-deleted ~7 days after upload (by object age, regardless of download) |
| One-Time PreKeys | Deleted from server upon consumption |
| Session tokens | Access token 24 hours, refresh token 90 days; revoked on sign-out or account deletion |
| APNs token | Retained until account deletion or token update |
| PushKit VoIP token | Retained until account deletion or token update |
| Username hash + User ID | Retained until account deletion |
| Signed PreKey | Replaced when rotated; old key deleted |
| Contact relationships | Currently not removed when a contact is removed or the account is deleted (blinded records; see 8.3) |
7. Data Sharing and Third Parties
We do not sell or rent your data, and we do not share it for advertising, profiling or any purpose unrelated to running the service. Operating it does require the providers listed below; each receives the minimum that its job needs, and none receives message content.
7.1 Infrastructure Providers
- DigitalOcean (Netherlands): provides the server. Has no access to application data or encryption keys.
- Hetzner Storage Box (Germany): holds database and queue backups — 7 daily and 4 weekly. Backups are encrypted before upload; Hetzner holds no key. They contain encrypted mailbox messages, blinded contact links and username hashes; media is not backed up.
- The TURN server (Netherlands) and censorship-protection relays: forward only encrypted traffic they cannot read, and see the network addresses of connections. Where the relays run is not published.
- Apple APNs: Receives only your device push token and a generic notification signal (no message content). Subject to Apple's privacy policy.
7.2 Legal Compliance
We may be required to disclose data if compelled by a valid legal order from a competent authority. However:
- We cannot decrypt your messages (end-to-end encrypted)
- We hold minimal metadata — no message content, no raw IP addresses in our databases (the short-lived rate-limit counter is described in Section 2.10), and no behavioural or usage profiling
- We will notify affected users unless legally prohibited from doing so
8. Your Rights
8.1 Anonymous Use
You can use Konstruct with no personally identifiable information. Your User ID is a random UUID the server assigns; it encodes nothing about you.
8.2 Access to Your Data
You may request a copy of any metadata associated with your account at any time by contacting us at the address below.
8.3 Account Deletion
You can delete your account from within the app settings. Upon deletion:
- The hash of your username, your User ID and your public key bundle are deleted from the server. The device ID and hash commitment remain in the key-transparency log, which is append-only and from which entries cannot be deleted
- Blinded contact-link records are not currently removed
- Your APNs and PushKit VoIP tokens are removed
- Messages in your mailbox expire on the normal retention schedule (up to ~7 days), and from backups as they rotate (up to ~4 weeks)
- Deletion is completed within 24 hours
Messages previously delivered to recipients are stored locally on their devices only and are outside our control after delivery.
8.4 Username
You can add, change, or remove your username at any time from account settings.
9. Minimum Age
Konstruct is intended for users 16 years of age and older, consistent with the app's 16+ App Store age rating. It is not directed to, or intended for, anyone under 16, and we do not knowingly collect data from anyone under 16. Because Konstruct holds only the minimal routing metadata described above and no message content, the data associated with any account is limited by design. If you believe someone under 16 is using Konstruct, contact us (Section 12) and we will act accordingly.
10. Who Is Responsible for Your Data
Konstruct is an independent project, not a company. The data controller under the GDPR is Maxim Eliseyev, the project's maintainer, reachable at the address in Section 12. Konstruct is not large enough to require a Data Protection Officer, and has not appointed one; requests under Section 8 go to the same address and are answered by the same person. If that changes — an entity is formed, or responsibility passes to someone else — this section changes with it, and the change is announced as described in Section 11.
11. Changes to This Policy
We will notify users of material changes through:
- An in-app notification
- An updated "Last Updated" date on this document
Continued use of Konstruct after changes constitutes acceptance of the revised policy.
12. Contact
For privacy questions, data access requests, or concerns:
- Email: maxim.elis@icloud.com
- Website: konstruct.cc
Summary
| No phone number or email required | End-to-end encrypted (Signal Protocol) |
| Fully anonymous use supported | Messages held only as ciphertext and deleted on a retention schedule (up to ~7 days) |
| No tracking or analytics SDKs | Traffic obfuscation built in |
| Private keys never leave your device | Minimal metadata only |
| No third-party data sales | GDPR jurisdiction (EU: server in the Netherlands, backups in Germany) |