Documentation

Security & Compliance

How Cari protects patient data and meets healthcare regulatory requirements.

HIPAA Compliance

Technical safeguards for protecting electronic Protected Health Information (ePHI).

Cari implements technical safeguards required by the Health Insurance Portability and Accountability Act (HIPAA) for protecting electronic Protected Health Information (ePHI).

Access Control (164.312(a))

  • Unique user identification: Every user has a UUID-based account. All API requests are tied to authenticated user identities via PASETO tokens containing the user's sub (subject) claim.
  • Emergency access procedure: Super Admin accounts can access any patient record in emergency situations. All emergency access is logged in the audit trail.
  • Automatic logoff: Access tokens have short expiration times. Refresh tokens enable seamless re-authentication without storing long-lived credentials.
  • Encryption: All data is encrypted in transit (TLS 1.3) and at rest (CockroachDB encryption at rest).

Audit Controls (164.312(b))

  • Clinical audit events: The Session service provides a full audit event system at /api/clinical/audit that records creation, reads, updates, and deletions of clinical records.
  • Per-record audit trails: Every clinical record has a dedicated audit trail accessible at /api/clinical-records/:id/audit.
  • User activity trails: All actions by a specific user can be retrieved via /api/clinical/audit/user/:user_id.
  • Search and filtering: Audit events can be searched by resource type, user, date range, and action type at /api/clinical/audit/search.

Person or Entity Authentication (164.312(d))

  • Multi-factor authentication: TOTP-based MFA is available via /api/auth/mfa/enroll. The implementation follows NIST SP 800-63B AAL2 guidelines.
  • PASETO v4 tokens: Cryptographically signed tokens that cannot be tampered with. Unlike JWT, PASETO eliminates algorithm confusion attacks by design.
  • Token refresh flow: Short-lived access tokens with secure refresh mechanism prevent long-term credential exposure.

Transmission Security (164.312(e))

  • All API traffic is encrypted with TLS 1.2+ (Cloud Run enforces HTTPS)
  • Internal service-to-service communication runs within Google Cloud's private network
  • CORS policies restrict browser access to approved origins

GDPR Compliance

Data subject rights under the EU General Data Protection Regulation.

Cari implements the rights granted to data subjects under the EU General Data Protection Regulation (GDPR) through dedicated API endpoints in the Patients service.

Right to Erasure (Article 17)

Patients can request complete deletion of their personal data. Erasure requests are submitted and tracked through a formal workflow:

// Submit an erasure request
POST /api/patients/:id/erasure-request
Authorization: Bearer v4.public.eyJ...
Content-Type: application/json

{
  "reason": "I no longer wish to use the platform",
  "confirm": true
}

// List all data subject requests for a patient
GET /api/patients/:id/dsr
Authorization: Bearer v4.public.eyJ...

Right to Data Portability (Article 20)

Patients can export their complete health record in a machine-readable format:

// Export all patient data
GET /api/patients/:id/export
Authorization: Bearer v4.public.eyJ...

// Returns structured JSON with all clinical records,
// prescriptions, lab results, appointments, and demographics

Consent Management

Cari implements granular consent management that tracks what data a patient has consented to share and with whom. Consent can be granted, requested, approved, and revoked:

POST

/api/consent/grant

Patient grants consent proactively

POST

/api/consent/request

Provider requests consent from patient

POST

/api/consent/:id/approve

Patient approves a consent request

POST

/api/consent/:id/revoke

Patient revokes previously granted consent

GET

/api/consent

Patient views all their consent records

GET

/api/organizations/:org_id/consents

Organization views consents within their scope

The session recording system has its own consent layer at /api/sessions/consents to manage consent for clinical session recording and AI transcription.

ISO 27001 Alignment

Information security management controls aligned with ISO 27001.

Cari's security architecture aligns with ISO 27001 information security management controls:

A.9 Access Control

  • Role-based access control (RBAC) enforced at the gateway and service levels
  • Principle of least privilege: each role grants only the permissions needed
  • User access provisioning through organization invitation system
  • Developer API keys with rotation and revocation support

A.10 Cryptography

  • PASETO v4 (Ed25519) for token signing — no algorithm negotiation, no symmetric key confusion
  • TLS 1.2+ for all data in transit
  • CockroachDB encryption at rest for all stored data
  • Passwords hashed with Argon2 (memory-hard algorithm resistant to GPU attacks)

A.12 Operations Security

  • Structured JSON logging across all services for SIEM integration
  • Rate limiting at the gateway (300 req/min for auth, 600 req/min globally)
  • Dead letter queue (DLQ) for failed events — prevents silent data loss
  • Health check endpoints on every service for monitoring

