Skip to content

How to Build HIPAA-Compliant Integrations for Healthcare SaaS

A technical guide to building HIPAA-compliant API and AI agent integrations for healthcare SaaS — covering BAAs, encryption, MCP server isolation, function-calling security, and architecture patterns that minimize PHI exposure.

Uday Gajavalli Uday Gajavalli · · 38 min read
How to Build HIPAA-Compliant Integrations for Healthcare SaaS

If you're building a healthcare SaaS product that pulls data from EHRs, HRIS systems, accounting platforms, or other clinical tools, the single biggest compliance risk you face isn't your core application — it's your integration layer. Every API connection that touches Protected Health Information (PHI) is a potential breach vector, a BAA requirement, and an audit liability. Integrations concentrate third-party credentials, cross-system access, retry logic, logs, and vendor relationships in one place. That makes them a hot zone.

This guide covers the architectural patterns, legal requirements, and practical engineering decisions you need to get right — without turning your integration layer into a second PHI warehouse. That includes a growing category of risk: AI agents that call accounting APIs, EHRs, and financial tools through function-calling protocols like MCP.

The High Stakes of Healthcare SaaS Integrations

Healthcare has been the most expensive industry for data breaches for over a decade, and the numbers keep getting worse. As of January 28, 2025, the OCR data breach portal shows 725 data breaches of 500 or more records in 2024, the third consecutive year that more than 700 large data breaches have been reported to OCR. Later portal updates pushed the 2024 total higher, with 734 large breaches and over 276 million affected records. Even using the earlier snapshot, that works out to roughly two large breaches per day.

The financial damage is staggering. For the 14th year in a row, the healthcare sector saw the costliest breaches across industries with average breach costs reaching $9.77 million. That's according to IBM's 2024 Cost of a Data Breach Report, against a global cross-industry average of $4.88 million. And that's the average — the Change Healthcare ransomware attack alone is estimated to have cost billions. Associated Press reported that UnitedHealth told Congress the attack involved compromised credentials and no MFA.

Regulators are responding in kind. In the January 2026 HHS inflation update, the maximum civil money penalty for an uncorrected willful neglect HIPAA violation rose to $2,190,294 — per violation, per year. And the enforcement trajectory is pointing up: The OCR Director has confirmed that in 2026, OCR will expand its risk analysis enforcement initiative to also include risk management, and 22 investigations resulted in penalties or settlements in 2024. On January 6, 2025, OCR published a Notice of Proposed Rulemaking to strengthen the Security Rule with explicit requirements around encryption, MFA, vulnerability scanning, penetration testing, network mapping, and annual compliance audits.

Here's the uncomfortable truth for engineering teams: 8 out of 14 mega-breaches in 2024 involved business associates of HIPAA-covered entities. The third-party vendor layer — the exact place where integrations live — is where the damage keeps happening. Verizon's 2025 DBIR says human involvement still showed up in about 60% of breaches, third-party involvement doubled to 30%, and credential abuse remained a leading initial access vector. Your integration layer sits right in the blast radius of all three failure modes.

What Makes an API Integration HIPAA-Compliant?

A HIPAA-compliant API integration protects the confidentiality, integrity, and availability of electronic Protected Health Information (ePHI) across every stage of data exchange — from authentication and transmission to processing and logging.

HIPAA doesn't hand you a technical checklist for APIs. The HIPAA Security Rule (45 CFR Part 164, Subpart C) mandates administrative, physical, and technical safeguards. Translating those legal requirements into software architecture means enforcing specific engineering patterns.

Technical Safeguards

  • Encryption in transit: Enforce secure protocols like TLS 1.2+ for all communications — including API calls and integrations with sub-processors. The proposed HIPAA Security Rule NPRM from December 2024 goes further: TLS 1.3 or higher must be used for secure data transmission.
  • Encryption at rest: The proposed rule would require encryption of ePHI at rest and in transit, with limited exceptions. Even under the current rule, not encrypting ePHI at rest is an almost indefensible position during an OCR audit. All credential fields — OAuth tokens, refresh tokens, API keys — must be encrypted using AES-256 and masked in any administrative UI.
  • Access controls: Every API call that could return ePHI needs authenticated, authorized, and auditable access. No anonymous endpoints. No shared API keys across tenants. No generic service accounts with permission to see everything.
  • Audit logging: HIPAA covered entities leveraging digital technologies for sharing and storing ePHI must have mechanisms to record and examine access and other activities within systems that contain or use ePHI. Log every API request, the identity of the user initiating it, the timestamp, and the specific endpoints accessed. But explicitly avoid logging the actual PHI payload. A common mistake engineering teams make is dumping raw HTTP responses into Datadog or CloudWatch for debugging — instantly creating a HIPAA violation. Log metadata, decisions, and hashes, not full payload bodies.

Administrative Safeguards

  • Risk assessments: Every organization must maintain an updated inventory of all technology assets that process, store, or transmit ePHI, including creating a network map that tracks ePHI's movement between internal systems and external partners. This is foundational and ongoing — not a one-time spreadsheet you produce for an auditor and ignore for the next 11 months.
  • Workforce training: Anyone who can access or configure integrations touching ePHI needs specific training on handling requirements.
  • Incident response: Documented procedures for what happens when an integration leaks data or credentials are compromised.

Physical Safeguards

For cloud-native SaaS, this largely translates to your infrastructure provider's compliance. Make sure your cloud provider (AWS, GCP, Azure) has a BAA in place and that you're only using HIPAA-eligible services.

One nuance matters a lot: addressable does not mean optional. HHS guidance says that when an addressable safeguard is not reasonable and appropriate, you must document why and implement an equivalent measure if one exists. For internet-facing healthcare APIs, this is not a place to improvise.

Control What it means in code
Risk analysis Map every place ePHI can land — including retries, logs, dead-letter queues, and support tooling
Access control Limit scopes, roles, and tenant boundaries
Audit controls Log actor, action, target, time, request ID, and outcome — not payloads
Integrity Detect unauthorized changes; use idempotent updates where possible
Transmission security Enforce TLS 1.2+ (preferably 1.3) for all API traffic

Handling Healthcare API Authentication Quirks

Healthcare APIs are notoriously difficult to authenticate against. Epic and Cerner rely heavily on SMART on FHIR and strict OAuth 2.0 flows with Proof Key for Code Exchange (PKCE).

Epic explicitly requires that credentials and tokens never be passed to non-Epic systems. They must remain confined to the specific application environment authorized by the healthcare provider — you cannot send an Epic access token down to a client-side frontend; it must be held securely in a backend proxy. Epic's rate limits also fluctuate based on data type and time of day, meaning your integration must handle HTTP 429 errors gracefully without dropping sensitive sync jobs.

SMART on FHIR is the right starting point when an EHR supports it well. But anyone who has shipped production healthcare integrations knows the standards story ends quickly when vendor quirks, missing fields, rate limits, and undocumented edge cases show up.

The Non-Negotiable: Business Associate Agreements (BAAs)

If your SaaS product, or any middleware it uses, creates, receives, maintains, or transmits ePHI on behalf of a covered entity, that vendor is a Business Associate under HIPAA and must sign a BAA. No exceptions.

