Building a healthcare mobile app is one of the most technically and legally demanding things you can do as a mobile developer. HIPAA violations carry fines up to $1.9 million per violation category per year — and ignorance is not a defence. I've spent the last several years building HealthTech apps in React Native, and this is the practical guide I wish I'd had at the start.
Disclaimer: This article covers technical implementation patterns. It does not constitute legal advice. Always engage a qualified HIPAA compliance officer and legal counsel for your specific application.
What HIPAA Means for Mobile Developers
HIPAA's Security Rule applies to Protected Health Information (PHI) — any data that can identify an individual and relates to their health status, healthcare provision, or payment. On a mobile device, PHI might live in network responses, local databases, log files, clipboard content, or screenshots. The Security Rule requires you to protect PHI at rest, in transit, and during disposal — and to maintain an audit trail of who accessed what and when.
Data Encryption in Transit
All network communication must use TLS 1.2 or higher. In React Native, fetch and axios use the platform's native HTTP stack, which enforces TLS by default. However, you must also pin your certificate to prevent man-in-the-middle attacks on compromised networks:
// Using react-native-ssl-pinning
import { fetch } from 'react-native-ssl-pinning';
const response = await fetch('https://api.myhealthapp.com/patient', {
method: 'GET',
sslPinning: {
certs: ['api_cert_sha256_hash'], // SHA256 hash of your server cert
},
headers: { Authorization: `Bearer ${token}` },
});
On Android, also configure Network Security Config to prevent cleartext HTTP traffic entirely:
<!-- android/app/src/main/res/xml/network_security_config.xml -->
<network-security-config>
<base-config cleartextTrafficPermitted="false">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
</network-security-config>
Encryption at Rest
Any PHI stored locally must be encrypted. AsyncStorage is plaintext — never store PHI there. Use react-native-mmkv with encryption enabled, or an encrypted SQLite solution with SQLCipher:
import { MMKV } from 'react-native-mmkv';
// Fetch the encryption key from Keychain (covered below)
const encryptionKey = await getKeychainEncryptionKey();
export const secureStorage = new MMKV({
id: 'phi-storage',
encryptionKey, // AES-256 encryption
});
// SQLite with SQLCipher
import { open } from 'react-native-quick-sqlite';
const db = open({
name: 'health.db',
encryptionKey: encryptionKey, // SQLCipher AES-256
});
Secure Storage with Keychain and Keystore
Encryption keys and auth tokens must never live in AsyncStorage. Use the platform's hardware-backed secure enclave — iOS Keychain and Android Keystore — via react-native-keychain:
import * as Keychain from 'react-native-keychain';
// Store a credential securely
await Keychain.setGenericPassword('user', authToken, {
service: 'com.myhealthapp.auth',
accessible: Keychain.ACCESSIBLE.WHEN_UNLOCKED_THIS_DEVICE_ONLY,
securityLevel: Keychain.SECURITY_LEVEL.SECURE_HARDWARE,
});
// Retrieve a credential
const credentials = await Keychain.getGenericPassword({
service: 'com.myhealthapp.auth',
});
// Revoke on logout
await Keychain.resetGenericPassword({ service: 'com.myhealthapp.auth' });
WHEN_UNLOCKED_THIS_DEVICE_ONLY means the item is inaccessible if the device is locked and cannot migrate to a new device via iCloud backup — both critical for PHI.
Biometric Authentication
HIPAA requires access controls. Biometric authentication (Face ID, Touch ID, fingerprint) satisfies the "unique user identification" requirement and provides a strong second factor for app access:
import * as LocalAuthentication from 'expo-local-authentication';
export async function authenticateUser() {
const hasHardware = await LocalAuthentication.hasHardwareAsync();
const isEnrolled = await LocalAuthentication.isEnrolledAsync();
if (!hasHardware || !isEnrolled) {
return promptForPIN(); // fall back to PIN
}
const result = await LocalAuthentication.authenticateAsync({
promptMessage: 'Verify your identity to access patient data',
fallbackLabel: 'Use PIN',
disableDeviceFallback: false,
});
return result.success;
}
Audit Logging
The HIPAA Security Rule requires activity logs for all PHI access. Every read, write, or delete of patient data must be recorded with a timestamp, user ID, action type, and the resource accessed:
const AuditAction = {
VIEW: 'VIEW',
EDIT: 'EDIT',
DELETE: 'DELETE',
EXPORT: 'EXPORT',
};
export async function logAuditEvent(action, resourceType, resourceId) {
const entry = {
timestamp: new Date().toISOString(),
userId: authStore.userId,
action,
resourceType,
resourceId,
deviceId: await getDeviceId(),
};
// Write locally first, then sync to server
auditQueue.push(entry);
await syncAuditQueue();
}
// Usage
await logAuditEvent(AuditAction.VIEW, 'PatientRecord', patientId);
PHI Minimisation
Only request and store PHI that is necessary for the app's function. Practical steps:
- Disable screenshots on screens displaying PHI using
react-native-prevent-screenshotor Android'sFLAG_SECURE. - Clear the clipboard after any copy action involving PHI.
- Exclude PHI-bearing directories from iCloud and Android auto-backup.
- Set aggressive session timeouts — auto-lock after 5–15 minutes of inactivity.
<!-- Exclude from Android backup in AndroidManifest.xml -->
<application
android:allowBackup="false"
android:fullBackupContent="@xml/backup_rules"
>
BAA Requirements
Every third-party service that processes PHI on your behalf must sign a Business Associate Agreement (BAA). This includes your cloud hosting provider, analytics platform, crash reporting service, and push notification provider. AWS, Google Cloud, Azure, and Firebase all offer BAA-eligible tiers. Standard free tiers of services like Sentry or Mixpanel typically do not include BAAs — you cannot send PHI to those endpoints without a signed agreement.
Testing for Compliance
- Run OWASP Mobile Security Testing Guide (MSTG) checks against your app binary.
- Use Frida or Objection to verify that Keychain items are not accessible on a jailbroken or rooted device without authentication.
- Verify with a network proxy (Charles, mitmproxy) that certificate pinning is enforced and no cleartext traffic is sent.
- Review crash reports and analytics events to confirm no PHI appears in log output.
- Conduct a penetration test before launch — many healthcare clients require a signed pen-test report as a condition of deployment.
HIPAA compliance is not a feature you add at the end of a project. It's an architectural decision that affects your data model, third-party dependencies, CI/CD pipeline, and release process. The teams I've seen handle it best are the ones who embed a compliance checklist into their definition of done from day one — treating security as a first-class concern, not an afterthought.