A.14 System Acquisition, Development & Maintenance

  • Type-safe Rust backend — eliminates buffer overflows, null pointer dereferences, and data races at compile time
  • SQL injection prevention via parameterized queries (SQLx compile-time checked)
  • Input validation on all API endpoints
  • FHIR resource validation at the gateway level

Role-Based Access Control (RBAC)

Two-level enforcement at the API gateway and individual service middleware.

Cari enforces RBAC at two levels: the API gateway and individual service middleware. The gateway checks roles before proxying requests to downstream services, and services apply additional role checks via shared middleware from cari-core.

Role Hierarchy

SUPER:ADMIN

Platform super administrator. Full access to all resources including MPI, public health data, and user management.

APP:ADMIN

Application administrator. Access to administrative functions, MPI, and public health data.

ORG:ADMIN

Organization administrator. Manages their organization's settings, members, patients, and clinical data.

ORG:DOCTOR

Doctor within an organization. Access to clinical records, prescriptions, session recordings, and clinical tools.

ORG:STAFF

Non-clinical staff. Access to scheduling, administrative functions, and non-clinical data.

BASE:DOCTOR

Independent doctor not attached to an organization. Access to their own clinical workflows.

BASE:PATIENT

Patients. Access to their own health records, appointments, consent management, and GDPR rights.

RBAC Middleware Functions

Services use these shared middleware functions from cari-core:

require_authenticated

Any valid PASETO token

require_doctor

BASE:DOCTOR or ORG:DOCTOR

require_patient

BASE:PATIENT or ORG:PATIENT

require_clinician

Doctors or org admins

require_org_staff

Any org-scoped staff role

require_org_admin

ORG:ADMIN, SUPER:ADMIN, or APP:ADMIN

require_admin

SUPER:ADMIN or APP:ADMIN only

Gateway-Level Role Enforcement

The gateway applies path-based role requirements before proxying requests:

/api/mpi/*

Platform admins only

SUPER:ADMIN, APP:ADMIN

/api/sessions/*

Doctors only

Recording/extraction context

/api/clinical/dictation, /dicom, /prescriptions

Doctors only

Clinical tools

/api/public-health/*

Admins only

MOH-level data

/api/surveillance/*

Admins only

Epidemiological data

/cds-hooks/*

Clinicians only

CDS hook invocation

/api/cds/drug-interactions

Admins only

Data mutation

Data Encryption

Encryption in transit and at rest for all patient data.

In Transit

  • All external API traffic encrypted with TLS 1.2+ (enforced by Cloud Run)
  • HTTPS-only — HTTP requests are redirected to HTTPS
  • Internal service-to-service calls travel over Google Cloud's encrypted internal network

At Rest

  • CockroachDB encrypts all data at rest using AES-256
  • Redis data stored in memory and encrypted in transit
  • Passwords hashed with Argon2 — never stored in plaintext
  • PASETO tokens signed with Ed25519 — private key never leaves the server

Audit Logging

Comprehensive audit logs for clinical data access and modifications.

Cari maintains comprehensive audit logs for clinical data access and modifications. The audit system captures:

Who

Authenticated user ID from the PASETO token

What

Resource type, resource ID, and action performed

When

Timestamp of the event

Where

Service and endpoint that processed the request

Context

IP address, user agent, organization context

Audit API

// Log a clinical audit event
POST /api/clinical/audit
Authorization: Bearer v4.public.eyJ...
Content-Type: application/json

{
  "resource_type": "ClinicalRecord",
  "resource_id": "record-uuid",
  "action": "read",
  "metadata": { "reason": "Patient consultation" }
}

// Get audit trail for a specific resource
GET /api/clinical/audit/resource/ClinicalRecord/{resource_id}

// Get all audit events for a user
GET /api/clinical/audit/user/{user_id}

// Search audit events
GET /api/clinical/audit/search?action=update&from=2026-04-01&to=2026-04-18

Rate Limiting

Per-IP rate limits using Redis-backed sliding window counters.

Auth endpoints

/api/auth/*

300 req/min

All other endpoints

Every other API path

600 req/min

When a rate limit is exceeded, the API returns HTTP 429 (Too Many Requests). Rate limiting can be disabled for testing by setting RATE_LIMITING_ENABLED=false.

Dead Letter Queue

Capture and retry failed asynchronous events to prevent silent data loss.

Failed asynchronous events (e.g., user creation notifications, organization member added events) are captured in a Dead Letter Queue (DLQ) to prevent silent data loss. Administrators can review, retry, or discard failed events:

GET

/admin/dlq

List all failed events

GET

/admin/dlq/depth

Current DLQ depth and alert status

POST

/admin/dlq/:id/retry

Re-queue a failed event for processing

DELETE

/admin/dlq/:id

Discard a failed event

Monitor /admin/dlq/depth regularly. A growing DLQ depth may indicate a downstream service issue that needs attention.