Trust
Security
Connecting your App Store, ad and payment accounts means trusting us with API keys. Here's exactly how they're handled.
How your keys are stored
- Encrypted at rest: every credential is encrypted with AES-256-GCM before it's written to the database, using a key that's held as a server secret, never in the database or source code.
- Write-only in the app: once saved, a key is never shown again, not even to you. Leaving a field blank when you edit a connector keeps the stored value.
- Never logged: request bodies and credentials are kept out of logs; error messages are scrubbed of anything that looks like a key or token before they're stored or displayed.
- Deleted when you leave: removing a connector, an app or your account deletes the stored credentials immediately.
Read-only, least-privilege access
WhyItChanged only reads reports and payments. It never creates charges, changes campaigns or edits your apps. Create keys with the smallest role each service offers:
| Service | Access to grant |
|---|---|
| App Store Connect | A team API key with the Sales and Reports role (not Admin) for sales; Analytics Reports also accept Finance or Sales roles. |
| Apple Search Ads | An API user with the API Account Read Only role. |
| Google Ads | OAuth for a user with read access to the account; the API is only queried with GAQL SELECT reports. |
| Google Analytics 4 | A service account added to the property as Viewer. |
| RevenueCat | A V2 secret key with only the charts & metrics read permissions. |
| Stripe | A restricted key (rk_live_) with Balance, Charges and Customers set to Read. |
| Polar | An organization token with orders:read, refunds:read, organizations:read. |
| Paddle | An API key with transaction.read and adjustment.read. |
| Lemon Squeezy | Lemon Squeezy keys can't be scoped; WhyItChanged only sends GET requests with it. |
Infrastructure
- Runs on Cloudflare Workers with data in Cloudflare D1. All traffic is HTTPS; www and HTTP redirect to HTTPS.
- Passwords are hashed with PBKDF2-SHA256; sessions are HttpOnly, SameSite cookies; changing your password signs out every other device.
- API keys for the MCP server are stored as SHA-256 hashes and can be revoked any time.
- Inbound webhooks (Stripe, RevenueCat, GitHub, your backend) are signature- or secret-verified.
- Sign-up is protected by Cloudflare Turnstile and rate limits.
- Payments for WhyItChanged itself are handled by Stripe; we never see your card number.
Your data
- We don't sell data, show ads, or use your numbers to train AI models.
- Your data is only visible to your account. The MCP server only answers with API keys you create.
- Delete any app, or your whole account, from settings at any time; it's removed immediately.
Report a vulnerability
Email admin@vitalsply.com. We reply within two business days and credit researchers who report responsibly.