reLux is an internal camera app. It access to camera to take photos, it access to photo gallery to save them if requested by the user, but without reading anything.
reLux uses hashed unique ID to avoid free roll duplicates. Optionally, if invite user function is used, double-hashed referenced ID of involved users and contacts are stored on the server, as described in the next section.
reLux Privacy Store
Last updated: 2026-04-19
This document explains what data reLux uses, why it is used, where it is stored, and how invite and reward logic works.
1) High-level principles
- Privacy by default: core camera usage works without account creation.
- Optional permissions: Contacts and Location are optional and requested only when needed.
- Data minimization: referral backend receives hashed identifiers, not raw contact details.
2) Data used on device
The app stores the following on device:
- Captured media and processing outputs created by the user.
- Film roll queue and manifest in app cache (
Caches/FilmRollQueue).
- Purchase and roll ledgers in local app storage (
UserDefaults).
- Referral send-lock records in local app storage (
UserDefaults), keyed by pseudonymous inviter hash and contact hash.
- Referral known inviter-hash history in local app storage (
UserDefaults, short bounded list) to recover pending rewards if identifier source varies temporarily.
- Short-lived in-memory cache of inviter hash aliases (~60s) to avoid repeated identity resolution calls.
- A keychain marker that locks one-time welcome gift issuance across reinstall attempts.
- Optional location metadata only if the user enables location for photos.
- StoreKit: purchase and transaction handling for paid film rolls.
- iCloud key-value store (
NSUbiquitousKeyValueStore): ledger sync across user devices.
- CloudKit (entitlement:
CloudKit): used to derive an opaque user record identifier for stable, privacy-preserving identity derivation.
- App review prompt (
SKStoreReviewController) and App Store deep links for referral install/open flow.
4) Referral and invite system (relux-invites-php)
When the user taps "Earn X gifted rolls per friend invited":
- The app requests Contacts permission.
- For each contact, only a preferred identifier is used (
email or phone).
- The identifier is normalized locally and double SHA-256 hashed on device.
- Raw contact values are not sent to the backend.
- The inviter identity is derived from a local device key + optional CloudKit user record signal, then hashed and double-hashed before backend use.
- For reward recovery robustness, the app may check both pseudonymous inviter hash variants (device-only and device+iCloud) without sending raw identifiers.
- The app shows a per-contact invite list and user-triggered one-by-one share actions (no automatic bulk messaging).
- After a successful share action, the app stores a local send-lock for that inviter+contact hash pair to reduce repeat spam from the same account/device.
Data sent to backend
- Inviter double-hash
- Contact double-hash
- Contact label text (sanitized; backend does not require plaintext phone/email)
Data stored by backend
- Hashed contact identifiers
- Invite tokens (server-generated random base62 IDs, default 12 chars)
- Invite click timestamps and counters
- Hashed request fingerprint signals for anti-abuse (
ip_hash, ua_hash, and derived signature hash)
- Click audit rows with self-click suspicion flag/reason
- Reward grant IDs and acknowledgement state
- Registered user hashes (no plaintext personal profile fields)
Reward policy implemented
- Invite links are unique per inviter+contact pair.
- Invite UI allows one-by-one sharing per contact with system share sheet app choice.
- Contacts already app users or in recent-click cooldown are blocked by backend policy.
- Reward is granted on first rewarded contact click in absolute terms (anti-duplication).
- Each qualified referral grants pre-defined purchased rolls.
5) Anti-abuse protections
- One-time welcome gift rolls are keychain-locked to reduce abuse through app deletion/reinstall.
- Invite rewards are server-side tracked and acknowledged to avoid duplicate client crediting.
- First-click self-reward checks use short-window source-signature matching (not raw IP-only blocking), reducing abuse while limiting false positives for users on the same home network.
- Invite feature auto-disables in app if referral backend health endpoint is not reachable.
6) Permissions and purpose
- Camera: capture photos/videos.
- Microphone: audio for video/cinema capture flows.
- Photos library: save exported media.
- Contacts (optional): generate per-contact referral links.
- Location (optional): embed photo metadata when explicitly enabled.
- Notifications (optional): free-roll availability reminders.
7) Retention and deletion
- Local media and queue data can be removed by user actions inside app or by uninstalling.
- Some anti-abuse keychain flags may persist across reinstall on the same device.
- Referral backend stores hashed referral records needed for fraud prevention and reward accounting.
- Users can request backend data removal through app support channels (recommended operational policy).
8) Data sharing
- No sale of user data.
- Data is shared only with:
- Apple services required by app functionality (StoreKit, CloudKit, iCloud KVS).
- reLux referral backend for invite and reward validation.
9) Security controls
- Network communication is expected over HTTPS/TLS.
- Referral identifiers are hashed before transmission (double SHA-256).
- Backend access rules block direct public access to storage and sensitive files (storage, settings, DB files).
10) Reviewer quick notes
- Contacts are used only for optional invite generation.
- Raw contact identifiers are not uploaded; hashed tokens are used for referral matching.
- Welcome gift anti-reinstall lock is implemented via keychain.