Security
How RevenueHog encrypts your App Store Connect, Stripe, Google Play and Apple Ads credentials, the sign-in methods it supports, token handling and rate limits.
RevenueHog works from keys you paste in: an App Store Connect .p8, and optionally a restricted Stripe key, a Google Play service account, or an Apple Ads key. This page covers how those keys are stored, what they can do, how you sign in, and the limits that protect the service.
Credential encryption
Every credential you give RevenueHog is encrypted with AES-256-GCM before it is written to the database.
- Each value gets a random 12-byte IV and is stored as IV, authentication tag and ciphertext.
- The 32-byte encryption key is a Cloudflare Worker secret, held apart from the database, so a copy of the database alone cannot decrypt anything.
- GCM is authenticated: a tampered value fails to decrypt instead of producing garbage.
- Keys are decrypted in memory only when RevenueHog calls Apple, Stripe or Google on your behalf.
- The dashboard never shows a stored key back to anyone. It shows only whether one is present.
If a stored key can no longer be read, the connection shows "The stored key can't be read. Disconnect and connect again."
The least access that works
Give the App Store Connect key the lowest role that covers what you want. RevenueHog detects the role and shows which features it unlocks in the capability matrix.
| App Store Connect role | What RevenueHog can do with it |
|---|---|
| Sales or Finance (minimum) | Read daily sales and subscription reports: revenue, MRR, churn, trials. |
| Finance | Also read payout reports. |
| App Manager | Also set server-notification URLs for you (the only write) and read TestFlight. |
| Admin | Also webhooks and analytics report requests. Not needed for most people. |
A Sales or Finance key can only read reports. The one write RevenueHog makes is setting your server-notification URLs, and only when the key has the App Manager role and you ask for it. See API key roles.
For Stripe, RevenueHog accepts restricted keys only (rk_live_ or rk_test_) and refuses secret and publishable keys, because a secret key can move money. Setup asks for read permissions on customers, subscriptions, invoices, charges, products, prices, payouts, balance and events. Webhook Endpoints write is optional; without it RevenueHog polls instead of registering a webhook. See Connect Stripe.
Rotation and removal
- Upload a new
.p8and the old encrypted copy is overwritten. - Remove a credential and its row is deleted.
- Clear credentials… under Settings → Connections → DANGER removes the App Store Connect key and stops syncing, keeping imported data.
- To be sure, also revoke the key at the source: App Store Connect (Users and Access, Integrations) or Stripe (Developers, API keys). Revoking at the source takes effect instantly, even if you never sign in to RevenueHog again.
- Deleting your account deletes every workspace you were the last member of, including stored keys. See Delete your account.
Sign-in methods
| Method | Notes |
|---|---|
| Email and password | Passwords must be at least 8 characters. Email verification is required in production. Reset by email from Forgot password. |
| Offered when configured. | |
| GitHub | Offered when configured. |
A Google or GitHub sign-in with the same email as an existing account links to that account automatically; both providers verify the email first. Sessions are shared between revenuehog.dev and app.revenuehog.dev.
The iOS app signs in with the same account and uses a session bearer token. The experiments skill signs a terminal in with a device code you approve at /device.
Tokens and API keys
| Credential | Format | Stored as | Lifetime |
|---|---|---|---|
| MCP token | rh_mcp_... | SHA-256 hash | Until revoked |
| MCP OAuth access token | mcp_at_... | Signed; its connection is a stored row | 7 days, or until the connection is revoked |
| MCP OAuth refresh token | mcp_rt_... | Signed; its connection is a stored row | 90 days, renewed on each refresh, or until revoked |
| Feedback API key | rh_live_..., rh_test_... | Only a prefix is kept for display | Until revoked |
| Device-flow session | Session token | Session row | About a week |
Secrets for MCP tokens and API keys are shown once at creation. MCP tokens and API keys belong to the workspace, not to the person who created them, so revoke them when someone leaves. Only owners and admins can create or revoke them. OAuth connections are listed under Settings → MCP tokens and can be revoked one at a time; a connection also stops working when the person who approved it leaves the workspace or deletes their account.
Rate limits
All limits are per minute and enforced on Cloudflare.
| Surface | Limit | Response when exceeded |
|---|---|---|
| Sign-in, sign-up, password reset and change, verification email | 10 per IP per group | 429 "Too many attempts. Try again in a minute." |
| Signed-in app and dashboard API (mobile routes) | 120 per user | 429 rate_limited |
| SDK, attested | 240 per workspace | 429 |
| SDK, unattested | 30 per IP and bundle ID | 429 |
| App Attest enrollment and challenge | 10 per IP | 429 |
| Feedback API keys | 240 per workspace | 429 |
| Customer lookup | 30 per workspace | 429 |
429 responses carry retry-after. If the limiter itself is unavailable, requests are allowed rather than blocked. See Rate limits.
Where it runs
| Sub-processor | Purpose |
|---|---|
| Cloudflare | Hosting (Workers), queues, cache, email delivery |
| Neon | PostgreSQL database, United States |
| Apple | Source of App Store reports and notifications; push delivery (APNs) |
| Google Play data if you connect it, Google sign-in, analytics, push (FCM) |
Report a problem
Found a vulnerability or think a key was exposed? Email privacy@revenuehog.dev. If a key may be exposed, revoke it at Apple or Stripe first; that takes effect immediately.
Related
Last updated on
Billing and plans
RevenueHog is free on the web. The only paid product is the RevenueHog Alerts subscription in the iOS app, which unlocks push alerts for your whole workspace.
Privacy
What data RevenueHog collects from your account, App Store Connect, notifications, SDKs and analytics, where it is stored, and how to remove all of it.