Skip to content

Security: dihannahdi/diagnosai

Security

SECURITY.md

Security Guidelines for DiagnosAI

Overview

This document outlines security best practices and guidelines for developing and deploying DiagnosAI. As a medical application handling sensitive patient data, security is paramount.

Environment Variables & Secrets Management

⚠️ Critical Rules

  1. NEVER commit secrets to version control

    • API keys, database passwords, JWT secrets
    • Supabase service role keys
    • Any production credentials
  2. Use environment variables for all secrets

    # ✅ CORRECT
    const apiKey = process.env.OPENAI_API_KEY;
    
    # ❌ WRONG - Never hardcode
    const apiKey = 'sk-1234567890abcdef';
  3. Separate development and production credentials

    • Use different Supabase projects for dev/staging/prod
    • Rotate keys regularly
    • Never use production keys in development

Required Environment Variables

Store these in .env.local (never commit this file):

# Supabase - Different keys for dev/prod
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGc...  # Public, client-side
SUPABASE_SERVICE_ROLE_KEY=eyJhbGc...      # SECRET - server only!
DATABASE_URL=postgresql://postgres:[password]@...

# AI Providers - Keep private
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...
GROQ_API_KEY=gsk_...
HUGGINGFACE_TOKEN=hf_...

# Application
NEXT_PUBLIC_APP_URL=http://localhost:3000

Environment Variable Security Levels

Variable Exposure Usage Security Level
NEXT_PUBLIC_* Public (embedded in client bundle) Browser-safe data Low
*_ANON_KEY Public (but restricted by RLS) Client-side DB access Medium
*_SERVICE_ROLE_KEY Private (server-only) Admin operations, bypasses RLS CRITICAL
DATABASE_URL Private (server-only) Direct DB connection CRITICAL
*_API_KEY Private (server-only) Third-party services High

Supabase Security Configuration

Row Level Security (RLS)

All tables with user data MUST have RLS enabled:

-- Enable RLS
ALTER TABLE diagnostic_sessions ENABLE ROW LEVEL SECURITY;

-- Create policy
CREATE POLICY "Users can only see their own sessions"
ON diagnostic_sessions FOR SELECT
USING (auth.uid() = doctor_id);

Tables WITHOUT RLS (public knowledge only):

  • medical_diseases - Public medical information
  • medical_symptoms - Public symptom index
  • medical_qa - Public Q&A knowledge base

These are protected by:

  • Insert/Update/Delete restricted to service role
  • No PHI (Protected Health Information)
  • Read-only for application users

Supabase Service Role Key Protection

The SUPABASE_SERVICE_ROLE_KEY has superuser privileges and bypasses all RLS policies.

Rules:

  1. ✅ Use ONLY in server-side code (/app/api/ routes)
  2. ✅ Use for ETL scripts and admin operations
  3. ❌ NEVER send to client-side code
  4. ❌ NEVER log or display in error messages
  5. ❌ NEVER commit to GitHub

Usage Example:

// ✅ CORRECT - Server-side API route
// app/api/sessions/route.ts
import { createServerClient } from '@/lib/supabase/client';

export async function POST(req: Request) {
  const supabase = createServerClient(); // Uses service role
  // ... admin operations
}

// ❌ WRONG - Client component
// components/my-component.tsx
'use client';
const supabase = createClient(url, SERVICE_ROLE_KEY); // EXPOSED!

Patient Health Information (PHI) Protection

HIPAA Compliance Considerations

DiagnosAI handles sensitive medical data. Follow these guidelines:

  1. Data Minimization

    • Only collect necessary patient information
    • Don't store unnecessary identifiable data
    • Use patient IDs instead of names where possible
  2. Encryption

    • Data in transit: HTTPS/TLS (enforced by Supabase)
    • Data at rest: PostgreSQL encryption (Supabase default)
    • Consider column-level encryption for extra sensitive data
  3. Audit Trails

    • All patient data access logged in session_audit_log
    • Append-only audit table (no modifications)
    • Include actor, timestamp, IP address
  4. Access Control

    • RLS policies enforce data isolation
    • Doctor can only access their own sessions
    • Admin access logged and monitored

Audit Log Immutability

The audit log is tamper-proof using database triggers:

