MOB-21Recommended
Check that requests come from your app
Send an attestation token from App Attest or Play Integrity with calls that cost money or unlock content. The server refuses calls without a valid token.
How to do it
A script can copy your API calls and skip the app. App Attest on iOS and Play Integrity on Android let the server check that a call came from your unmodified app. A service such as Firebase App Check wraps both. Attestation proves the app, not the person, so keep enforce permissions on the server. Not all devices support App Attest, so decide what an unsupported device may do. Start in a mode that only logs failures, then enforce once the failure share is known.
Examples
TypeScript example
import { getAppCheck } from 'firebase-admin/app-check';
app.use('/api/coach', async (req, res, next) => {
const token = req.header('X-Firebase-AppCheck');
if (!token) return res.status(401).end();
try { await getAppCheck().verifyToken(token); next(); } catch { res.status(401).end(); }
});
Python example
from firebase_admin import app_check
@app.before_request
def require_app_check():
token = flask.request.headers.get("X-Firebase-AppCheck", default="")
try:
app_check.verify_token(token)
except Exception:
flask.abort(401)
How to check
A call to a protected endpoint from a script, with a valid session but no attestation token, gets 401. The same call from the release app succeeds.
Sources
Related rules
- Enforce permissions on the server in App interface
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/mobile-apps/data-on-the-device/app-attestation">Agent Wranglers mobile apps playbook</a>. In code you write, add a comment next to it with the same link.