Skip to main content

HIPAA Technical Safeguards

OmniEHR implements comprehensive technical safeguards to ensure HIPAA compliance for Protected Health Information (PHI). The system is designed with security-first principles to meet regulatory requirements for healthcare data protection.

Administrative Controls

Access Control

Role-based access control (RBAC) with three distinct roles: admin, practitioner, and auditor

Audit Trail

Comprehensive logging of all PHI access and modifications

Authentication

JWT-based authentication with configurable token expiration

Encryption

AES-256-GCM encryption for all PHI at rest

Technical Implementation

The system enforces HIPAA compliance through multiple layers:

1. Access Control

All API endpoints require authentication via JWT bearer tokens. Access is restricted based on user roles:
// From ~/workspace/source/server/src/middleware/auth.js:4
export const authenticate = (req, _res, next) => {
  const authorization = req.headers.authorization;

  if (!authorization?.startsWith("Bearer ")) {
    return next(new ApiError(401, "Missing bearer token"));
  }

  const token = authorization.slice(7);

  try {
    const payload = verifyAccessToken(token);
    req.user = payload;
    return next();
  } catch {
    return next(new ApiError(401, "Invalid or expired token"));
  }
};

2. Audit Logging

Every FHIR and administrative API request is automatically logged with comprehensive audit information:
// From ~/workspace/source/server/src/middleware/audit.js:36
AuditLog.create({
  actorUserId: req.user?.sub,
  actorEmail: req.user?.email,
  actorRole: req.user?.role,
  action: methodToAction[req.method] || "unknown",
  resourceType,
  resourceId,
  method: req.method,
  path: req.originalUrl,
  statusCode: res.statusCode,
  outcome,
  ipAddress: req.ip,
  userAgent: req.get("user-agent")
});
Audit logs are stored with indexed fields for efficient querying by date, user, resource type, and outcome. They capture both successful and failed access attempts.

3. PHI Encryption

All Protected Health Information fields are encrypted at rest using AES-256-GCM:
// From ~/workspace/source/server/src/models/Patient.js:38
phi: {
  givenName: encryptedFieldSchema,
  familyName: encryptedFieldSchema,
  phone: encryptedFieldSchema,
  email: encryptedFieldSchema,
  line1: encryptedFieldSchema,
  city: encryptedFieldSchema,
  state: encryptedFieldSchema,
  postalCode: encryptedFieldSchema
}
Each encrypted field contains:
  • iv - Initialization vector (12 bytes)
  • authTag - Authentication tag for integrity verification
  • content - Encrypted data
The PHI_ENCRYPTION_KEY must be a 64-character hexadecimal string (32 bytes). Store this key securely and never commit it to version control.

Required Environment Variables

From ~/workspace/source/server/src/config/env.js:5, the following environment variables are required for security:
JWT_SECRET=your-secret-key-here
JWT_EXPIRES_IN=8h
PHI_ENCRYPTION_KEY=64-char-hex-string
MONGODB_URI=mongodb://...
The system validates that all required security environment variables are present at startup and will fail fast if any are missing.

Audit Log Schema

Audit logs track the following information for compliance:
FieldTypeDescription
actorUserIdObjectIdReference to the User who performed the action
actorEmailStringEmail of the actor for human readability
actorRoleStringRole at the time of action (admin/practitioner/auditor)
actionStringType of action (read/create/update/delete)
resourceTypeStringFHIR resource type or admin resource
resourceIdStringSpecific resource identifier
methodStringHTTP method (GET/POST/PUT/DELETE)
pathStringFull request path
statusCodeNumberHTTP response status code
outcomeStringsuccess or failure
ipAddressStringClient IP address
userAgentStringClient user agent
createdAtDateTimestamp of the action

Access to Audit Logs

From ~/workspace/source/server/src/routes/adminRoutes.js:83, audit logs are accessible only to admins and auditors:
router.get(
  "/audit-logs",
  authorize("admin", "auditor"),
  asyncHandler(async (req, res) => {
    // Query and return paginated audit logs
  })
);
Query parameters:
  • page - Page number (default: 1)
  • limit - Results per page (default: 50)
  • outcome - Filter by success/failure
  • resourceType - Filter by resource type
  • actorEmail - Filter by user email

Compliance Checklist

  • Access Control: Role-based permissions enforced at API level
  • Audit Trail: All PHI access logged with actor, action, and outcome
  • Encryption: AES-256-GCM encryption for PHI at rest
  • Authentication: JWT-based authentication with expiration
  • Integrity: GCM mode provides authenticated encryption
  • Minimum Necessary: Role-based filtering limits data exposure

Next Steps

Authentication

Learn about JWT authentication and login flow

Encryption

Deep dive into PHI encryption implementation

RBAC

Understand role-based access control

API Reference

View authentication API endpoints

Build docs developers (and LLMs) love