-- Prevents modification/deletion of audit records
CREATE TRIGGER audit_log_immutable
  BEFORE UPDATE OR DELETE ON session_audit_log
  FOR EACH ROW
  EXECUTE FUNCTION prevent_audit_log_modification();

This ensures medicolegal compliance and evidence integrity.

API Security Best Practices

1. Input Validation

Always validate and sanitize user input:

import { z } from 'zod';

const sessionSchema = z.object({
  patient_name: z.string().min(1).max(100),
  patient_age: z.number().int().min(0).max(150),
  chief_complaint: z.string().max(500)
});

// Validate before database insertion
const validated = sessionSchema.parse(req.body);

2. Rate Limiting

Protect API endpoints from abuse:

// Example rate limiting (implement in middleware)
const rateLimit = {
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100 // limit each IP to 100 requests per window
};

3. Error Handling

Never expose sensitive information in error messages:

// ❌ WRONG - Exposes internal details
throw new Error(`Database connection failed: ${dbPassword}`);

// ✅ CORRECT - Generic message, log details server-side
console.error('DB connection failed:', error);
throw new Error('Internal server error');

4. CORS Configuration

Restrict API access to known origins:

// next.config.ts
module.exports = {
  async headers() {
    return [
      {
        source: '/api/:path*',
        headers: [
          { key: 'Access-Control-Allow-Origin', value: 'https://yourdomain.com' },
          { key: 'Access-Control-Allow-Methods', value: 'GET,POST,PUT,DELETE' }
        ]
      }
    ];
  }
};

Development vs Production

Development Environment

# .env.local (development)
NEXT_PUBLIC_SUPABASE_URL=https://dev-project.supabase.co
SUPABASE_SERVICE_ROLE_KEY=dev_key_xxx
OPENAI_API_KEY=test_key_xxx

Development Practices:

  • Use separate Supabase project for dev
  • Use test API keys with spending limits
  • Never test with real patient data
  • Reset database frequently

Production Environment

# Vercel environment variables (production)
NEXT_PUBLIC_SUPABASE_URL=https://prod-project.supabase.co
SUPABASE_SERVICE_ROLE_KEY=[stored securely in Vercel]
OPENAI_API_KEY=[stored securely in Vercel]

Production Practices:

  • Use Vercel's encrypted environment variables
  • Enable Supabase production mode
  • Set up monitoring and alerting
  • Regular security audits
  • Backup strategy for patient data

Secret Rotation Schedule

Rotate secrets regularly to minimize breach impact:

Secret Type Rotation Frequency Action
Supabase Keys Every 90 days Generate new keys in dashboard
API Keys Every 90 days Rotate with providers
Database Passwords Every 180 days Update via Supabase
JWT Secrets Every 365 days Update auth configuration

Security Checklist

Before deploying to production:

  • All secrets stored in environment variables
  • No hardcoded credentials in code
  • .env.local in .gitignore
  • RLS enabled on all tables with user data
  • Audit logging configured and tested
  • HTTPS/TLS enforced on all endpoints
  • Input validation on all API routes
  • Error messages don't leak sensitive info
  • Rate limiting configured
  • CORS properly restricted
  • Separate dev/prod environments
  • Backup and disaster recovery plan
  • Security monitoring and alerting
  • Code review for security issues
  • Dependency vulnerability scan

Incident Response

If a security breach occurs:

  1. Immediate Actions

    • Rotate all compromised credentials immediately
    • Revoke exposed API keys
    • Lock down affected systems
    • Document timeline and impact
  2. Investigation

    • Review audit logs for unauthorized access
    • Identify scope of data breach
    • Determine attack vector
  3. Remediation

    • Patch vulnerabilities
    • Update security policies
    • Notify affected users (if required by law)
    • Post-mortem and lessons learned
  4. Contact

    • Report to Supabase support
    • Contact relevant authorities if PHI exposed
    • Inform affected healthcare providers

Reporting Security Issues

If you discover a security vulnerability:

  1. DO NOT open a public GitHub issue
  2. Email security concerns to: [your-security-email]
  3. Include:
    • Description of vulnerability
    • Steps to reproduce
    • Potential impact
    • Suggested fix (if known)

Resources


Last Updated: January 2026

Version: 1.0

Review Schedule: Quarterly security audits recommended

There aren't any published security advisories