A BAA is a HIPAA-required contract between a covered entity (like a healthcare provider or health plan) and a business associate (like a SaaS company or cloud service provider) that creates, receives, maintains, or transmits protected health information (PHI) on its behalf.

The direct implication for your integration stack: BAAs between developers and their vendors/partners must be in place before ePHI is exchanged, otherwise the exchange becomes a HIPAA violation. Every piece of middleware in your data flow needs a BAA.

The chain of custody looks like this:

%%{init: {'themeVariables': {'fontSize': '18px'}}}%%
graph LR
    A[Covered Entity<br>Hospital / Health Plan] -->|BAA Required| B[Your Healthcare SaaS]
    B -->|BAA Required| C[Integration Middleware<br>Unified API / iPaaS]
    C -->|BAA Required| D[Cloud Infrastructure<br>AWS / GCP / Azure]
    B -->|BAA Required| D

A common mistake: engineering teams adopt an iPaaS or integration tool that doesn't offer a BAA, assuming the tool "just passes data through" and doesn't really count. Even if a cloud service provider stores only encrypted data, doesn't have a key, and can't view the ePHI — they are still considered a business associate and fully responsible under HIPAA Rules. The legal bar is whether the vendor could access PHI, not whether it does. The conduit exception is narrow and generally limited to transmission-only services with only transient access. Most middleware, storage, queueing, and support vendors are not conduits.

If you route hospital data through a vendor that won't sign a BAA, your company assumes the entirety of the legal liability. When evaluating integration infrastructure, the BAA is the binary filter. If the vendor can't sign one, the technical evaluation stops immediately.

Warning

A BAA is necessary, but it is not a substitute for design discipline. A signed contract does not fix broad scopes, raw payload logging, or weak token handling.

Before you add any third-party integration service to your stack, ask three questions:

  1. Does the vendor sign a BAA? If not, full stop. You cannot use them for any workflow touching ePHI.
  2. What data does the vendor store, and for how long? More storage means more liability.
  3. Does the vendor have SOC 2 Type II certification? Not legally required by HIPAA, but a strong signal that security controls have been independently audited. Truto has completed its SOC 2 Type II audit for two consecutive years.

Architecture Patterns for Secure PHI Data Sync

Not all integration architectures are equal when it comes to HIPAA compliance. The fundamental architectural decision is: how much PHI does your integration middleware store, and for how long? Every extra copy of ePHI becomes another thing you have to secure, map, back up, monitor, and explain during an audit.

About 40% of all breaches involved data distributed across multiple environments, and data breaches solely involving public clouds were the most expensive type, costing $5.17 million on average.

Pattern 1: Data-Hoarding Middleware (High Risk)

Many legacy iPaaS platforms operate on a "store and forward" model. They poll the third-party API, pull data into their own managed databases, run transformations, and then push the data to your system.

For healthcare SaaS, this is an architectural nightmare. You're creating a secondary, shadow database of PHI hosted by a third-party vendor. Even if that vendor signs a BAA, you've doubled your attack surface. The middleware vendor now stores ePHI at rest, requiring their own encryption, access controls, and breach notification procedures. If they suffer a breach, your patients' data is in the blast radius.

Pattern 2: Pass-Through Proxy Architecture (Minimal Risk)

The safer approach is a pass-through proxy that fetches data in real time and transmits it directly to your application without storing it at rest. The middleware handles authentication, pagination, and data normalization, but it never keeps a copy.

%%{init: {'themeVariables': {'fontSize': '18px'}}}%%
graph TD
    subgraph Data-Hoarding iPaaS
        A[EHR System] -->|Raw PHI| B[(Middleware Database<br>Stores PHI at rest)]
        B -->|Transformed PHI| C[Healthcare SaaS]
    end

    C ~~~ D

    subgraph Zero-Retention Proxy
        D[EHR System] -->|Raw PHI| E[Proxy Layer<br>In-memory processing only]
        E -->|Transformed PHI| F[Healthcare SaaS]
    end
    
    style B fill:#ffcccc,stroke:#ff0000
    style E fill:#ccffcc,stroke:#00aa00

In this model, when your application requests a list of patients, the request passes through the proxy. The proxy attaches the encrypted OAuth credentials, forwards the request to the EHR, receives the response, and transforms the payload entirely in memory. The data is delivered to your application, and the memory is flushed. Because PHI is never written to disk on the integration layer, the compliance risk drops dramatically.

%%{init: {'themeVariables': {'fontSize': '18px'}}}%%
sequenceDiagram
    participant App as Your Healthcare SaaS
    participant Proxy as Integration Layer<br>(Pass-Through)
    participant EHR as Third-Party EHR / HRIS

    App->>Proxy: GET /unified/hris/employees
    Proxy->>EHR: GET /api/v1/employees<br>(with refreshed OAuth token)
    EHR-->>Proxy: Employee records (ePHI)
    Proxy-->>App: Normalized response<br>(no data stored)

This pattern reduces your compliance burden because:

  • The middleware never stores ePHI at rest, eliminating an entire class of encryption-at-rest requirements for that layer.
  • A breach of the middleware vendor doesn't expose patient data — there's nothing to steal.
  • Your data residency footprint stays small: ePHI exists in the source system and in your application. That's it.

The trade-off is latency. Real-time API calls are slower than querying a local cache. For most healthcare SaaS use cases — pulling employee rosters, syncing patient demographics, fetching billing data — this latency is perfectly acceptable.

Pattern 3: Customer-Controlled Data Store (Best of Both)

For cases where you need queryable, cached data or high-throughput analytics, the best approach to handle bulk data extraction is to sync data into your own infrastructure rather than relying on the middleware vendor's storage. Truto's sync jobs push records to your webhook endpoint as they're fetched. You control the data store, the encryption keys, the access policies, and the retention schedule.

This keeps the integration layer stateless while giving you the performance benefits of local data. It's the right separation of concerns — you already have the infrastructure and compliance controls for your own database.

The important thing across all these patterns is what you don't do. You don't spray raw bundles into traces. You don't drop payloads into a queue because they might be handy later. You don't forward them to five internal services before you know whether the caller even needed those fields. That's how a convenient integration layer turns into a second PHI warehouse.

Pass-Through Proxy Implementation

Building a pass-through proxy sounds simple until you actually try it. The failure modes are subtle: a buffer that lives one function call too long, a log line added during debugging that never gets removed, a retry that queues a response payload "just in case." Any one of them turns a compliant architecture into a HIPAA incident. Here's the concrete shape of an implementation that holds up.

The Core Request Handler

The proxy accepts a request from your application, resolves the connected account, refreshes credentials if needed, forwards to the upstream API, transforms the response in memory, and returns. Nothing persists.

