Security
Protecting what matters most
Overview
In the age of AI powered tools that can decompile apps and scan for exposed secrets in seconds, keeping sensitive data off the client is not optional. Folio treats security as a first class concern. Every third party API key lives on the server, never in the app bundle. Authentication tokens are stored in platform native secure storage (Keychain on iOS, Keystore on Android). And because your portfolio is deeply personal financial data, we added biometric lock so nobody can peek at your holdings without your face or fingerprint.
How it works
All third party API keys (Alpha Vantage, Anthropic, service role keys) are stored as Supabase environment variables. The client never sees them.
When the app needs market data or AI features, it sends a request to a Supabase Edge Function with the user's JWT. The edge function retrieves the secret key from the environment, makes the upstream call, and returns only the result.
Auth tokens and user data on the device are persisted through expo-secure-store, not AsyncStorage or plain disk. Clerk's built in tokenCache handles JWT lifecycle automatically.
Every edge function validates the Authorization header before doing anything. No valid JWT, no response. The market-data function also enforces per user rate limiting to prevent abuse.
Biometric lock is an app level gate. When enabled, the app requires Face ID or Touch ID before revealing any portfolio data. Even if someone has your unlocked phone, they cannot see your holdings.
Key decisions
API keys on the server, never in the bundle
It would have been simpler to ship the Alpha Vantage or Anthropic key directly in the app and call the APIs from the client. But any key in a client bundle can be extracted. Tools exist that pull strings from .ipa and .apk files in seconds. By proxying every external call through edge functions, the keys only exist in Supabase's secret manager. Even if someone decompiles the entire app, they will find nothing useful.
Secure storage over AsyncStorage
AsyncStorage stores data as plain text on disk. Anyone with device access (or a backup tool) can read it. expo-secure-store uses the OS level keychain and keystore, which encrypt at rest and require device authentication to access. We use it for auth tokens, user data, and the authenticated flag. It is a tiny change in code but a massive difference in protection.
Biometric lock for portfolio privacy
Portfolio data is uniquely sensitive. Unlike a social media app where the worst case is someone seeing your posts, a finance app exposes your net worth, your positions, and your strategy. Biometric lock adds a layer that is tied to you physically, not just to your phone's passcode. It is optional so it does not add friction for users who do not want it, but it is there for anyone who does.
Per user rate limiting on edge functions
Without rate limiting, a single user (or attacker) could burn through our Alpha Vantage quota in minutes. Each edge function tracks requests by the JWT subject claim with a sliding window of 60 requests per minute. If you exceed it, you get a 429 response. This protects both our API quotas and the service availability for other users.