Chapter 15: Security
Building a secure purchase system from scratch means implementing server-side receipt verification, protecting against client-side tampering, validating purchase tokens, and ensuring the client never makes its own access decisions.
With RevenueCat, server-side verification is automatic, every purchase is verified before awaitPurchase() returns. This chapter covers the additional security features RevenueCat provides.
Trusted Entitlements (Response Verification)
The default configuration trusts CustomerInfo responses from RevenueCat's backend without cryptographic verification. An attacker with network access could theoretically intercept and modify the response.
Enable response signature verification to prevent this:
In INFORMATIONAL mode, RevenueCat signs every CustomerInfo response. The SDK verifies the signature and attaches the result to EntitlementInfos.verification:
In INFORMATIONAL mode, a failed verification is logged but does not block access. Change to ENFORCED to block access on verification failure:
In ENFORCED mode, EntitlementInfo.isActive returns false for any response that fails signature verification. This is the highest client-side security setting, but be aware that legitimate network issues (proxies, some VPNs) could cause verification failures for real users.
The Server Is Always the Authority
Even with EntitlementVerificationMode.ENFORCED, do not make server-side access decisions based solely on what the client reports. For any API that serves premium content, verify entitlement using the RevenueCat REST API or your own database updated by webhooks.
API Key Security
Your RevenueCat Android API key is embedded in your app binary. This is expected, it is a public API key that allows reading and purchasing but not administrative operations. Guard your secret API key (used for the REST API) on your server and never embed it in the client.
Anonymous Users
RevenueCat's anonymous user IDs ($RCAnonymousID:...) are generated on the device and are not secret. They are simply identifiers, not credentials. If a user shares their device, both users can read the anonymous purchase history. For production apps with real users, always identify users with your own authenticated user IDs by calling Purchases.sharedInstance.logIn("your_user_id").
Purchase Token Security
The purchase token is posted to RevenueCat's backend immediately after the purchase. If the network call fails, the SDK retries on the next app launch. The token is verified against Google's servers by RevenueCat, a fabricated or reused token will fail verification and not grant entitlements.
What RevenueCat Handles
- Receipt validation against Google Play Developer API on every purchase
- Protection against token reuse (RevenueCat deduplicates tokens)
- Cryptographic response signing (
INFORMATIONAL/ENFORCEDmodes) - Secure transmission to RevenueCat backend (HTTPS)
What You Handle
- Identifying users with authenticated IDs instead of relying on anonymous IDs
- Server-side entitlement checks using RevenueCat REST API for premium content
- Protecting your RevenueCat secret API key on your server