async function proxyRequest(req) {
  const { tenantId, connectionId, resource, method, query, body } = req;
  const startedAt = Date.now();
 
  // 1. Resolve the connected account (metadata only, no PHI in this record)
  const account = await getConnectedAccount(tenantId, connectionId);
  if (!account) throw new NotFoundError('connection');
 
  // 2. Refresh credentials proactively if TTL is low
  const credentials = await ensureFreshCredentials(account);
 
  // 3. Apply the scoped filters the customer chose at connect time
  const scopedQuery = applyScopeFilters(query, account.context);
 
  // 4. Build and forward the upstream request
  const upstream = buildUpstreamRequest({
    integration: account.integration,
    resource,
    method,
    query: scopedQuery,
    body
  });
 
  const response = await fetch(upstream.url, {
    method: upstream.method,
    headers: {
      ...upstream.headers,
      Authorization: `Bearer ${credentials.accessToken}`
    },
    body: upstream.body,
    agent: hipaaTlsAgent
  });
 
  // 5. Transform in memory via a declarative mapping - no disk writes
  const raw = await response.json();
  const mapped = applyMapping(raw, resource, account.integration);
 
  // 6. Log the access event - metadata only, no payload
  auditLog({
    request_id: req.id,
    tenant_id: tenantId,
    connection_id: connectionId,
    integration: account.integration,
    resource,
    operation: method,
    status_code: response.status,
    latency_ms: Date.now() - startedAt,
    outcome: response.ok ? 'success' : 'error'
  });
 
  return mapped;
  // On return, raw and any intermediates leave scope.
  // Nothing was written to disk, queued, or cached with a payload.
}

Note what is absent: no database insert for the response, no cache put keyed on the resource ID, no queue enqueue with the payload, no request or response body in the audit log.

Enforce Zero Retention Structurally, Not by Convention

Good intentions leak. Enforce the invariant at the infrastructure layer so no future code change can violate it:

  • Read-only file system on proxy workers. If the process cannot write to disk outside a small tmpfs for its own binaries, it cannot accidentally persist PHI.
  • Strip payload keys at the logger. Configure your logger to drop body, data, response, and known-sensitive keys before serialization. Emit a redaction metric when it fires so you can find and fix the code path.
  • Disable swap on workers. Decrypted PHI in process memory should never land in a swap file that outlives the request.
  • Null out large objects before return. In long-lived request contexts, explicitly release references to raw response payloads once the mapped output is built.
  • No default egress. Deny outbound network by default; allowlist only the specific upstream integrations the proxy is configured for. This blocks a compromised worker from exfiltrating to an attacker-controlled endpoint.

Streaming Large Payloads

Bulk endpoints (Epic $export, Cerner Bulk Data Access) return NDJSON files that can be gigabytes. Buffering the whole file into memory before mapping is both an OOM risk and a compliance problem - the entire dataset sits in one process for longer than it needs to. Stream it, map each line, and pipe the transformed output straight to the caller:

async function proxyBulk(upstream) {
  const response = await fetch(upstream.url, { agent: hipaaTlsAgent, ...upstream });
  const decoder = new TextDecoder();
  const encoder = new TextEncoder();
  let buffer = '';
 
  const transform = new TransformStream({
    async transform(chunk, controller) {
      buffer += decoder.decode(chunk, { stream: true });
      const lines = buffer.split('\n');
      buffer = lines.pop() ?? '';
      for (const line of lines) {
        if (!line) continue;
        const record = JSON.parse(line);
        const mapped = applyMapping(record, upstream.resource, upstream.integration);
        controller.enqueue(encoder.encode(JSON.stringify(mapped) + '\n'));
      }
    }
  });
 
  return new Response(response.body.pipeThrough(transform));
}

Each record is mapped and forwarded before the next one is read. The bulk payload never exists as a single object anywhere in the proxy.

Idempotency for Safe Retries

Any write forwarded through the proxy should carry an idempotency key derived from the caller's request. If the caller retries, the proxy replays with the same key and the upstream API deduplicates on its side:

function idempotencyKey(tenantId, connectionId, operation, canonicalBody) {
  return createHmac('sha256', process.env.IDEMPOTENCY_SECRET)
    .update([tenantId, connectionId, operation, canonicalBody].join('|'))
    .digest('hex');
}

For upstream APIs that do not support idempotency headers natively (many EHRs), the proxy can maintain a short-lived (60 to 120 second) in-memory map of idempotency key to resulting record ID. Only the key and the ID live in the map - never the PHI payload.

Wire It Through the Same Credential Path as the Unified API

A common failure pattern: teams build a "raw proxy" endpoint for vendor-specific calls that bypasses the credential decryption, logging, and filtering logic used by the unified API. Six months later, an audit reveals that raw proxy calls are unlogged and use a different token refresh path. Both the unified path and the proxy path should route through the same credential manager, the same audit logger, and the same TLS agent. Differ only in whether a response mapping is applied.

Ensuring HIPAA Compliance in the Proxy Layer

Implementation is only half the job. You have to prove the proxy actually behaves as claimed, both in initial verification and continuously in production. Auditors do not accept "we designed it that way" - they want evidence.

Verification Tests to Run Before Launch

  • PHI leak scanner on logs. Run a synthetic sync against a sandbox EHR with tagged canary values (a specific fake SSN, MRN, and DOB). Grep every log sink for those canaries. Anything that matches is a code path that logs PHI, and it needs to be fixed before production.
  • Disk write monitor. Trace filesystem writes on a proxy worker during a full sync cycle using strace or an eBPF probe. The only writes should be metric buffers and rotated log files. Any write to a data file is a violation.
  • Memory retention check. Trigger a heap snapshot mid-request and confirm response payloads are not held after the request completes. Look for large string or buffer objects rooted at long-lived request contexts.
  • TLS scanner. Run testssl.sh against every proxy endpoint monthly. Fail the build if TLS 1.1 or non-AEAD ciphers reappear.
  • Credential exposure test. Attempt to fetch a decrypted credential through every public API surface, including error paths and debug endpoints. Every attempt must return 404 or 403 - never the token, never a partial token, never the ciphertext.
  • Field-filter parity test. Compare the upstream response size to the mapped response size for a representative set of resources. If the mapped payload is not smaller, field-level filtering is not running.

Continuous Compliance Signals

  • Redaction counter metric. Emit a metric every time the logger redacts a field. A sudden spike means someone added a code path that tries to log PHI - investigate before it becomes a habit.
  • Egress byte accounting per tenant. Track upstream response bytes fetched vs. bytes returned to the caller. A widening delta confirms filtering is working; a shrinking delta is a warning.
  • Token age distribution. Alert if any tenant has tokens past 90% of their nominal TTL. That means the refresh scheduler is falling behind, and you are one restart away from silent sync failures.
  • BAA registry check. Automate a monthly job that confirms every third-party service on the proxy's egress allowlist has a current BAA on file. Block new destinations at the network policy layer until they are added to the registry.
  • Circuit breaker state transitions. Track opens and closes per (tenant, integration). Correlated opens across tenants signal an upstream incident; isolated opens signal a per-tenant credential or scope problem.

Auditor-Ready Evidence

