Agent Skills: Abridge Security Basics

|

UncategorizedID: jeremylongshore/claude-code-plugins-plus-skills/abridge-security-basics

Install this agent skill to your local

pnpm dlx add-skill https://github.com/jeremylongshore/claude-code-plugins-plus-skills/tree/HEAD/plugins/saas-packs/abridge-pack/skills/abridge-security-basics

Skill Files

Browse the full folder contents for abridge-security-basics.

Download Skill

Loading file tree…

plugins/saas-packs/abridge-pack/skills/abridge-security-basics/SKILL.md

Skill Metadata

Name
abridge-security-basics
Description
|

Abridge Security Basics

Overview

HIPAA-compliant security configuration for Abridge clinical AI integrations. Abridge handles PHI (Protected Health Information) — security is not optional. This skill covers encryption, access control, audit logging, and BAA requirements.

HIPAA Security Checklist

| Requirement | Implementation | Status | |-------------|---------------|--------| | Encryption in transit | TLS 1.3 enforced | Required | | Encryption at rest | AES-256 for stored PHI | Required | | Access control | Role-based with MFA | Required | | Audit logging | All PHI access logged | Required | | BAA signed | Business Associate Agreement | Required | | Minimum necessary | Only access needed PHI | Required | | Breach notification | 60-day notification plan | Required |

Instructions

Step 1: Enforce TLS and Certificate Pinning

// src/security/tls-config.ts
import https from 'https';
import axios from 'axios';

const abridgeHttpsAgent = new https.Agent({
  minVersion: 'TLSv1.3',           // Enforce TLS 1.3 minimum
  rejectUnauthorized: true,         // Never disable cert validation
  // Optional: certificate pinning for Abridge API
  // ca: fs.readFileSync('./certs/abridge-ca.pem'),
});

const secureClient = axios.create({
  baseURL: process.env.ABRIDGE_BASE_URL,
  httpsAgent: abridgeHttpsAgent,
  headers: {
    'Authorization': `Bearer ${process.env.ABRIDGE_CLIENT_SECRET}`,
    'X-Org-Id': process.env.ABRIDGE_ORG_ID!,
    'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
  },
});

Step 2: PHI-Safe Audit Logger

// src/security/audit-logger.ts
interface AuditEntry {
  timestamp: string;
  action: 'create' | 'read' | 'update' | 'delete' | 'access';
  resource_type: 'session' | 'note' | 'transcript' | 'patient_summary';
  resource_id: string;           // Session/note ID (not PHI)
  actor: string;                 // Provider NPI or system ID
  ip_address: string;
  success: boolean;
  // NEVER include: patient name, DOB, SSN, MRN, diagnosis, note content
}

class HipaaAuditLogger {
  private entries: AuditEntry[] = [];

  log(entry: Omit<AuditEntry, 'timestamp'>): void {
    const fullEntry: AuditEntry = {
      ...entry,
      timestamp: new Date().toISOString(),
    };

    // Validate no PHI leaked into audit log
    const serialized = JSON.stringify(fullEntry);
    if (this.containsPhi(serialized)) {
      console.error('CRITICAL: PHI detected in audit entry — entry blocked');
      return;
    }

    this.entries.push(fullEntry);
    // In production: write to HIPAA-compliant log store (CloudWatch, Splunk, etc.)
    console.log(`AUDIT: ${JSON.stringify(fullEntry)}`);
  }

  private containsPhi(text: string): boolean {
    const phiPatterns = [
      /\b\d{3}-\d{2}-\d{4}\b/,        // SSN
      /\b[A-Z]\d{8}\b/,               // MRN pattern
      /\b\d{1,2}\/\d{1,2}\/\d{4}\b/,  // DOB
    ];
    return phiPatterns.some(p => p.test(text));
  }

  getRetentionPolicy(): { minYears: number; note: string } {
    return {
      minYears: 6,
      note: 'HIPAA requires audit logs retained for minimum 6 years',
    };
  }
}

export { HipaaAuditLogger, AuditEntry };

Step 3: Role-Based Access Control

// src/security/rbac.ts
type AbridgeRole = 'clinician' | 'nurse' | 'admin' | 'billing' | 'integration_service';

interface AbridgePermissions {
  canCreateSession: boolean;
  canViewNotes: boolean;
  canViewPatientSummary: boolean;
  canExportData: boolean;
  canManageProviders: boolean;
  canAccessBilling: boolean;
}

const ROLE_PERMISSIONS: Record<AbridgeRole, AbridgePermissions> = {
  clinician: {
    canCreateSession: true, canViewNotes: true, canViewPatientSummary: true,
    canExportData: false, canManageProviders: false, canAccessBilling: false,
  },
  nurse: {
    canCreateSession: true, canViewNotes: true, canViewPatientSummary: true,
    canExportData: false, canManageProviders: false, canAccessBilling: false,
  },
  admin: {
    canCreateSession: false, canViewNotes: false, canViewPatientSummary: false,
    canExportData: true, canManageProviders: true, canAccessBilling: true,
  },
  billing: {
    canCreateSession: false, canViewNotes: false, canViewPatientSummary: false,
    canExportData: false, canManageProviders: false, canAccessBilling: true,
  },
  integration_service: {
    canCreateSession: true, canViewNotes: true, canViewPatientSummary: false,
    canExportData: false, canManageProviders: false, canAccessBilling: false,
  },
};

function checkPermission(role: AbridgeRole, action: keyof AbridgePermissions): boolean {
  return ROLE_PERMISSIONS[role]?.[action] ?? false;
}

Step 4: Secrets Management

// src/security/secrets.ts
// Never hardcode credentials — use environment or secret manager

async function loadAbridgeSecrets(): Promise<Record<string, string>> {
  // Option 1: Environment variables (minimum viable)
  // Option 2: AWS Secrets Manager / GCP Secret Manager (recommended)
  // Option 3: HashiCorp Vault (enterprise)

  // Example: GCP Secret Manager
  const { SecretManagerServiceClient } = await import('@google-cloud/secret-manager');
  const client = new SecretManagerServiceClient();

  const secrets: Record<string, string> = {};
  const secretNames = ['abridge-client-secret', 'abridge-org-id', 'epic-client-secret'];

  for (const name of secretNames) {
    const [version] = await client.accessSecretVersion({
      name: `projects/${process.env.GCP_PROJECT}/secrets/${name}/versions/latest`,
    });
    secrets[name] = version.payload?.data?.toString() || '';
  }

  return secrets;
}

Output

  • TLS 1.3 enforcement with optional cert pinning
  • HIPAA-compliant audit logger with PHI leak detection
  • Role-based access control matrix
  • Secrets loaded from cloud secret manager

Error Handling

| Issue | Cause | Solution | |-------|-------|----------| | TLS handshake failure | Server doesn't support TLS 1.3 | Verify Abridge endpoint; check proxy | | PHI in logs | Audit logger bypass | Add PHI detection to all log paths | | Permission denied | Wrong role | Check RBAC matrix for required role |

Resources

Next Steps

For production deployment checklist, see abridge-prod-checklist.