skills/hipaa-compliance/SKILL.md
Ensure HIPAA compliance when handling PHI (Protected Health Information). Use when writing code that accesses user health data, check-ins, journal entries, or any sensitive information. Activates for audit logging, data access, security events, and compliance questions.
npx skillsauth add curiositech/windags-skills hipaa-complianceInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill helps you maintain HIPAA compliance when developing features that handle Protected Health Information (PHI).
Is this user data?
├─ NO → No HIPAA requirements, proceed normally
└─ YES → Is it health-related or personally identifiable?
├─ NO (aggregated analytics, page views) → No audit logging needed
└─ YES → PHI detected, proceed to access type:
├─ READ access → Use logPHIAccess() + authentication check
├─ WRITE/UPDATE → Use logPHIModification() + change tracking
├─ DELETE → Use logPHIModification() + soft delete preferred
└─ EXPORT → Use logAdminAction() + encryption required
| Data Type | PHI Status | Decision Rule | |-----------|------------|---------------| | Check-in mood/cravings | PHI | Always audit - health condition | | Journal entries | PHI | Always audit - personal health notes | | Chat messages | PHI | Always audit - health discussions | | User profile (name/email) | PHI | Audit modifications only | | Sobriety date | PHI | Always audit - health milestone | | Usage patterns (timing) | Depends | If linkable to individual → PHI | | Error logs with userIds | PHI | If contains health context → PHI |
Is this a high-frequency operation (>100/min)?
├─ NO → Use synchronous audit logging
└─ YES → Performance consideration needed:
├─ Critical PHI access → Async logging with failure retry
├─ Bulk operations → Batch logging every 100 records
└─ Analytics tracking → Sample logging (1 in 10)
Symptoms: Missing entries in audit trail, incomplete access records
Detection: if (auditLog.count < actualOperations.count)
Fix: Add try-catch around all PHI operations, implement audit middleware
Symptoms: Actual health data appears in logs or error messages
Detection: if (logEntry.includes(personalHealthInfo))
Fix: Use sanitization middleware, audit log reviews, content redaction
Symptoms: Users accessing data without recent authentication
Detection: if (timeSinceLastAuth > 15_MINUTES && accessingPHI)
Fix: Force re-authentication for PHI access, implement session timeouts
Symptoms: Emergency access used for non-emergencies
Detection: if (breakGlassUsage.frequency > normalPatterns)
Fix: Require written justification, automated compliance officer alerts
Symptoms: PHI stored in plaintext, backup files unencrypted
Detection: if (database.encryption === false && containsPHI)
Fix: Enable database encryption, encrypt export files, audit storage
Context: User wants to view 6 months of chat history (1000+ messages).
Step 1 - PHI Classification:
// Decision: Chat messages contain health discussions → PHI
const messageType = 'chat';
const isPHI = true; // Health-related conversations
Step 2 - Performance vs Compliance Trade-off:
// OPTION A: Real-time logging (high latency)
messages.forEach(async (msg) => {
await logPHIAccess(userId, 'chat', msg.id, AuditAction.PHI_VIEW);
});
// OPTION B: Batch logging (chosen solution)
const batchSize = 100;
const messageChunks = chunk(messages, batchSize);
for (const chunk of messageChunks) {
await logBatchPHIAccess(
userId,
'chat_bulk',
chunk.map(m => m.id),
AuditAction.PHI_VIEW,
{ messageCount: chunk.length }
);
}
Expert vs Novice:
Step 3 - Implementation:
export async function getChatHistory(userId: string) {
const session = await requireAuth();
// Performance: Paginated fetch
const messages = await db.messages.findMany({
where: { userId },
orderBy: { createdAt: 'desc' },
take: 100 // First page only
});
// Compliance: Batch audit log
await logBatchPHIAccess(
session.userId,
'chat_history',
messages.map(m => m.id),
AuditAction.PHI_VIEW,
{
pageSize: messages.length,
totalRequested: '6_months',
loadTime: performance.now()
}
);
return messages;
}
Before deploying any PHI-related feature:
Do NOT use this skill for:
When to delegate:
tools
Building resilient distributed systems with circuit breakers, retries with full-jitter exponential backoff, retry budgets (per-request 3-attempt + per-client 10% ratio per Google SRE), deadline propagation, and the cascading-failure math (4 layers × 3 retries = 64x amplification). Grounded in Resilience4j, Microsoft Cloud Patterns, AWS Architecture Blog (Marc Brooker), and Google SRE Book.
testing
Designing HTTP cache headers that work correctly across browsers, CDNs, and shared proxies — `Cache-Control` directives per RFC 9111, `stale-while-revalidate` and `stale-if-error` per RFC 5861, the Vary header for varying responses, and surrogate keys for tag-based purging. Grounded in IETF RFCs and Cloudflare/Fastly docs.
development
Use when designing or fixing a Content Security Policy on a real site, choosing between nonce-based and hash-based CSP, adding strict-dynamic, debugging "Refused to execute inline script" errors, deploying CSP in report-only mode first, configuring report-to / report-uri, or auditing an existing policy for unsafe-inline / unsafe-eval / wildcards. Triggers: "CSP blocks legitimate inline script", strict-dynamic, nonce-{RANDOM}, sha256-{HASH}, object-src none, base-uri none, frame-ancestors, Trusted Types, X-Content-Security-Policy obsolete, report-only vs enforced. NOT for general HTTP security headers (HSTS, COOP/COEP), Trusted Types deep dive, CORS configuration, or building a WAF.
tools
Choosing and operating an HTTP API versioning strategy that doesn't break clients — Stripe's date-based pinned versions, the Deprecation/Sunset header pair (RFC 9745 + RFC 8594), URI vs header vs media-type approaches, and the version-transformer pattern. Grounded in Stripe's published architecture and IETF RFCs.