When an OCR audit or a customer's security review lands, the artifacts you want to produce on demand:

  1. Architecture diagram showing zero-retention data flow, with named components and BAA coverage annotated on each edge.
  2. Log samples demonstrating audit fields present and PHI fields absent, drawn from the actual production log store.
  3. Encryption inventory: every credential and ePHI store, its algorithm (AES-256-GCM), the KMS provider, key rotation cadence, and last rotation timestamp.
  4. Access review: quarterly proof that only authorized workforce members can view connected account metadata, and that no one can view credentials or payloads.
  5. Incident response test results from your most recent tabletop, including a credential-compromise scenario.
  6. Penetration test report against the proxy layer, including credential extraction attempts and log-injection attempts.
  7. Vendor management: signed BAAs for every business associate in the data path, with expiration and renewal tracking.

Compliance is not a one-time architecture decision. It is the day-to-day discipline of proving the architecture still holds.

Enforcing the "Minimum Necessary" Rule with Scoped Access

HIPAA's "minimum necessary" standard (45 CFR §164.502(b)) requires that when PHI is used or disclosed, only the minimum amount necessary to accomplish the purpose should be shared. For integrations, this means your API connections should never pull more data than the specific workflow requires.

You cannot simply request GET /patients and pull down the entire hospital directory if your SaaS only needs to track patients participating in a specific clinical trial. Over-fetching data is a compliance liability. Broad access should be the exception you justify, not the default you clean up later.

User-Level Scoping at Connection Time

When your customer connects their third-party account, give them the ability to specify exactly what data should be synced. This means presenting a post-connection form where the end user can select specific workspaces, projects, tags, departments, or patient cohorts to include in the sync.

For example, a healthcare org connecting their ticketing system might only want to sync tickets tagged "clinical-ops" — not the entire ticket backlog that could contain PHI in unrelated support threads. A billing integration should ask the user to select specific billing codes or departments.

{
  "name": "ticket_tags",
  "type": "multi_select",
  "label": "Tags to sync",
  "help_text": "Select only the tags relevant to your workflow",
  "data_source": {
    "type": "proxy",
    "resource": "tags",
    "method": "list"
  },
  "options": {
    "value": "id",
    "label": "name"
  }
}

These selections are stored as context variables on the connected account and used to filter every subsequent API call. This isn't just a nice UX feature — it's a direct implementation of the minimum necessary rule, and it gives you audit evidence that the customer explicitly chose what data to share.

Field-Level Filtering at the API Layer

Even when you restrict the API query, healthcare APIs often return massive, nested JSON payloads containing sensitive data you don't need — Social Security Numbers, full medical histories, salary data. The burden falls on your integration layer to strip fields before they reach your application.

Using an expression language like JSONata lets you map and filter the response in memory:

response.{
  "id": $string(id),
  "patient_name": name[0].text,
  "condition": condition_code,
  "last_visit": $fromMillis(last_updated * 1000)
}

By explicitly mapping only the fields your application requires, extraneous PHI is stripped out at the proxy layer and never enters your database. Parameters like truto_exclude_fields and truto_ignore_remote_data give you additional control over exactly what comes through the wire.

Credential Security: The Attack Surface You Forget About

Your integration layer doesn't just move data — it stores the keys to your customers' systems. OAuth tokens, API keys, and service account credentials are high-value targets. If an attacker compromises your integration middleware, they don't just get the data that was synced — they get persistent access to the source systems.

A compliant integration architecture needs to treat credential storage with the same rigor as ePHI storage:

  • Encrypt all credentials at rest. Every credential field — OAuth access tokens, refresh tokens, API keys, client secrets, and passwords — should be encrypted using AES-256. These fields must be masked in the UI and only decrypted at the moment they're needed for an API call.
  • Proactive token refresh. Expired tokens that force re-authentication create security gaps and operational disruptions. Schedule token refresh proactively — before the token expires — and automatically mark accounts as needing re-authorization if refresh fails, firing a webhook so your application can notify the customer.
  • Per-tenant credential isolation. Every connected account needs its own credential context. No shared token pool. A breach of one connected account shouldn't cascade to others.

For a deeper look at how to handle the complexity of enterprise authentication across legacy systems, see our engineering deep-dive.

Practical Configuration: TLS 1.3 and AES-256-GCM Settings

The abstract rules ("encrypt in transit," "encrypt at rest") only matter if the concrete configuration is right. This section is what to hand to the engineer implementing the controls.

TLS Configuration for HIPAA Encryption in Transit

For any outbound HTTPS client that fetches ePHI, disable everything below TLS 1.2 and prefer TLS 1.3 where the source system supports it. The proposed HIPAA Security Rule update calls out TLS 1.3 explicitly, and there is no operational reason to keep TLS 1.0 or 1.1 enabled in 2026.

A Node.js outbound agent that meets the bar:

const https = require('https');
 
const agent = new https.Agent({
  minVersion: 'TLSv1.2',
  maxVersion: 'TLSv1.3',
  ciphers: [
    // TLS 1.3
    'TLS_AES_256_GCM_SHA384',
    'TLS_CHACHA20_POLY1305_SHA256',
    'TLS_AES_128_GCM_SHA256',
    // TLS 1.2 fallback (AEAD only, forward secrecy only)
    'ECDHE-ECDSA-AES256-GCM-SHA384',
    'ECDHE-RSA-AES256-GCM-SHA384',
    'ECDHE-ECDSA-CHACHA20-POLY1305',
    'ECDHE-RSA-CHACHA20-POLY1305'
  ].join(':'),
  honorCipherOrder: true,
  keepAlive: true
});

For inbound HTTPS on your API gateway, terminate TLS with an HSTS response header and reject any downgrade attempts:

Strict-Transport-Security: max-age=63072000; includeSubDomains; preload

A few operational notes that matter more than the config itself:

  • Certificate pinning is worth the overhead for high-value EHR endpoints. Rotate pinned fingerprints on a schedule so a legitimate certificate renewal doesn't take you down.
  • Disable TLS session resumption across tenants. A shared session ticket key across tenant workers is a subtle way to blur isolation boundaries.
  • Run a scanner against your own endpoints monthly. SSL Labs, testssl.sh, or an internal equivalent. Configuration drift is the enemy.

AES-256-GCM for ePHI and Credentials at Rest

Use AES-256-GCM (not CBC) for both ePHI payloads that must be persisted and credential fields. GCM gives you authenticated encryption, so any tampering with ciphertext produces a decryption error rather than silently returning garbage.

const { createCipheriv, createDecipheriv, randomBytes } = require('crypto');
 
function encrypt(plaintext, dek, keyId) {
  const iv = randomBytes(12); // 96-bit nonce for GCM
  const cipher = createCipheriv('aes-256-gcm', dek, iv);
  const ciphertext = Buffer.concat([
    cipher.update(plaintext, 'utf8'),
    cipher.final()
  ]);
  const authTag = cipher.getAuthTag();
  return {
    v: 1,
    keyId,           // which DEK version was used
    iv: iv.toString('base64'),
    ct: ciphertext.toString('base64'),
    tag: authTag.toString('base64')
  };
}

Two rules that matter more than the specific library:

  1. Never reuse a nonce with the same key. A single reused (key, nonce) pair in GCM leaks the XOR of two plaintexts. Use a CSPRNG for nonces; do not derive them from timestamps or counters shared across processes.
  2. Store the key ID alongside the ciphertext. This is what makes rotation possible without a big-bang re-encryption.

