Modèles de Conformité PHI/PII pour la Santé
Modèles pour protéger les données des patients, des cliniciens et les données financières dans les applications de santé. Applicable à HIPAA (États-Unis), DISHA (Inde), RGPD (UE) et à la protection générale des données de santé.
Quand Utiliser
- Lors de la construction de toute fonctionnalité qui touche aux dossiers patients
- Lors de la mise en œuvre du contrôle d'accès ou de l'authentification pour les systèmes cliniques
- Lors de la conception de schémas de base de données pour les données de santé
- Lors de la construction d'API qui renvoient des données patients ou cliniciens
- Lors de la mise en œuvre de pistes d'audit ou de journalisation
- Lors de la révision de code pour des vulnérabilités d'exposition des données
- Lors de la configuration de la Sécurité au Niveau des Lignes (RLS) pour les systèmes multi-établissements de santé
Comment Ça Marche
La protection des données de santé fonctionne sur trois couches : classification (ce qui est sensible), contrôle d'accès (qui peut le voir) et audit (qui l'a vu).
Classification des Données
PHI (Protected Health Information) — toute donnée pouvant identifier un patient ET liée à sa santé : nom du patient, date de naissance, adresse, téléphone, email, numéros d'identification nationaux (SSN, Aadhaar, NHS), numéros de dossier médical, diagnostics, médicaments, résultats de laboratoire, imagerie, détails de police d'assurance et de réclamation, dossiers de rendez-vous et d'admission, ou toute combinaison de ce qui précède.
PII (Données non sensibles du patient) dans les systèmes de santé : informations personnelles des cliniciens/personnel, structures de frais et montants de paiement des médecins, salaires et coordonnées bancaires des employés, informations de paiement des fournisseurs.
Contrôle d'Accès : Sécurité au Niveau des Lignes
ALTER TABLE patients ENABLE ROW LEVEL SECURITY;
-- Limiter l'accès par établissement
CREATE POLICY "staff_read_own_facility"
ON patients FOR SELECT TO authenticated
USING (facility_id IN (
SELECT facility_id FROM staff_assignments
WHERE user_id = auth.uid() AND role IN ('doctor','nurse','lab_tech','admin')
));
-- Journal d'audit : insertion uniquement (inviolable)
CREATE POLICY "audit_insert_only" ON audit_log FOR INSERT
TO authenticated WITH CHECK (user_id = auth.uid());
CREATE POLICY "audit_no_modify" ON audit_log FOR UPDATE USING (false);
CREATE POLICY "audit_no_delete" ON audit_log FOR DELETE USING (false);
Piste d'Audit
Chaque accès ou modification de PHI doit être journalisé :
interface AuditEntry {
timestamp: string;
user_id: string;
patient_id: string;
action: 'create' | 'read' | 'update' | 'delete' | 'print' | 'export';
resource_type: string;
resource_id: string;
changes?: { before: object; after: object };
ip_address: string;
session_id: string;
}
Vecteurs de Fuite Courants
Messages d'erreur : N'incluez jamais de données identifiant le patient dans les messages d'erreur renvoyés au client. Consignez les détails côté serveur uniquement.
Sortie console : Ne journalisez jamais les objets patients complets. Utilisez des identifiants internes opaques (UUID) — pas de numéros de dossier médical, d'identifiants nationaux ou de noms.
Paramètres d'URL : Ne mettez jamais de données identifiant le patient dans les chaînes de requête ou les segments de chemin qui pourraient apparaître dans les journaux ou l'historique du navigateur. Utilisez uniquement des UUID opaques.
Stockage navigateur : Ne stockez jamais de PHI dans localStorage ou sessionStorage. Conservez les PHI en mémoire uniquement, récupérez-les à la demande.
Clés de rôle de service : N'utilisez jamais la clé service_role dans le code côté client. Utilisez toujours la clé anon/publiable et laissez le RLS appliquer l'accès.
Journaux et surveillance : Ne journalisez jamais les dossiers patients complets. Utilisez uniquement des identifiants opaques (pas de numéros de dossier médical). Nettoyez les traces de pile avant de les envoyer aux services de suivi des erreurs.
Balisage du Schéma de Base de Données
Marquez les colonnes PHI/PII au niveau du schéma :
COMMENT ON COLUMN patients.name IS 'PHI: patient_name';
COMMENT ON COLUMN patients.dob IS 'PHI: date_of_birth';
COMMENT ON COLUMN patients.aadhaar IS 'PHI: national_id';
COMMENT ON COLUMN doctor_payouts.amount IS 'PII: financial';
Liste de Vérification Avant Déploiement
Avant chaque déploiement :
- Pas de PHI dans les messages d'erreur ou les traces de pile
- Pas de PHI dans console.log/console.error
- Pas de PHI dans les paramètres d'URL
- Pas de PHI dans le stockage navigateur
- Pas de clé service_role dans le code client
- RLS activé sur toutes les tables PHI/PII
- Piste d'audit pour toutes les modifications de données
- Délai d'expiration de session configuré
- Authentification API sur tous les points de terminaison PHI
- Isolement des données entre établissements vérifié
Exemples
Exemple 1 : Gestion d'Erreur Sûre vs Non Sûre
// MAUVAIS — fuit des PHI dans l'erreur
throw new Error(`Patient ${patient.name} introuvable dans ${patient.facility}`);
// BON — erreur générique, détails journalisés côté serveur avec identifiants opaques uniquement
logger.error('Échec de la recherche patient', { recordId: patient.id, facilityId });
throw new Error('Enregistrement introuvable');
Exemple 2 : Politique RLS pour l'Isolement Multi-Établissement
-- Un médecin de l'établissement A ne peut pas voir les patients de l'établissement B
CREATE POLICY "facility_isolation"
ON patients FOR SELECT TO authenticated
USING (facility_id IN (
SELECT facility_id FROM staff_assignments WHERE user_id = auth.uid()
));
-- Test : connectez-vous en tant que médecin-établissement-a, interrogez les patients de l'établissement-b
-- Résultat attendu : 0 lignes retournées
Exemple 3 : Journalisation Sûre
// MAUVAIS — journalise des données identifiables du patient
console.log('Traitement du patient :', patient);
// BON — journalise uniquement l'identifiant interne opaque
console.log('Traitement de l\'enregistrement :', patient.id);
// Remarque : même patient.id doit être un UUID opaque, pas un numéro de dossier médical