Back to Architecture
    ArchitectureArchitecture
    16 min read
    June 2026

    Mobile App Security Architecture

    Mobile App Security Architecture

    Last quarter, a fintech client in Gurgaon shipped a UPI-linked wallet to production with refresh tokens stored in AsyncStorage and API keys embedded in the React Native bundle. Penetration testing took four days. The testers extracted the staging API key from a decompiled APK, replayed refresh tokens from a rooted emulator, and initiated fund transfers that bypassed device binding. None of this required exotic tooling—just MobSF, Frida, and patience.

    The product team had followed a checklist: HTTPS everywhere, bcrypt on the server, two-factor authentication for high-value transfers. What they lacked was a coherent mobile app security architecture—a set of layered decisions about where secrets live, how the client proves its identity, and what the backend trusts when a request arrives from a phone on a patchy 4G connection in Noida.

    We rebuilt the architecture over six weeks without rewriting the entire app. The lesson was not that mobile security is impossible on a startup budget. It is that security controls must be designed as a system, not sprinkled on after feature development. This article documents the architecture we recommend when CTOs and founders ask us how to secure a mobile app without turning every login into a fifteen-step ordeal.

    What You Will Learn

    • Map a threat model across client, transport, API, and backend layers—and decide what you will not try to defend on-device
    • Implement token storage, certificate pinning, and session handling using platform-native primitives (Android Keystore, iOS Keychain, OAuth 2.0 + PKCE)
    • Align your release pipeline with OWASP mobile security 2026 expectations: MASVS Level 1 for most apps, Level 2 when handling payments or health data
    • Choose between attestation (Play Integrity, App Attest), root detection, and server-side risk scoring—with honest trade-offs on each
    • Structure backend API gates so compromised clients cannot escalate privilege through replay or token theft
    • Estimate security engineering cost in INR and sequence work across MVP, growth, and compliance phases
    • Apply mobile app security best practices that survive Indian network conditions, device fragmentation, and DPDP Act obligations

    The Client Layer: Assume the Device Is Hostile

    Every serious mobile app security architecture starts with one assumption: the client runs on hardware you do not control. Users install sideloaded builds. They run Magisk on Android or jailbreak iOS. They share phones with family members. They dismiss security prompts because the OTP arrived late on Jio during peak hours.

    That means secrets that unlock money, health records, or admin access must never live in plaintext on the device. It also means client-side validation is UX convenience, not security. Your architecture should treat the mobile app as an untrusted presentation layer that holds short-lived credentials and renders responses from a server that makes the real authorization decisions.

    What belongs on-device versus on-server

    We keep on-device: access tokens with TTL under fifteen minutes, non-sensitive UI preferences, cached public content, and device-specific keys generated inside secure hardware when available. We never keep on-device: long-lived refresh tokens without hardware binding, payment signing keys, admin credentials, or PII that regulations classify as sensitive personal data under India's Digital Personal Data Protection Act.

    For a healthcare app development engagement, we extend this boundary further: clinical identifiers and diagnostic summaries stay encrypted at rest with keys the server rotates, and the app fetches them only after step-up authentication. Storing a patient's full record locally because "offline mode is a nice feature" creates an audit trail problem you cannot fix with a patch release.

    Secure storage: platform primitives, not DIY encryption

    Teams often roll custom AES wrappers around SharedPreferences or UserDefaults. We discourage this unless you have a cryptographer reviewing the implementation quarterly. Android's EncryptedSharedPreferences (backed by Android Keystore) and iOS Keychain with kSecAttrAccessibleWhenUnlockedThisDeviceOnly give you hardware-backed protection on most devices shipping in India today.

    The limitation is real: on devices without TEE support or with known Keystore bugs on older OEM skins, encrypted storage degrades to software-only protection. Your architecture must account for that by keeping token lifetimes short and pairing storage hardening with server-side session revocation.

    Why we store refresh tokens in the Keystore, not AsyncStorage

    This is the single highest-impact client change we make on React Native and Flutter audits. AsyncStorage, MMKV without encryption, and plain SQLite are fine for theme preferences. They are not fine for OAuth refresh tokens.

    // Android: refresh token in EncryptedSharedPreferences + Keystore
    val masterKey = MasterKey.Builder(context)
        .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
        .build()
    
    val securePrefs = EncryptedSharedPreferences.create(
        context,
        "auth_vault",
        masterKey,
        EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
        EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
    )
    
    fun saveRefreshToken(token: String) {
        securePrefs.edit()
            .putString("refresh_token", token)
            .apply()
    }
    
    fun clearOnLogout() {
        securePrefs.edit().clear().apply()
        // Also revoke server-side — client clear alone is insufficient
    }

    iOS Keychain with device-only accessibility

    On iOS, we mirror the same policy with Keychain items that do not sync via iCloud and require the device passcode gate. Swift's Security framework is verbose; we wrap it once and reuse across projects.

    enum KeychainError: Error { case unexpectedStatus(OSStatus) }
    
    func saveRefreshToken(_ token: String, service: String) throws {
        let data = Data(token.utf8)
        let query: [String: Any] = [
            kSecClass as String: kSecClassGenericPassword,
            kSecAttrService as String: service,
            kSecAttrAccount as String: "refresh_token",
            kSecAttrAccessible as String:
                kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
            kSecValueData as String: data
        ]
        SecItemDelete(query as CFDictionary)
        let status = SecItemAdd(query as CFDictionary, nil)
        guard status == errSecSuccess else {
            throw KeychainError.unexpectedStatus(status)
        }
    }

    Transport and Session Architecture

    TLS 1.2+ with strong cipher suites is table stakes. It is also insufficient when users install corporate MITM proxies, when outdated devices trust compromised CAs, or when an attacker on the same café Wi-Fi in Connaught Place runs sslstrip against apps that do not pin certificates.

    Certificate pinning: when we require it

    We require pinning for fintech, healthcare, and any app handling government-issued identifiers. We often skip pinning for content-heavy consumer apps where CDN certificate rotation would break older builds in the field—unless the app handles authenticated sessions on the same domain.

    Pinning trades operational flexibility for tamper resistance. If you pin to a leaf certificate that expires in ninety days and forget to ship an app update, you lock out users. We pin to SPKI hashes of intermediate CAs and maintain a backup pin for rotation. We also implement a controlled break-glass path: a remote config flag that disables pinning only after two failed app versions have been pulled from stores—never a silent server-side disable on every request.

    // React Native 0.76+ with react-native-ssl-pinning
    import { fetch } from 'react-native-ssl-pinning';
    
    const PINNED_HOST = 'api.example.com';
    
    export async function secureGet(path: string, accessToken: string) {
      const response = await fetch(`https://${PINNED_HOST}${path}`, {
        method: 'GET',
        timeoutInterval: 15000,
        sslPinning: {
          certs: ['api_example_com'], // .cer in android/app/src/main/res/raw/
        },
        headers: {
          Authorization: `Bearer ${accessToken}`,
          'X-Request-Id': crypto.randomUUID(),
        },
      });
      if (response.status === 401) throw new Error('SESSION_EXPIRED');
      return response.json();
    }

    OAuth 2.0 + PKCE and refresh token rotation

    Password grants are dead. Authorization Code with PKCE is the baseline for native apps in 2026. Our session architecture looks like this: short-lived access tokens (5–15 minutes), rotating refresh tokens bound to a device ID, and server-side session tables that store token family hashes—not the raw tokens themselves.

    When a refresh token is reused after rotation, we treat it as a theft signal: revoke the entire token family, force re-authentication, and log the event for fraud review. This pattern costs more backend engineering than stateless JWTs, but it closes the replay window that bit our Gurgaon fintech client.

    API and Backend Gates: Where Real Authorization Lives

    The mobile app requests. The API decides. Every sensitive operation—transfer initiation, prescription upload, admin configuration—passes through gates that do not trust client claims about user role or account balance.

    Defense in depth on the server

    Our standard backend stack for Indian deployments runs behind AWS ALB or Cloudflare, with WAF rules tuned for mobile traffic patterns: rate limits per device fingerprint and IP, geo-fencing for admin endpoints, and payload size caps on upload routes. Application-layer checks include scoped OAuth tokens (a read-only token cannot call POST /transfers), idempotency keys on financial writes, and server-computed risk scores that may trigger step-up authentication regardless of what the app UI shows.

    For teams already on Firebase, we document the hidden risks in our guide on Firebase cost and security issues—Firestore security rules are not a substitute for an API gateway when money moves.

    Device attestation and integrity checks

    Root detection and jailbreak flags are noisy. Legitimate power users trigger them; sophisticated attackers hide them. We use Google Play Integrity API (Android) and Apple App Attest (iOS) as signals, not verdicts. A failed integrity check might block high-value transfers while still allowing balance enquiries.

    Attestation adds latency—200–800 ms on Indian networks—and fails on sideloaded enterprise builds. Budget for a fallback path: step-up OTP via bank-grade SMS gateway, not a hard crash loop.

    CI pipeline gates aligned with OWASP MASVS

    We wire security checks into CI so they run on every release candidate, not once before launch. OWASP Mobile Application Security Verification Standard (MASVS) Level 1 covers baseline storage, network, and platform interaction controls. Level 2 adds reverse-engineering resistance and advanced auth—appropriate for wallets and clinical apps.

    # .github/workflows/mobile-security.yml (excerpt)
    name: mobile-security-gates
    on:
      pull_request:
        paths: ['android/**', 'ios/**', 'src/**']
    
    jobs:
      dependency-check:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - name: OWASP Dependency-Check
            uses: dependency-check/Dependency-Check_Action@main
            with:
              project: 'mobile-client'
              path: '.'
              format: 'HTML'
              args: >
                --enableExperimental
                --failOnCVSS 7
    
      mobsf-scan:
        runs-on: ubuntu-latest
        needs: dependency-check
        steps:
          - uses: actions/checkout@v4
          - name: Build debug APK
            run: ./gradlew assembleDebug
          - name: MobSF static scan
            run: |
              docker run --rm -v "$PWD:/src" opensecurity/mobile-security-framework-mobsf \
                python3 scan.py /src/android/app/build/outputs/apk/debug/app-debug.apk

    Reverse Engineering Resistance: Honest Expectations

    Obfuscation (ProGuard/R8 on Android, Swift symbol stripping on iOS) raises the cost of static analysis. It does not stop a determined attacker. We use R8 full mode with custom dictionaries on Android release builds, strip debug symbols on iOS, and move business logic that must stay secret to the server.

    Frida hooking defeats most client-side checks within hours. That is why we do not store HMAC signing secrets in the binary—even obfuscated. If your payment gateway requires a client-side signature, use a server-mediated signing endpoint with per-transaction nonces.

    Runtime Application Self-Protection (RASP) SDKs from vendors like Guardsquare or Promon add tamper detection and debugger blocking. They cost ₹3–8 lakh annually for mid-size apps and complicate debugging. We recommend them when threat models include organised fraud rings targeting a specific APK—not for every MVP.

    Reference Architecture

    The diagram below shows the layered model we implement on most production apps. Arrows indicate trust boundaries, not data flow alone. Every boundary crossing is an opportunity to validate, rate-limit, or reject.

    ┌─────────────────────────────────────────────────────────────────────────┐
    │                        MOBILE CLIENT (UNTRUSTED)                          │
    ├─────────────────────────────────────────────────────────────────────────┤
    │  UI Layer          │  Auth Module (PKCE)    │  Secure Storage            │
    │  (no secrets)      │  Biometric gate        │  Keystore / Keychain       │
    ├────────────────────┴────────────────────────┴───────────────────────────┤
    │  Transport: TLS 1.3 + Certificate Pinning (SPKI) + Request signing      │
    │  Integrity: Play Integrity / App Attest (risk signal, not sole gate)    │
    └───────────────────────────────────┬─────────────────────────────────────┘
                                        │ HTTPS (pinned)
                                        ▼
    ┌─────────────────────────────────────────────────────────────────────────┐
    │                         EDGE / API GATEWAY                               │
    ├─────────────────────────────────────────────────────────────────────────┤
    │  WAF + Rate Limiting  │  mTLS (B2B)  │  JWT validation  │  Geo rules    │
    └───────────────────────────────────┬─────────────────────────────────────┘
                                        ▼
    ┌─────────────────────────────────────────────────────────────────────────┐
    │                      APPLICATION SERVICES                                │
    ├─────────────────────────────────────────────────────────────────────────┤
    │  OAuth Server        │  Business Logic     │  Risk Engine               │
    │  (rotating refresh)  │  (authz checks)     │  (step-up triggers)       │
    ├──────────────────────┴─────────────────────┴────────────────────────────┤
    │  Audit Log (immutable)  │  Idempotency Store  │  Session Revocation       │
    └───────────────────────────────────┬─────────────────────────────────────┘
                                        ▼
    ┌─────────────────────────────────────────────────────────────────────────┐
    │  DATA LAYER: Encrypted at rest (AES-256) │  Secrets Manager │  HSM/KMS  │
    └─────────────────────────────────────────────────────────────────────────┘
    

    Figure 1: Mobile app security architecture with explicit trust boundaries between client, edge, application, and data layers.

    Token Storage and Attestation: Comparison

    Approach Security posture Operational cost Failure modes
    AsyncStorage / plain prefs Low — trivial extraction via backup or root Minimal dev effort Token theft, account takeover at scale
    EncryptedSharedPreferences / Keychain Medium-high — hardware-backed on modern devices Low — platform APIs, ~2–3 dev days Older OEM Keystore bugs; no protection if device unlocked
    Biometric-gated Keychain access High for local access control Medium — UX friction on every cold start Family device sharing; fallback PIN path must be secure
    Play Integrity + server-bound refresh High for fraud reduction High — backend session infra, attestation latency Enterprise sideloads; degraded networks in tier-2 cities
    Best for Consumer content apps: encrypted storage + short TTL. Fintech/health: attestation signals + rotating refresh + step-up auth on sensitive actions.
    Pinakinvox recommendation Ship encrypted Keystore/Keychain storage and PKCE from MVP. Add pinning and attestation before handling real money or PHI. Never defer refresh token rotation—it is cheaper to build early than to retrofit under incident pressure.

    Choosing the Right Approach

    Security architecture is not one-size-fits-all. Sequence controls based on data sensitivity, regulatory exposure, and release velocity.

    If you are pre-revenue MVP with no payment or health data, implement MASVS Level 1 basics: HTTPS, encrypted token storage, no secrets in the bundle, dependency scanning in CI, and server-side authorization on every mutating endpoint. Skip RASP and attestation until you have users worth attacking. Our MVP development engagements include a security baseline checklist so you do not rebuild auth in month nine.

    If you process UPI, card, or wallet transactions, add certificate pinning, refresh token rotation, Play Integrity/App Attest signals, and a server-side risk engine with step-up OTP for anomalous transfers. Align with RBI's digital payment security controls and PCI-DSS mobile guidance if card data touches your infrastructure—even briefly.

    If you handle clinical or insurance data, treat the app as a thin client. Minimise local PHI retention, encrypt at rest with rotating keys, log access for audit, and design offline sync with conflict resolution that never stores unencrypted records. Partner with a team experienced in healthcare application development that understands CDSCO and clinical data handling—not just HIPAA checklists copied from US templates.

    If your codebase was generated or heavily assisted by AI tools, run a dedicated security audit before production. AI-generated React Native apps routinely ship with hardcoded API keys, permissive CORS, and Firestore rules that allow public reads. Our AI app security audit service targets exactly these failure patterns.

    If you are scaling across Delhi NCR with a distributed team, centralise security decisions in architecture review—not in each sprint's ad hoc fixes. A Gurgaon-based app development partner that shares your timezone can run weekly threat modelling sessions without the async lag that lets insecure shortcuts merge on Friday evenings.

    Real-World Example: B2B Field Operations App

    We recently hardened a B2B logistics app used by warehouse staff across North India—roughly 12,000 monthly active users on a mix of Samsung A-series and older Xiaomi devices. The original architecture cached JWTs with thirty-day expiry in SQLite and synced order data over unpinned HTTPS because "the CDN certificate changes too often."

    After restructuring, access tokens expired in ten minutes, refresh tokens rotated on every use and lived in EncryptedSharedPreferences, and the API rejected requests from clients failing Play Integrity on routes that modified inventory valuations. Offline sync still worked: cached orders used SQLCipher with keys derived from the user's session, wiped on logout. Penetration test findings dropped from eleven critical/high to two medium (both social engineering, not architecture). Crash rates increased by 0.3% due to pinning misconfiguration on one OEM—we fixed it with a remote config pin fallback. Total engineering effort: approximately eight person-weeks, billed in the ₹6–9 lakh range including external pentest.

    Frequently Asked Questions

    What is the difference between mobile app security architecture and a security checklist?
    A checklist tells you to "use HTTPS" and "encrypt data." An architecture defines how components interact: where tokens live, what the API trusts, how sessions revoke, and what happens when a device is compromised. Checklists catch omissions; architecture prevents contradictions—like pinning certificates while storing refresh tokens in plaintext.
    How does OWASP mobile security guidance apply in 2026?
    OWASP MASVS and the Mobile Application Security Testing Guide (MASTG) remain the reference framework. MASVS Level 1 is appropriate for most consumer apps. Level 2 adds anti-tampering and advanced authentication for fintech and health. We map each control to CI gates and pentest scopes so verification is repeatable, not a one-time audit PDF that gathers dust.
    Is certificate pinning worth the operational risk?
    For apps handling money, credentials, or regulated data: yes, with SPKI pinning and a documented rotation runbook. For pure content apps with no authenticated API: often no—the outage risk from certificate expiry outweighs the threat model. Pinning is not a substitute for proper token handling; it only protects the transport channel.
    Can root detection or jailbreak blocking make my app secure?
    No. Root detection is a risk signal, not a control. Sophisticated attackers bypass it; legitimate users on rooted devices get blocked and complain. We use integrity APIs and server-side risk scoring instead of hard exits, applying stricter rules to high-value actions rather than denying app access entirely.
    How much does implementing proper mobile app security architecture cost in India?
    For a mid-complexity React Native or Flutter app, expect ₹4–8 lakh for initial architecture hardening (secure storage, PKCE, pinning, CI gates) over four to six weeks. Adding attestation, RASP, and external penetration testing pushes the range to ₹10–18 lakh. Ongoing costs include annual pentests (₹2–5 lakh), RASP licensing if used (₹3–8 lakh/year), and roughly 10–15% additional backend engineering for session management. MVPs can start at ₹1.5–3 lakh for MASVS Level 1 basics if built correctly from day one.
    Do Delhi NCR companies face different mobile security requirements than global startups?
    Regulatory context differs. India's DPDP Act imposes consent and data minimisation obligations. RBI guidelines apply to payment apps. Device diversity is higher—budget Android hardware with inconsistent Keystore implementations—and network reliability varies between Gurgaon fibre offices and field sites on 4G edge. Architecture must tolerate latency and intermittent connectivity without falling back to insecure caching. Teams in Delhi NCR benefit from local security review cycles and pentest vendors familiar with Indian compliance frameworks.
    Should we use JWTs or opaque server-side sessions for mobile?
    We prefer short-lived JWTs for access tokens combined with opaque, rotating refresh tokens stored server-side as hashes. Pure stateless JWTs without rotation make revocation slow—problematic when a phone is stolen between Connaught Place and the Metro. If you use JWTs, keep TTL under fifteen minutes and maintain a revocation list or token version counter for critical events.
    How do we secure AI-generated or low-code mobile apps?
    Treat them as untrusted codebases until reviewed. AI tools routinely embed API keys, disable SSL verification in development configs that ship to production, and generate permissive backend rules. Run MobSF and dependency-check in CI, manually inspect networking code, and assume secrets exist in the bundle until proven otherwise. A focused security audit before launch costs far less than incident response after credentials leak.

    Final Recommendation

    We do not recommend chasing perfect on-device security—it does not exist. We recommend a mobile app security architecture that limits blast radius: short-lived tokens in hardware-backed storage, pinned transport for sensitive apps, server-side authorization on every mutation, rotating refresh with theft detection, and CI gates aligned with OWASP MASVS. Add attestation and RASP when your threat model includes targeted fraud, not when you are still validating product-market fit.

    The Gurgaon fintech team we opened with could have avoided a rushed six-week retrofit by spending two weeks on architecture during MVP. That is the sequencing we advocate: security primitives first, features second, obfuscation and RASP last. Indian users on mixed networks and mixed devices will not tolerate friction that does not protect them—but they will tolerate a brief biometric prompt before a ₹50,000 transfer if the app has earned trust through consistent, explainable security behaviour.

    If you are planning a new build or auditing an existing app before a compliance review, start with a threat model workshop and a MASVS gap assessment. Talk to our mobile development team or reach out directly—we will tell you what to fix now, what to schedule for the next release, and what is not worth your budget.

    Need a technical partner?

    We design and build production systems. If you are working through the architecture decisions covered here, our engineering team can help you scope, validate, and execute.

    Production-verified.

    Every architectural pattern published here has been deployed in real client systems — not demo environments.

    Written by engineers.

    Our architecture articles are written by the engineers who built the systems — not by marketing teams.

    Looking for a technical partner to architect your next system?

    Our engineering team specialises in high-complexity architecture design, from mobile backends to distributed cloud systems. Let's talk about building for scale.

    Partner with

    aws
    partnernetwork