Key Rotation Without Downtime

Adopt an envelope encryption model: a data encryption key (DEK) per record or per tenant, wrapped by a key encryption key (KEK) held in a KMS. Rotate KEKs on a fixed cadence - 90 days is a reasonable default, 30 days after a suspected compromise. Rotating a KEK re-wraps the DEKs; it does not require touching the underlying ciphertext.

DEK rotation for high-sensitivity records (long-lived OAuth refresh tokens, for example) should happen on read: if a decrypted record was encrypted under an older DEK version, re-encrypt with the current DEK before writing it back. Track this via the keyId you stored with the ciphertext.

A reasonable rotation runbook:

  1. Issue a new KEK version in the KMS. Keep the old version enabled for decryption.
  2. Enumerate wrapped DEKs and re-wrap under the new KEK. This is a metadata-only operation.
  3. Flip the "current" pointer to the new KEK version.
  4. After a monitoring window (7 to 14 days), disable the old KEK version. Do not delete it until you are confident no ciphertext still references it.
  5. Log every rotation event with actor, key IDs (old and new), and duration.

Credentials Management: Encryption at Rest and UI Masking

Credentials are the highest-value target in your integration layer. The concrete controls:

  • Encrypt every credential field - OAuth access tokens, refresh tokens, client secrets, API keys, session IDs, and basic auth passwords - using AES-256-GCM with a per-tenant or per-account DEK.
  • Never return decrypted credentials to any UI or API response. The plaintext should exist only in memory, only during an outbound request, and only inside the process that will attach it to the HTTP call.
  • Mask consistently in the admin UI. Show the first two and last two characters of a token at most (sk_l****...****a92c). Never show length either - a masked field of variable length leaks entropy information over time.
  • Prohibit credential export. No "copy token to clipboard" affordance for stored credentials. If a customer needs the token to debug directly against the source API, force a fresh OAuth flow.
  • Separate the decryption boundary from the request path. The service that decrypts should be a narrow function that takes a credential ID and returns a signed HTTP request, not a general-purpose "give me the token" endpoint.

An integration platform should also expose credential health as a first-class signal: last successful use, last refresh, next scheduled refresh, and current status (healthy, refresh_uncertain, needs_reauth). Your application uses these signals to disable dependent workflows before they start failing loudly.

Logging Configuration: What to Log, What to Hash

The single most common accidental HIPAA violation is dumping raw responses into structured logs for "debugging." Establish a strict schema for what integration logs can contain, and enforce it at the logger level - not at the developer's discretion.

Fields Safe to Log

  • request_id (UUID)
  • tenant_id / connected_account_id
  • integration (e.g. epic, cerner, quickbooks)
  • resource (e.g. patient, invoice)
  • operation (list, get, create, update)
  • http_method and status_code
  • latency_ms
  • retry_count
  • outcome (success, client_error, server_error, rate_limited)
  • actor (user or agent identity)
  • policy_context (scopes, tags, filters applied)

Fields That Must Never Appear in Cleartext

  • Request or response bodies
  • URL path segments containing record IDs that could be re-identified against the source system
  • Query strings from EHR APIs (they often carry patient identifiers)
  • OAuth tokens, refresh tokens, API keys, session IDs
  • Header values that carry credentials
  • Any field whose name matches ssn, dob, mrn, patient_id, name, email, phone, address

Hashing for Correlation Without Leaking PHI

You often need to correlate a log entry back to a specific record for support - "why did this patient sync fail?" Store an HMAC-SHA-256 of the identifier, keyed by a tenant-specific secret. This gives you deterministic correlation within a tenant while preventing cross-tenant re-identification and preventing plaintext ID exposure in the log stream.

const { createHmac } = require('crypto');
 
function hashIdentifier(id, tenantSecret) {
  return createHmac('sha256', tenantSecret)
    .update(String(id))
    .digest('hex')
    .slice(0, 16); // 64 bits of correlation is plenty for support workflows
}
 
// Sample log entry
logger.info({
  request_id: 'a3f9...',
  tenant_id: 'tnt_842',
  integration: 'epic',
  resource: 'patient',
  operation: 'get',
  status_code: 200,
  latency_ms: 412,
  outcome: 'success',
  patient_ref: hashIdentifier(patientId, tenantSecret) // 'c81a4b7f9e2d3a55'
});

Rotate the tenant-specific HMAC key on the same cadence as your KEKs. When it rotates, existing log entries become uncorrelatable with new ones - which is actually the desired behavior for old logs approaching retention expiry.

Redaction at the Logger, Not the Call Site

Trusting every developer to remember to redact before calling logger.info() is how you end up with a breach. Wrap your logger to strip known-sensitive keys recursively, and log a warning counter (not the offending value) when redaction fires so you can find and fix the code path:

const SENSITIVE_KEYS = new Set([
  'authorization', 'token', 'access_token', 'refresh_token',
  'api_key', 'client_secret', 'password', 'session_id',
  'ssn', 'dob', 'mrn', 'patient_id', 'first_name', 'last_name',
  'email', 'phone', 'address', 'body', 'response_body'
]);
 
function redact(obj, depth = 0) {
  if (depth > 8 || obj === null || typeof obj !== 'object') return obj;
  const out = Array.isArray(obj) ? [] : {};
  for (const [k, v] of Object.entries(obj)) {
    if (SENSITIVE_KEYS.has(k.toLowerCase())) {
      out[k] = '[REDACTED]';
      metrics.increment('logger.redaction', { key: k });
    } else {
      out[k] = redact(v, depth + 1);
    }
  }
  return out;
}

Finally, retain integration logs for the minimum period your compliance program requires (typically 6 years for HIPAA-relevant records) and no longer. Old logs are pure liability.

Token Lifecycle: Refresh, Rotation, and Re-auth Workflows

OAuth tokens are the credentials that make integrations run - and the credentials most likely to fail silently until a customer sync breaks at 3 AM.

Proactive Refresh, Not Reactive

Waiting until a 401 invalid_token response to refresh is a mistake for three reasons: it adds latency on every request that catches an expired token, it produces noisy failures in your metrics, and some EHR APIs treat repeated 401s as suspicious and lock the account temporarily. Instead, schedule refresh ahead of expiry.

A reasonable policy: refresh when the token's remaining TTL drops below 20% of its original lifetime, with a floor of five minutes. Truto's platform schedules refresh work ahead of token expiry so requests never hit an expired token in the hot path.

token_issued_at: 2026-07-15T10:00:00Z
token_expires_at: 2026-07-15T11:00:00Z   // 3600s lifetime
refresh_threshold_at: 2026-07-15T10:48:00Z // TTL <= 20% or T-5min, whichever is later

Handle Refresh Token Rotation Correctly

Many providers (Epic, Google, and increasingly others) rotate the refresh token itself on each use. The old refresh token becomes invalid the moment a new one is issued. If your refresh flow crashes between "received new refresh token" and "persisted new refresh token," the connected account is now permanently broken.

