Privacy & security

Keys in secure device storage, conversations local-only, prompts only to your chosen provider, no telemetry, and one-tap erase of every local boundary.

Cordy for Mobile is designed so that your keys and conversations stay yours. There is no Cordy backend: the app talks directly from your device to the provider you choose. This page is the complete data-handling story, including an honest note on platform status.

Principles

  1. No backend. Cordy operates no server. Nothing you type is sent to, stored by, or routed through Cordy.
  2. Local-first. Conversations and settings live on the device; API keys live in the platform secure store.
  3. Direct to the provider. Prompts go only to the provider you selected, over HTTPS, carrying your key as the request's Authorization header.
  4. No account, no sync, no telemetry. You never sign in, nothing is mirrored to a server, and there is no analytics or payload capture.
  5. Erasable. One action wipes every local boundary the app owns.

The data flow

When you send a message:

You → CordyAI (on device) → the provider you selected

That's the entire path. The provider receives your prompt (and processes it under their privacy policy and data-retention terms — worth reading for whichever provider you use). Cordy is not a party to the request.

Where your data lives

DataLocationNotes
API keysAndroid Keystore / iOS KeychainEncrypted, device-bound, per provider. Never in the DB or logs.
Conversations & messagesOn-device SQLDelight (SQLite) databaseNever leave the device except as prompt content you send.
Attachments (images)On-device file storage, referenced by messagesReleased when their message/conversation is deleted.
Settings & preferencesOn-device app preferencesNon-sensitive (active provider/model, temperature, etc.).
Model catalog & pricing cacheOn-device databaseFetched per provider; safe to clear/refresh.

Key storage, in detail

API keys get the strongest local protection each platform offers:

  • Android — a key held in the Android Keystore performs AES-256-GCM encryption of each value, stored as Base64(IV ‖ ciphertext ‖ GCM tag) in a private preferences file. If the Keystore key is permanently invalidated (for example by a device restore or lock-screen reset), the affected value is dropped rather than returned corrupt. Values written by the older EncryptedSharedPreferences are transparently migrated to this scheme on first read.
  • iOS — the Keychain, stored with AfterFirstUnlockThisDeviceOnly accessibility. This makes each key device-bound and non-syncable: it is kept out of iCloud Keychain and out of encrypted backups, and is available only after the first unlock.

Keys are scoped per provider, so each provider has an independent entry. Saving a blank key is treated as deletion.

What leaves the device — and what doesn't

  • Leaves: the prompt content of messages you send, to the provider you chose, plus your key in that request's auth header.
  • Does not leave: your conversation history, your key at rest, your settings, your usage analytics. There is no account, no cloud sync, and no server-side copy of anything.

Logging

Cordy does not capture analytics or telemetry. In release builds, logging severity is capped so that verbose/debug/info logs — which can carry prompt or request detail — never reach the device console. Error messages shown in the UI are deliberately safe: raw provider response bodies, API keys, and auth headers are never displayed.

One-tap erase

Settings → Erase all local data wipes every local boundary the app owns. The confirm dialog is explicit: "This permanently deletes every local conversation, every preference, and every API key on this device. This cannot be undone."

Erase clears, in order:

BoundaryWhat's removed
DatabaseConversations, messages, and generation runs (plus user-defined providers and the model catalog)
PreferencesThe whole preferences store
Secure storageAll stored API keys
AttachmentsImage attachment files
Image cachesPlatform image memory + disk caches
Temp filesCamera / capture temporary files

Erase attempts every boundary even if one fails (so a locked keychain can't leave the database full of conversations), collects any failures, and then verifies the app is actually empty. It reports honestly if any part could not be cleared.

What erase does not touch: the app binary, OS-level backups, and anything outside CordyAI's own storage. It only removes data the app itself persisted.

In-app disclosures

Cordy states its data flow inside the app, not just in these docs. Settings includes a Privacy and data flow section: "Conversations stay on this device. API keys use secure storage. This version has no cloud sync, account, or analytics." When a provider is selected, it also shows "Your prompts go to (provider) when you send them. CordyAI doesn't send them anywhere else."

Honest platform note

Android is the fully verified platform. The security model above is implemented and tested on Android.

iOS is in progress. The Keychain-backed key store and the privacy design are implemented in the shared/iOS code and compile against the iOS target, but they have not yet been smoke-tested on a device, and mobile capture (image / camera / voice) is not yet wired on iOS. Until iOS device verification is complete, treat the iOS build as preview-quality and rely on Android for the fully verified experience.