Privacy Policy
This policy is versioned alongside the app's source code; the most recent commit on main is authoritative.
TL;DR
Exchange is a cryptographic messenger that puts your keys on your device and leaves them there. It has no servers, no accounts, no analytics, no telemetry, no advertising, and contacts no third-party network at all. Everything you encrypt or decrypt happens locally inside the app process. The only things that ever leave your device are encrypted envelopes you choose to share through other apps — and once they leave, the developer has no way to read or trace them.
What the app accesses, and what each access does
Camera (NSCameraUsageDescription). Used by the Add Recipient screen when you tap "Scan QR" to capture a contact's public-key bundle from their phone. Camera frames are processed entirely on-device by iOS's QR-code recognition framework; nothing is recorded, stored, or transmitted. iOS asks for camera permission the first time you tap Scan QR. You can revoke the permission at any time in Settings → Exchange → Camera; without it, you can still add recipients by pasting their public-key bundle as text.
Keychain. Exchange writes a single 64-byte item to the iOS Keychain (your encryption + signing private keys) under a Keychain access group shared with the iMessage extension on the same device. The item uses kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, an OS-level flag that prevents the item from syncing via iCloud Keychain or migrating to a different device. It is generated on first launch, replaced when you tap "Reset identity" in Settings, and is otherwise never copied, exported, or transferred.
App Group container. The list of recipients you've saved (display name, two public keys, fingerprint, optional notes, creation date) is stored in a SwiftData store inside an App Group container shared between the main app and the iMessage extension. The container is local to your device.
What goes over the network
Nothing the developer controls. Exchange has no backend. It does not contact any server operated by nettrash. It contains no third-party SDKs, no analytics, no telemetry, no crash reporter beyond Apple's automatic anonymous crash logs (which contain no user content). The app makes zero outbound network requests under its own initiative.
What you choose to share. When you tap Share or Copy on an encrypted envelope, the envelope is handed to whichever messenger you pick (iMessage, Mail, Telegram, WhatsApp, etc.). That messenger handles its own data flow under its own privacy policy; Exchange does not participate in or observe what happens after handoff. The envelope content is ciphertext that only your selected recipient's private key can open.
iMessage extension data flow. When you compose through Exchange's iMessage extension, the encrypted envelope is embedded in an MSMessage URL and delivered through Apple's iMessage end-to-end encrypted service to the recipient's device. Apple is the data controller for that delivery. The plaintext is never seen by iMessage — only the already-encrypted Exchange envelope rides inside the iMessage transport.
Data stored on your device
Identity private keys — the 64-byte concatenated Curve25519 ECDH + Ed25519 signing private keys, stored in iOS Keychain. Generated on first launch. Starting with v1.1, the default storage mode is Synchronizable with kSecAttrAccessibleAfterFirstUnlock, which lets iOS / macOS sync the keys across the user's same-Apple-ID devices via end-to-end encrypted iCloud Keychain. The user can opt back to kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly in Settings → Identity sync if they prefer the v1.0 device-bound behaviour. The user can also export the identity as a passphrase-encrypted (PBKDF2-SHA256 + ChaCha20-Poly1305) blob, or transfer it in person via QR — both in Settings → Backup & transfer.
Recipient list — display names, public keys (encryption + signing), fingerprints, optional notes, creation timestamps. Stored locally in the app's private SwiftData container inside the App Group group.me.nettrash.Exchange. Starting with v1.1, the recipient list is also synced across the user's devices via an end-to-end-encrypted blob: the list is JSON-encoded, encrypted with ChaCha20-Poly1305 under a key derived from the identity's encryption private key (HKDF-SHA256, info "Exchange.recipients.v1"), and the resulting opaque blob is stored as a Synchronizable Keychain item. iCloud Keychain carries the ciphertext between the user's devices on the same Apple ID; Apple cannot decrypt it because Apple does not hold the identity-derived key. Recipients sync is on by default in v1.1 and can be turned off in Settings → Recipients sync. SwiftData's CloudKit integration remains explicitly disabled (cloudKitDatabase: .none) — no recipient metadata is ever stored on Apple's CloudKit servers in plaintext or under Apple-managed keys.
No message history. Exchange does not retain plaintext messages, ciphertext envelopes, or send/receive logs. Each compose and decrypt action is transient: the plaintext appears on screen and is forgotten when you dismiss the sheet. If you want a record of what you sent, copy it before dismissing — the app does not keep one for you.
Encryption details
Exchange uses standard, publicly vetted cryptography from Apple's CryptoKit framework. Each outgoing envelope is sealed using a hybrid scheme:
- Curve25519 (X25519) ephemeral-static ECDH for per-message key agreement.
- HKDF-SHA256 to derive a wrapping key from the shared secret.
- ChaCha20-Poly1305 AEAD for both wrapping the per-message symmetric key and encrypting the body.
- Ed25519 signature over the entire binary blob, so the recipient can authenticate which signing key produced the message.
All four primitives are implemented by Apple's CryptoKit on-device and are exempt under EAR §740.17(b)(1) as standard mass-market cryptography. The app's source code is the authoritative reference; envelope format is documented in CryptoEnvelope.swift.
App Tracking Transparency
Exchange does not "track" you in the sense Apple's App Tracking Transparency framework defines: it does not link any data collected in the app with data from other apps, websites, or offline sources to build a user profile, and it does not share any data with data brokers. There is no data collected to share. Exchange therefore does not present an ATT prompt. The app ships a PrivacyInfo.xcprivacy manifest in every binary (main app and iMessage extension) declaring NSPrivacyTracking = false, no tracking domains, no collected data types, and no Required-Reason API usage.
Third-party services
| Service | What it sees | Whose policy applies |
|---|---|---|
| Apple iMessage | Encrypted envelopes embedded in MSMessage URLs, when the iMessage extension is used as the transport | Apple's |
| Apple CryptoKit | On-device cryptographic operations only; no network use | Apple's |
| Apple Keychain | The identity item; if iCloud Keychain sync is on (the default), Apple stores the end-to-end-encrypted blob in iCloud Keychain so the user's own devices on the same Apple ID share it | Apple's |
| Whatever messenger you choose for the Share button | The encrypted envelope (ciphertext) that you decided to send through it | That messenger's |
Specifically NOT used: any third-party analytics SDK (Firebase, Mixpanel, Sentry, etc.), any advertising SDK, any attribution / install-tracking SDK, any social-media SDK, any IDFA-consuming network, any custom server. Exchange has no code that calls anything outside Apple's bundled frameworks.
Children's privacy
Exchange is rated 4+ and is suitable for all ages. We do not knowingly collect personal information from children, because we do not collect personal information from anyone.
International data transfers
Because Exchange has no backend and contacts no third-party network, no personal data is transferred internationally by the app. Your encrypted envelopes, when sent through Apple's iMessage or any other messenger, transit those services' infrastructure under their own respective privacy policies.
Your rights
Because we hold no data about you:
- There is no record to access under GDPR Article 15 / CCPA "right to know".
- There is no record to delete under GDPR Article 17 / CCPA "right to delete" — the local identity and recipient list are yours alone, and you can remove them by tapping Reset identity in Settings or by uninstalling the app.
- There is no record to correct under GDPR Article 16.
- There is nothing being sold or shared under CCPA / CPRA, so no opt-out is required.
Changes to this policy
If a future version of Exchange changes any of the above — adds analytics, integrates a third-party SDK, adds a network endpoint, or starts using a permission for a new purpose — this document will be updated in the same release and the Effective date will be bumped.
Contact
Privacy questions: nettrash@nettrash.me. For day-to-day support, see the Exchange support page.