The fix is a short, disciplined transaction:

  1. Take a short-lived lock on the connected account, keyed on connected_account_id, so two workers don't try to refresh at once.
  2. Call the token endpoint.
  3. Persist the new refresh token and access token atomically before releasing the lock.
  4. Only after successful persistence, use the new access token for the caller's request.

If the token endpoint returns a network error mid-flight, do not assume the old refresh token is still valid - it may or may not be, depending on the provider. Mark the account as refresh_uncertain, attempt one more refresh from a background worker before marking it needs_reauth, and alert an operator if the uncertain state persists beyond a threshold.

Re-auth Detection and Customer Notification

When a refresh definitively fails (invalid_grant, unauthorized_client, invalid_client), the connected account needs human intervention. Your integration layer should:

  1. Mark the connected account as needs_reauth.
  2. Fire a webhook to your application so you can email the customer and disable dependent workflows.
  3. Stop scheduling further sync jobs for that account until re-auth completes.
  4. Preserve the last-known-good sync cursor so re-auth doesn't cause a full historical resync (which is expensive and generates unnecessary PHI movement).
  5. Retain the connected account record but clear the credential ciphertext once re-auth succeeds with a new set of tokens - old ciphertext is dead weight and audit surface.

A typical event flow:

%%{init: {'themeVariables': {'fontSize': '18px'}}}%%
sequenceDiagram
    participant Sched as Refresh Scheduler
    participant IdP as Provider IdP
    participant Store as Credential Store
    participant App as Your App

    Sched->>IdP: POST /token (grant_type=refresh_token)
    alt Success
        IdP-->>Sched: new access + refresh
        Sched->>Store: Atomic persist (locked)
        Store-->>Sched: OK
    else invalid_grant
        IdP-->>Sched: 400 invalid_grant
        Sched->>Store: mark needs_reauth
        Sched->>App: webhook: connection.needs_reauth
        App->>App: Notify customer, pause syncs
    else network error
        IdP-->>Sched: timeout / 5xx
        Sched->>Store: mark refresh_uncertain
        Note over Sched: Retry from background<br>with exponential backoff
    end

Rate Limits and Retries Without PHI Persistence

EHR rate limits are strict, opaque, and vary by data type and time of day. Epic, Cerner, and Athena all rate-limit aggressively, and the naive retry strategy - "queue the payload and try again later" - is exactly what turns your integration layer into a PHI warehouse.

Retry the Request, Not the Payload

For pass-through architectures, the correct retry primitive is "retry the caller's original request against the upstream API" - not "queue the response payload for later delivery." If a request is rate-limited or hits a 5xx, propagate a retryable error back to the caller. The caller re-issues the request; the proxy re-fetches from the source; no PHI is ever written to a queue.

For sync jobs that must succeed eventually, queue the request specification (tenant ID, resource type, cursor, filters) - never the fetched response. When the job retries, it re-fetches from the source using the specification. A queued job record should look like this:

{
  "job_id": "sync_9f3a...",
  "tenant_id": "tnt_842",
  "integration": "epic",
  "resource": "patient",
  "cursor": "eyJvZmZzZXQiOjIwMH0=",
  "filters": { "department_id": "dept_17" },
  "attempt": 2,
  "next_run_at": "2026-07-15T10:15:03Z"
}

No PHI in the job envelope. If the queue is breached, no records leak.

Exponential Backoff with Full Jitter

function nextDelay(attempt, base = 500, cap = 30_000) {
  const exp = Math.min(cap, base * 2 ** attempt);
  return Math.floor(Math.random() * exp); // full jitter
}

Full jitter prevents thundering-herd retries after a source-side outage. Cap total retry duration; do not retry indefinitely. Beyond a threshold (three to five attempts for user-triggered requests, ten to fifteen for background jobs), surface the failure and let the operator decide.

Respect Retry-After

Most healthcare APIs return Retry-After on 429 or 503. Honor it exactly. Ignoring it is how you get IP-blocked or temporarily suspended by the EHR, which turns a transient rate-limit event into an outage.

function backoffFromResponse(res, attempt) {
  const header = res.headers.get('retry-after');
  if (header) {
    const seconds = Number.isNaN(Number(header))
      ? Math.max(0, (new Date(header).getTime() - Date.now()) / 1000)
      : Number(header);
    return Math.max(1, seconds) * 1000;
  }
  return nextDelay(attempt);
}

Per-Tenant Circuit Breakers

A failing tenant should not consume all your retry budget and starve healthy tenants. Wrap upstream calls in a circuit breaker keyed on (tenant_id, integration). When the breaker opens, fail fast for that tenant while other tenants continue to sync. Typical thresholds:

  • Open the breaker after 5 consecutive failures or a 50% error rate over 60 seconds.
  • Half-open after 30 to 60 seconds; allow a single probe request.
  • Close the breaker after 3 consecutive probe successes.

Emit a metric on every state transition. Circuit breaker events are one of the earliest signals of an EHR-side incident, and correlating them across tenants gives you upstream outage detection before the vendor status page updates.

EHR Vendor Quirks and Practical Mitigations

Standards get you 80% of the way. The last 20% is vendor-specific behavior that will burn a sprint if you don't know about it up front.

Epic

  • SMART on FHIR with PKCE is required for public clients. Confidential clients must additionally use asymmetric client authentication (JWT-signed client assertion with a private key registered in the developer program).
  • Refresh tokens rotate on each use. Persist atomically or expect breakage.
  • Access tokens must never be exposed to browser code. Backend proxy only.
  • Rate limits vary by data category and time of day. Bulk data endpoints have separate, much stricter limits than transactional FHIR reads.
  • Sandbox and production have different endpoints and different data models. Test against the same FHIR version your customer is running.
  • Some resources return Provenance and AuditEvent sub-resources that reference the primary resource - fetching them naively multiplies your API call count and rate-limit exposure.

Oracle Health (Cerner)

  • Two API surfaces exist side by side: the older Millennium APIs and the newer FHIR R4 APIs. The same customer often runs both.
  • Bulk Data Access ($export) is async. You poll for job status, then download NDJSON files. Do not stream those files through your logging layer.
  • Tenant-specific base URLs. You cannot hardcode a single endpoint - resolve it per connected account.
  • Token scopes are granular and must be requested explicitly during authorization. A missing scope produces a 403 at read time, not at connect time.

Athenahealth

  • Practice-scoped tokens. A single credential does not give you cross-practice access.
  • Rate limits are per-practice and per-endpoint. A hot practice can starve a cold one if you share a worker pool naively - shard workers by practice ID.
  • The Preview and Production environments have distinct authentication URLs. Configuration drift here is a common outage cause.

Veeva Vault and Life Sciences Platforms

  • Session-based auth with short-lived session IDs, not OAuth. Store the session ID in the connected account context and refresh via the login endpoint before it expires.
  • Vault-specific object models. Do not assume Salesforce-style semantics even though the API shape is superficially similar.

