Data flow at a glance
Protected locally
SwiftData persists entries inside the iOS app container. Privacy Lock can require device authentication before trade content is shown.
Optional off-device copy
When iCloud sync is enabled, CloudKit stores a private database under the user's Apple ID. Kyra does not operate a trade-history server.
Verify the boundary
Use App Privacy Report or a proxy to inspect destinations while logging, syncing, and viewing patterns.
Compare Kyra's App Privacy label with the data path and analytics description on this page.
Local protection does not replace Apple ID security or device security; those boundaries are listed below.
Storage layer
Kyra uses SwiftData for local persistence. The database file lives in the app's container on the device. Standard iOS protections apply:
- File is encrypted at rest using the device's Data Protection class
- File is not readable by other apps on the device (iOS sandboxing)
- File is included in iCloud Backup unless the user disables it (App Store Connect setting on by default)
- File is excluded from iTunes Backup if the user opts out
The model classes are Trade, UserSettings, and ChecklistSession. Schema migrations happen on app version updates. SwiftData handles the migration; no data is sent off-device during the migration.
Sync layer
When iCloud sync is on, SwiftData replicates the database through CloudKit's .automatic mode. CloudKit is Apple's user-data storage layer; in .automatic mode, the data lives in the user's private database in their iCloud account.
What this means concretely:
- The data is bound to the user's Apple ID, not to a Kyra account
- Apple cannot read the data without the user's iCloud credentials
- Kyra cannot read the data through any developer-accessible API — CloudKit
.automaticuser-private data is not surfaced to the developer - A subpoena to Apple would receive whatever data Apple has access to under their disclosure policies; a subpoena to Kyra returns nothing about your trades, because Kyra has nothing
If iCloud sync is off (toggle in Settings), trades remain on the single device they were logged on. No sync, no network traffic, no off-device copy.
Privacy Lock
Privacy Lock is the in-app authentication layer that gates trade visibility. When enabled:
- Opening Kyra prompts for Face ID, Touch ID, or the device passcode
- Returning to Kyra from the background re-prompts after a configurable timeout
- The app switcher blurs Kyra's preview thumbnail so trade information is not visible during a swipe-up gesture
- A direct deep link into a trade detail still requires authentication
The implementation uses Apple's LocalAuthentication framework. Kyra never sees the biometric data; the authentication result is a boolean response from iOS, not a credential the app stores.
Privacy Lock is a per-device setting — not synced through iCloud — so a trader can enable it on the iPhone and leave it off on the iPad if their threat model differs by device.
For the setup walkthrough, see FAQ ("How do I lock the app?").
Crash reporting
Kyra uses TelemetryDeck for anonymous analytics and Apple's MetricKit for crash diagnostics. The combination forwards three data classes:
- Device ID (anonymous, generated by TelemetryDeck — not the IDFA, not the IDFV, not anything Apple's ad system uses)
- Product Interaction (anonymous — what features get tapped, e.g., "trade entered via Quick P&L mode")
- Crash Data (anonymous — the technical crash report, function names and call stack, no user content)
What is not forwarded:
- Trade content (ticker, P&L, emotion, reflection text, any other field on the trade model)
- User identity (Apple ID, email, name)
- Location
- Device serial number, IDFA, IDFV
- IP address (TelemetryDeck strips or truncates per their policy)
Trade fields — ticker, direction, prices, P/L, emotion, execution rating, setup tag, reflections — are excluded from analytics payloads, log statements, and error messages by design. A quarterly egress audit verifies the exclusion across the codebase.
Analytics can be turned off in Settings → Privacy & Security → Analytics. With analytics off, zero outbound data is sent from Kyra except CloudKit sync traffic (if iCloud is on).
Network behavior
Kyra is built to function fully offline. The only outbound network activity is:
- CloudKit sync (only when iCloud sync is on; handled by Apple's framework, not by Kyra's networking code)
- TelemetryDeck signal (only when analytics is on; one HTTPS POST per session-bounded event)
- App Store software updates (handled by iOS; Kyra does not call out for update checks)
There is no third-party API call. There is no analytics SDK with its own outbound traffic. There is no ad-network beacon. There is no crash reporter that ships full device fingerprints. The list above is exhaustive.
A trader who wants to verify this can use Apple's built-in App Privacy Report (Settings → Privacy & Security → App Privacy Report on iOS 15.2+) to see Kyra's actual network destinations. The report will show Apple's CloudKit domains (gateway.icloud.com, etc.) and TelemetryDeck's ingestion endpoint if analytics is on. Nothing else.
Threat model
What Kyra defends against:
- A malicious app on the same device. iOS sandboxing prevents other apps from reading Kyra's database.
- An attacker with physical device access but no biometric. Privacy Lock gates the data behind Face ID / Touch ID / passcode.
- A shoulder-surfer in the app switcher. App-switcher blur hides the trade content.
- A subpoena to Kyra. Kyra has no trade content to surrender.
- A breach of a Kyra server. Kyra has no server to breach.
- An ad network that wants trader-targeting data. Kyra ships no advertising SDKs.
What Kyra does not defend against (because the threat is outside Kyra's control):
- A compromised Apple ID. If your iCloud is breached, your synced data is at risk. The defense is your iCloud password and two-factor authentication, not Kyra.
- A compromised device with biometric defeated. If an attacker has your unlocked iPhone, Kyra's at-rest encryption does not help. The defense is iOS-level (lost device wipe, Find My).
- A subpoena to Apple. Apple's policy for CloudKit user-private data determines what they release under legal order. Kyra is not in the chain of disclosure.
- A malicious iCloud backup restored to a different device. If a third party restores your iCloud backup to a device they control, they get the Kyra database. The defense is iCloud account integrity.
The threat model is honest about its boundaries. Kyra does not claim to defend against threats outside its layer.
What you can verify independently
Five things any technically curious user can check without taking Kyra's word:
- The App Privacy nutrition label. Visible on Kyra's App Store listing. Compare to any competitor's label.
- The App Privacy Report. Settings → Privacy & Security → App Privacy Report on iOS 15.2+. Shows Kyra's actual network destinations over the last 7 days.
- Network traffic with a proxy. Use Charles Proxy or Little Snitch on a Mac to intercept Kyra's outbound traffic. Confirm: no third-party domains, no analytics beacons beyond TelemetryDeck.
- The CloudKit storage class. Apple's documentation explains that
.automaticmode places data in the user's private database. Kyra's mode is verifiable from the schema definitions (publicly described in/why-on-device.html). - The TelemetryDeck mode. TelemetryDeck publishes an official guide for its default privacy configuration. Kyra uses the default mode with no custom user identifier.
If any of the architecture stopped matching the description above, the App Privacy label would have to change, the App Privacy Report would expose the discrepancy, the network traffic would tell on Kyra, and CloudKit would refuse the storage class. The story is auditable through five independent checks.
Updates to this page
When the security model changes — Privacy Lock gets a new authentication path, TelemetryDeck adds a new signal class, the threat model gains or loses a defense — this page gets updated. The version history is captured in the public changelog at Changelog.
If a vulnerability is reported, the disclosure timeline and the fix description land here. Email security disclosures to privacy@neontigerlabs.com.
The security model is small because the architecture is small. There is no backend, no account system, no ad SDK, no analytics SDK with its own outbound traffic. Each absence is a defense; together they form the privacy model explained in Why on-device. The implementation details on this page make that model auditable, not just claimed.