General Mitigations

  • Keep an integration-specific config that describes each vendor's auth flow, rate-limit headers, pagination style, and known-broken endpoints. Version it alongside your integration code.
  • Build a small "vendor probe" endpoint that checks connectivity, auth validity, and basic rate-limit headroom for each connected account. Run it before large sync jobs.
  • Treat every EHR sandbox as behaviorally different from production. Do not certify compliance based on sandbox testing alone.
  • Maintain a per-vendor incident playbook: known failure modes, escalation contacts, and the fastest path to a workaround.

Securing AI Agent Integrations Under HIPAA

AI agents that interact with healthcare data through function-calling and tool-use protocols introduce a distinct set of HIPAA risks. The compliance obligations do not change because the accessor is a machine. HIPAA's Privacy Rule, Security Rule, and Breach Notification Rule were written around the data, not the person or system reading it. An agent that queries a patient record, creates an invoice in QuickBooks, or reconciles billing data in NetSuite has performed a regulated data access event.

This matters especially for accounting API integrations. HIPAA protects patient medical records and any data that can identify an individual when linked to healthcare services. In accounting and billing systems, this often includes billing details, insurance claims, and payment records. An AI agent automating order-to-cash workflows, expense categorization, or bank reconciliation against an accounting system is handling ePHI if those records are linked to healthcare services. The integration layer connecting the agent to QuickBooks, Xero, or Sage Intacct must be HIPAA-compliant end-to-end.

Execution-Step Security: HIPAA Constraints on Function Calling

When an AI agent invokes a tool - whether through MCP, OpenAI function calling, or any other tool-use protocol - the execution step is where PHI exposure actually happens. The LLM itself may only see a tool description and schema. But the moment the platform executes the function and returns results, ePHI is in motion.

HIPAA's Technical Safeguards (§164.312) apply to every execution step:

  • Access control at tool invocation. Each tool call must be authenticated and authorized. The agent's identity, the delegating user, and the specific operation must all be verified before execution proceeds. No anonymous tool execution against ePHI-bearing systems.
  • Audit logging per invocation. A HIPAA-compliant AI audit trail must record the agent's authenticated identity, the human authorizer who delegated the workflow, the specific operation performed, the PHI records accessed, the policy context governing the access decision, and a tamper-evident timestamp. Do not log the returned payload - log the access event.
  • Minimum necessary at the schema level. Your tool schemas should request only the fields the workflow actually needs. If the agent is reconciling payments, expose invoice amounts and dates - not patient diagnoses. Field-level filtering at the proxy layer strips extraneous PHI before it ever reaches the agent's context window.
  • Encryption of tool responses in transit. All communication between the tool server and the agent client must use TLS 1.2+ (1.3 preferred). This includes internal service-to-service calls, not just external-facing endpoints.

A common mistake: treating the LLM orchestration layer as a trusted internal service that doesn't need the same controls as a user-facing API. Under HIPAA, it does.

MCP and Tool Server Isolation

If you're exposing healthcare data through MCP servers or any tool server protocol, every server that could access ePHI needs its own compliance posture.

BAA coverage for tool servers. If an AI vendor's infrastructure accesses, processes, or transmits PHI - even transiently as part of model inference - that constitutes a business associate function under HIPAA. A BAA is required. This applies to any MCP server or tool execution environment in the data path, even if it only passes data through without persisting it. If PHI is processed through the MCP layer, the operator must act as a Business Associate under an executed BAA. Customers are responsible for HIPAA compliance end-to-end, including minimum necessary access, identity and access management, and governance of PHI in prompts, outputs, and logs.

Scope tools to the minimum necessary. Don't expose a broad "do anything" tool set to an agent handling healthcare data. Restrict MCP servers to specific operation types (read-only for reporting agents, write-only for data entry agents) and specific resource categories (billing tools only, not clinical records). Exposing only minimum required tools per team role - so scheduling agents see calendar tools, not clinical documentation systems - directly implements the HIPAA "minimum necessary" standard. Tag-based tool grouping lets you create an MCP server that exposes only accounting-related tools - invoices, payments, expenses - without also exposing patient demographics or clinical data.

Isolate tool execution environments. MCP servers connect AI agents to healthcare systems like EHRs, imaging platforms, and clinical databases. The main risk is PHI exposure, HIPAA violations, and privilege escalation in dynamic AI workflows. A compromised tool server should not give an attacker lateral movement to other connected accounts or data sources. This means:

  • Per-tenant credential isolation: each connected account has its own credential context
  • Network-level separation between tool servers handling different data classifications
  • Short-lived, scoped tokens for each tool session rather than persistent broad-access credentials

Prevent token leakage to client-side layers. Provider tokens - OAuth access tokens, refresh tokens, API keys for EHR or accounting systems - must never be passed to the AI agent, the LLM, or any client-side runtime. The tool server is the only component that should ever touch these credentials. The agent sends a tool call request; the server authenticates to the third-party API on the agent's behalf. This is non-negotiable for HIPAA, and Epic's developer program explicitly requires this pattern for their APIs.

Example: HIPAA-Safe Function-Calling Sequence

Here's what a compliant AI agent workflow looks like when an agent needs to create an invoice in a healthcare customer's accounting system:

%%{init: {'themeVariables': {'fontSize': '18px'}}}%%
sequenceDiagram
    participant User as Healthcare Staff
    participant Agent as AI Agent (LLM)
    participant GW as Tool Server / MCP Gateway<br>(BAA-covered, zero-retention)
    participant Acct as Accounting API<br>(QuickBooks / Xero / NetSuite)

    User->>Agent: "Create an invoice for patient visit #4821"
    Agent->>GW: tools/call: create_invoice<br>{visit_id: "4821", amount: 350.00}
    
    Note over GW: Validate agent identity +<br>user authorization.<br>Log access event (no PHI in logs).<br>Decrypt OAuth token for this tenant.
    
    GW->>Acct: POST /invoices<br>(OAuth token attached server-side)
    Acct-->>GW: Invoice created {id: "INV-9920"}
    
    Note over GW: Strip unnecessary fields.<br>Flush response from memory.
    
    GW-->>Agent: {invoice_id: "INV-9920", status: "created"}
    Agent-->>User: "Invoice INV-9920 created for $350.00"
    
    Note over GW: Audit log entry recorded:<br>agent_id, user_id, tool, resource,<br>timestamp, outcome

Key properties of this flow:

  1. The OAuth token never leaves the tool server. The agent sees a tool schema and gets back a result. It never handles credentials for the accounting system.
  2. PHI exposure is minimized. The tool server strips the response down to just the fields the agent needs (invoice ID, status). Patient demographics, diagnosis codes, and billing details don't enter the LLM context.
  3. Every access event is logged. The audit trail captures who authorized the action, which agent executed it, what tool was called, and when - without logging the ePHI payload itself.
  4. The tool server is stateless. No API payloads are written to disk. The request is processed in memory and flushed.
  5. BAA coverage is continuous. The tool server operator has a signed BAA. The accounting platform has a BAA. The chain of custody is unbroken.

This pattern works identically for read operations. An agent fetching open invoices for bank reconciliation or pulling expense reports for audit review hits the same tool server, with the same credential isolation, the same field-level filtering, and the same audit logging.

For healthcare SaaS teams building AI agent features that touch accounting data - automated billing, expense categorization, payment reconciliation - the architecture is the compliance story. Get the execution layer right, and the rest follows.

The Integration Compliance Checklist

Here's the practical checklist for engineering teams shipping healthcare integrations:

Requirement What to verify HIPAA reference
BAA signed with integration middleware Vendor provides executed BAA before any data exchange §164.502(e), §164.504(e)
TLS 1.2+ enforced for all API traffic No plaintext API calls, certificate pinning where possible §164.312(e)(1)
ePHI encrypted at rest in your data store AES-256 encryption with proper key management §164.312(a)(2)(iv)
Audit logs for all data access Log every API call that returns ePHI, with timestamps and user identity — not payloads §164.312(b)
Scoped access via user consent End users select specific data sets at connection time §164.502(b) — Minimum Necessary
Credential encryption All OAuth tokens and API keys encrypted at rest, masked in UI §164.312(a)(1)
Incident response plan for integration failures Documented procedure for credential compromise, data exposure §164.308(a)(6)
Automatic re-auth detection System detects failed tokens and notifies your application §164.312(d)

Why Truto Is the Safest Way to Build Healthcare Integrations

Building a zero-retention proxy, managing encrypted OAuth token lifecycles, handling SMART on FHIR quirks, and maintaining field-level filtering engines requires immense engineering effort. For healthcare SaaS companies, spending those cycles on integration infrastructure distracts from core product development.

If you're evaluating how to build vs. buy your integration layer, the compliance dimension deserves serious weight. Just as we've seen compliance platforms abandon point-to-point connectors, building these integrations in-house means your team owns every aspect of HIPAA compliance for those connections: credential storage, encryption, audit logging, token refresh, and the long tail of niche healthcare tools your customers use.

Truto's architecture was designed to minimize compliance exposure by default:

Zero Data Retention Architecture. Truto acts as a pass-through proxy and does not store your customers' data at rest. Data is fetched from the third-party API, transformed in memory using predefined JSONata mappings, and delivered to your system in real time. Truto never caches or persists API payloads. This eliminates the most dangerous class of breach risk at the middleware layer.

Granular Access Control via RapidForm. Truto allows end-users to precisely scope which data is synced, adhering to HIPAA's "minimum necessary" rule. RapidForm injects dynamic forms directly into the connection flow — supporting single-select, multi-select, and dependency-aware fields. A user can select specific folders, tags, departments, or provider groups, and Truto stores these preferences as variables. Your background sync jobs then use these variables to automatically filter the data pulled from the EHR.

Enterprise-Grade Credential Security. Truto encrypts every credential field — OAuth access tokens, refresh tokens, API keys, client secrets, and passwords — at rest using AES-256. These fields are permanently masked in the UI and only decrypted at the moment of the API call. Truto handles complex token refresh logic proactively, refreshing tokens before they expire to prevent sync failures, and automatically marks accounts as needing re-authorization if refresh fails.

Unified API with Proxy Fallback. Truto offers both a normalized Unified API and a direct Proxy API. Use the unified path for common data models and consistent product behavior across multiple EHRs. Use the proxy path when the source system has a vendor-specific endpoint or response shape that doesn't fit the common model — like a proprietary Epic or Cerner endpoint. Both route through the same credential management and encryption layer.

HIPAA-Ready MCP Servers for AI Agent Workflows. Truto's MCP servers expose scoped tool sets to AI agents without the agent ever touching provider credentials. Each MCP server can be restricted by operation type (read-only, write-only) and by resource category using tag-based filtering - so an accounting agent sees only invoice, payment, and expense tools, not clinical data endpoints. Tokens are validated server-side, provider credentials are decrypted only at execution time, and servers can be set to expire automatically for temporary access scenarios. An optional second authentication layer requires the AI client to present a valid API token on top of the MCP server URL, preventing unauthorized use if the URL is exposed in logs or configuration files.

SOC 2 Type II Certified. Truto has completed two consecutive years of SOC 2 Type II audits, providing independent verification of security controls.

To be transparent about the trade-offs: a pass-through architecture means you can't query cached data in the middleware layer. If you need fast, repeated access to synced records, use Truto's sync jobs to push data into your own HIPAA-compliant data store. Truto gives you the transport and normalization; you own the storage and access controls.

Info

Need more control over your data? Truto allows you to execute custom JSONata transformations on the fly, ensuring you can strip out sensitive remote_data fields before they ever reach your servers.

What to Do Next

HIPAA compliance for integrations isn't a checkbox exercise. It's an architectural decision that affects every layer of your stack. The regulatory environment is tightening fast — On December 27, 2024, HHS issued a Notice of Proposed Rulemaking to modify the HIPAA Security Rule to strengthen cybersecurity protections for ePHI. Encryption that was technically "addressable" is becoming mandatory. Risk assessments are getting more detailed.

Here's the shortlist to push through in the next sprint cycle:

  1. Audit your integration middleware for BAA coverage. If any tool in your data flow touches ePHI and hasn't signed a BAA, that's a live HIPAA violation. Fix it before your next audit.
  2. Draw one end-to-end ePHI flow for a single integration. Include retries, logs, dead-letter queues, support tooling, and analytics. Know where PHI can land.
  3. Strip raw payloads out of logs and traces. Keep audit metadata instead. This is the single most common accidental violation.
  4. Implement scoped access at connection time. Don't sync everything because it's easier. Let your customers choose what data to share, and log that choice for audit purposes.
  5. Minimize PHI at the middleware layer. Prefer pass-through architectures. If you must cache, push data into infrastructure you control.
  6. Tabletop three incidents: compromised credentials, third-party outage, and token reauthorization failure.

The time to get your integration architecture right is before the next round of rules takes effect — not after.

FAQ

Do I need a BAA with my integration middleware provider?
Yes. Under HIPAA, any third-party service that creates, receives, maintains, or transmits ePHI on behalf of a covered entity is a business associate and must sign a BAA before any data is exchanged. This applies even if the middleware only passes data through without storing it, or stores only encrypted data it cannot view.
Does a pass-through API proxy still need to be HIPAA compliant?
Yes. Even if the proxy doesn't store ePHI at rest, it transmits ePHI and holds authentication credentials to access source systems. It must enforce encryption in transit, secure credential storage, and sign a BAA. However, the compliance burden is significantly lower than middleware that caches data.
What encryption standards does HIPAA require for API integrations?
HIPAA requires encryption of ePHI both at rest (AES-256 recommended) and in transit (TLS 1.2+ minimum, TLS 1.3 recommended). The proposed 2024 NPRM to the Security Rule would make encryption mandatory with limited exceptions, removing the previous 'addressable' classification.
What is the minimum necessary rule in API integrations?
The minimum necessary rule mandates that you only request and sync the exact subset of PHI required for your application to function. In practice, this means scoping OAuth permissions tightly, letting end users choose what data to sync at connection time, and filtering out unneeded fields before they reach your database.
How much does a healthcare data breach cost on average?
According to IBM's 2024 Cost of a Data Breach Report, the average healthcare data breach costs $9.77 million — the highest of any industry for the 14th consecutive year. This is roughly double the global cross-industry average of $4.88 million.

More from our Blog