HIPAA Compliance Checklist for SaaS Engineering Teams

A HIPAA compliance checklist for engineering teams maps the Security Rule's technical safeguards directly to automated test cases. Under 45 CFR Part 164, covered entities and business associates must implement access controls (164.312(a)), audit controls (164.312(b)), integrity controls (164.312(c)), transmission security (164.312(e)), and authentication (164.312(d)). The 2026 HIPAA Security Rule Final Rule makes MFA mandatory and removes the "addressable" classification from encryption, meaning both are now required with no flexibility. For engineering teams, each safeguard has a direct testable equivalent: access control means testing that unauthorized users cannot reach PHI endpoints; audit controls mean testing that every PHI access is logged; transmission security means testing that plaintext connections are rejected. This checklist maps all of them to code-level test cases you can run in CI.
Your compliance officer has a HIPAA checklist. It covers policy documentation, risk assessment procedures, and BAA requirements. It will not help you when an enterprise health system sends over a security questionnaire asking how you enforce unique user identification, what your audit log retention policy is at the code level, or how you verify that ePHI is never transmitted over plaintext connections.
Those are engineering questions. And the honest answer at most Series A health-tech startups is: "we think we're doing those things, but we haven't verified them with tests." That gap, between assuming you're compliant and being able to prove it, is exactly where late-stage enterprise deals fall apart.
Here is what each safeguard requires, what to test for it, and the exact code to put in your CI pipeline.
What HIPAA Compliance Means for Engineering Teams
HIPAA compliance for SaaS means that your application, not just your organization, must implement and continuously verify the Security Rule's safeguards under 45 CFR Part 164. The Security Rule divides requirements into three categories: administrative safeguards (workforce training, risk management, contingency planning), physical safeguards (facility access, workstation security), and technical safeguards (access controls, encryption, audit logging, transmission security).
This checklist focuses on the technical safeguards at 164.312 because those are the safeguards your code must implement and your tests must verify. The administrative and physical safeguards matter, but they are owned by your compliance officer. The technical safeguards are owned by your engineering team.
The Security Rule also requires a risk assessment (45 CFR 164.308(a)(1)) that identifies where ePHI is at risk in your systems. This checklist is effectively the output of that risk assessment for your technical controls: the specific tests that prove each identified risk is mitigated.
What Non-Compliance Costs
The HHS Office for Civil Rights does not treat HIPAA violations as theoretical. In 2023 alone, OCR levied $14.3 million in HIPAA settlements. Anthem paid $16 million for a breach affecting 78.8 million records. The University of Rochester Medical Center paid $3 million for failing to encrypt mobile devices. Advocate Health Care settled for $5.55 million over unencrypted laptops.
The pattern is consistent: the largest penalties target failures in technical safeguards that automated tests would have caught. Unencrypted devices, missing access controls, inadequate audit logging. These are not exotic attack vectors. They are the exact controls covered in this checklist.
For SaaS startups pursuing enterprise health-tech deals, the cost is not just regulatory. A failed vendor security assessment can stall a six-figure deal for months or kill it entirely.
BAAs and Your Infrastructure Stack
Before getting into the technical safeguards, one administrative requirement directly affects engineering: Business Associate Agreements. Any vendor that processes, stores, or transmits PHI on your behalf needs a signed BAA. For a typical SaaS stack, that means your cloud provider (AWS, GCP, or Azure all offer HIPAA BAAs), your database hosting provider, your email or SMS delivery service if it touches patient communications, your logging and monitoring platform if logs contain PHI, and your error tracking service if stack traces could expose PHI fields.
The engineering team's role here is not signing the BAAs (that is legal's job) but ensuring that the infrastructure configuration matches what the BAA requires. If your AWS BAA covers specific services, your team needs to verify that PHI only touches those covered services. That verification is testable: an infrastructure test can confirm that PHI-tagged resources only use BAA-covered service types.
The 2026 Security Rule Changes You Cannot Ignore
Before getting into the checklist, the 2026 updates matter because they change what is optional.

The original HIPAA Security Rule (2003) divided implementation specifications into "required" and "addressable." Required meant you had to do it. Addressable meant you had to implement it, or document why an equivalent measure was used instead, or document why it wasn't reasonable and appropriate. Addressable was widely treated as optional in practice.
The 2026 HIPAA Security Rule Final Rule removes that ambiguity for two critical areas. MFA is now required, not addressable. Encryption of ePHI at rest and in transit is now required, not addressable. If you are currently relying on compensating controls or documented exceptions for either of these, that posture is no longer defensible.
The rule also adds new requirements around network segmentation, vulnerability scanning, and incident response testing. But MFA and encryption are the two that will catch engineering teams off guard, because they were commonly deferred as "addressable" under the old rule.
What this means in practice: your test suite needs explicit tests for MFA enforcement and encryption enforcement. Not "we plan to implement" but "here is a test that fails if MFA is not enforced on PHI access routes."
Access Controls (164.312(a)(1)): Who Can Reach PHI
What the regulation requires: Unique user identification, emergency access procedures, automatic logoff, and encryption/decryption. The core intent is that access to ePHI must be limited to authorized users, and that access must be tied to individual identities (no shared accounts).
What to test: The access control surface for a typical SaaS is larger than most engineering teams realize. It includes authentication gates on every PHI endpoint, role-based access enforcement, automatic session expiration, and the ability to revoke access immediately when an employee leaves.
The tests that catch real failures are the negative-path tests: what happens when an unauthenticated request hits a PHI endpoint, what happens when a user with the wrong role tries to access another user's records, what happens when a session token expires.
# test_access_controls.py
import pytest
import requests
import time
BASE_URL = "https://api.yourapp.com"
class TestHIPAAAccessControls:
"""Tests for HIPAA 164.312(a)(1) - Access Control"""
def test_phi_endpoint_requires_authentication(self):
"""Unauthenticated requests to PHI endpoints must return 401, not 403 or 200"""
phi_endpoints = [
"/api/patients",
"/api/patients/123/records",
"/api/records/search",
"/api/encounters/456",
]
for endpoint in phi_endpoints:
response = requests.get(f"{BASE_URL}{endpoint}")
assert response.status_code == 401, (
f"PHI endpoint {endpoint} returned {response.status_code} "
f"without authentication. Expected 401."
)
def test_role_based_access_enforcement(self, auth_tokens):
"""A billing user must not be able to read clinical records"""
billing_token = auth_tokens["billing_user"]
response = requests.get(
f"{BASE_URL}/api/patients/123/clinical-notes",
headers={"Authorization": f"Bearer {billing_token}"}
)
assert response.status_code == 403, (
f"Billing user accessed clinical records endpoint. "
f"HIPAA 164.312(a)(1) role enforcement failed."
)
def test_cross_patient_access_blocked(self, auth_tokens):
"""A patient must not be able to access another patient's records"""
patient_a_token = auth_tokens["patient_a"]
patient_b_id = auth_tokens["patient_b_id"]
response = requests.get(
f"{BASE_URL}/api/patients/{patient_b_id}/records",
headers={"Authorization": f"Bearer {patient_a_token}"}
)
assert response.status_code in [403, 404], (
f"Patient A accessed Patient B's records. "
f"Horizontal privilege escalation possible."
)
def test_session_expiry_enforced(self, auth_tokens):
"""An expired session token must not grant access"""
expired_token = auth_tokens["expired"]
response = requests.get(
f"{BASE_URL}/api/patients",
headers={"Authorization": f"Bearer {expired_token}"}
)
assert response.status_code == 401, (
f"Expired session token returned {response.status_code}. "
f"Session expiry not enforced."
)Common failure modes: Most teams test the happy path (valid user can access their records) and miss the negative paths. Shared service accounts that bypass individual user identification are a persistent finding in audits. Automatic logoff is often implemented in the frontend only, leaving API tokens with no server-side expiry.
MFA Enforcement (164.312(d) + 2026 Rule): Now Mandatory
What the regulation requires: The 2026 rule makes multi-factor authentication mandatory for all workforce members accessing ePHI. The original "authentication" specification at 164.312(d) required verifying that a person is who they claim to be; the 2026 rule specifies that MFA is the required mechanism.
What to test: MFA enforcement is surprisingly easy to miss in tests because most testing happens with pre-authenticated tokens. The critical test is whether the authentication flow actually enforces a second factor, and whether that enforcement can be bypassed.
# test_mfa_enforcement.py
import pytest
import requests
class TestMFAEnforcement:
"""Tests for HIPAA 164.312(d) - Authentication, 2026 MFA requirement"""
def test_login_without_mfa_does_not_grant_phi_access(self):
"""
A login with only username/password (step 1 of MFA) must not
return a token that grants access to PHI endpoints.
"""
# Authenticate with valid credentials but no MFA code
response = requests.post(f"{BASE_URL}/auth/login", json={
"email": "provider@clinic.com",
"password": "ValidPassword123!"
})
assert response.status_code == 200
partial_token = response.json().get("partial_token")
assert partial_token is not None
# Attempt to use the partial token to access PHI
phi_response = requests.get(
f"{BASE_URL}/api/patients",
headers={"Authorization": f"Bearer {partial_token}"}
)
assert phi_response.status_code == 401, (
f"Partial (pre-MFA) token granted access to PHI. "
f"MFA enforcement bypassed. HIPAA 2026 violation."
)
def test_mfa_required_for_admin_phi_routes(self, admin_tokens):
"""Admin routes that expose PHI must reject non-MFA sessions"""
non_mfa_admin_token = admin_tokens["no_mfa"]
response = requests.get(
f"{BASE_URL}/admin/patients/export",
headers={"Authorization": f"Bearer {non_mfa_admin_token}"}
)
assert response.status_code in [401, 403], (
f"PHI export route accessible without MFA. "
f"Admin bulk access requires MFA under 2026 HIPAA rule."
)Common failure modes: MFA enforced in the web UI but not on API endpoints. Mobile apps using a separate auth flow that skips MFA. Password reset flows that bypass MFA entirely and issue full-access tokens.
Audit Controls (164.312(b)): Every PHI Access Must Be Logged
What the regulation requires: Implement hardware, software, and/or procedural mechanisms that record and examine activity in information systems that contain or use ePHI. This means every read, write, update, and delete of PHI must generate an audit record with who did it, when, and what they accessed.
What to test: The audit log tests are some of the most important and least commonly written tests in health-tech codebases. You are not just testing that the log exists; you are testing that the log is correct, that it captures the right fields, and that it cannot be tampered with.
# test_audit_controls.py
import pytest
import requests
from datetime import datetime, timezone
class TestAuditControls:
"""Tests for HIPAA 164.312(b) - Audit Controls"""
def test_phi_read_generates_audit_log(self, auth_tokens, audit_log_client):
"""Every PHI read must create an audit log entry"""
before_access = datetime.now(timezone.utc)
provider_token = auth_tokens["provider"]
patient_id = "patient-test-001"
requests.get(
f"{BASE_URL}/api/patients/{patient_id}/records",
headers={"Authorization": f"Bearer {provider_token}"}
)
# Query your audit log store (Elasticsearch, CloudWatch, etc.)
logs = audit_log_client.search(
resource_id=patient_id,
after=before_access,
action="READ"
)
assert len(logs) >= 1, (
f"No audit log generated for PHI read on patient {patient_id}. "
f"HIPAA 164.312(b) requires all PHI access to be logged."
)
log = logs[0]
required_fields = ["user_id", "timestamp", "resource_type",
"resource_id", "action", "ip_address", "outcome"]
for field in required_fields:
assert field in log, (
f"Audit log missing required field: {field}. "
f"HIPAA audit logs must capture who, what, when, and from where."
)
def test_failed_access_attempt_logged(self, auth_tokens, audit_log_client):
"""Denied access attempts must also be logged, not just successful ones"""
before = datetime.now(timezone.utc)
billing_token = auth_tokens["billing_user"]
requests.get(
f"{BASE_URL}/api/patients/123/clinical-notes",
headers={"Authorization": f"Bearer {billing_token}"}
)
logs = audit_log_client.search(
after=before,
action="READ",
outcome="DENIED"
)
assert len(logs) >= 1, (
f"Failed PHI access attempt not logged. "
f"Audit controls must capture denied access, not just successful access."
)
def test_audit_logs_not_modifiable_by_application(self, auth_tokens):
"""Application-level tokens must not be able to modify audit logs"""
admin_token = auth_tokens["admin"]
response = requests.delete(
f"{BASE_URL}/api/audit-logs/some-log-id",
headers={"Authorization": f"Bearer {admin_token}"}
)
# 404 (route doesn't exist) or 403 (forbidden) are both acceptable
assert response.status_code in [403, 404, 405], (
f"Application token can delete audit logs. "
f"Audit log integrity compromised. HIPAA 164.312(b) violation."
)Common failure modes: Audit logging is implemented for production but disabled in test and staging environments. Log entries exist but are missing user IDs (especially for service-to-service calls). Background jobs that access PHI don't generate audit logs because they run outside the request context.
Integrity Controls (164.312(c)(1)): PHI Must Not Be Altered Undetectably
What the regulation requires: Implement security measures to ensure that ePHI is not improperly altered or destroyed, and implement electronic mechanisms to corroborate that ePHI has not been altered or destroyed in an unauthorized manner.
What to test: Integrity is harder to test than access control because you are testing for the absence of a property (undetectable alteration) rather than a binary pass/fail. The practical test surface includes checksums or hashes on critical records, immutable audit trails, and that bulk delete or update operations require elevated authorization.
# test_integrity_controls.py
import pytest
import requests
import hashlib
class TestIntegrityControls:
"""Tests for HIPAA 164.312(c)(1) - Integrity Controls"""
def test_clinical_record_includes_integrity_hash(self, auth_tokens):
"""Clinical records must include an integrity hash or signature field"""
provider_token = auth_tokens["provider"]
response = requests.get(
f"{BASE_URL}/api/patients/123/clinical-notes/latest",
headers={"Authorization": f"Bearer {provider_token}"}
)
assert response.status_code == 200
record = response.json()
# Records must carry a server-computed hash of their content
assert "integrity_hash" in record or "content_hash" in record, (
f"Clinical record missing integrity hash. "
f"PHI records must support tamper detection per 164.312(c)(1)."
)
def test_bulk_phi_deletion_requires_admin_plus_reason(self, auth_tokens):
"""Bulk deletion of PHI must require elevated authorization and a documented reason"""
standard_admin_token = auth_tokens["admin"]
response = requests.delete(
f"{BASE_URL}/api/patients/bulk",
headers={"Authorization": f"Bearer {standard_admin_token}"},
json={"patient_ids": ["123", "456"]}
)
assert response.status_code in [403, 422], (
f"Bulk PHI deletion succeeded without elevated authorization or reason. "
f"Integrity controls require safeguards against unauthorized mass deletion."
)Common failure modes: Integrity hashes computed client-side (easily spoofed). Soft deletes implemented as a flag flip with no audit record of who deleted what. No controls on bulk operations through admin tools or database migrations.
Transmission Security (164.312(e)(1)): Encryption Is Now Required
What the regulation requires: Implement technical security measures to guard against unauthorized access to ePHI being transmitted over an electronic communications network. The 2026 rule moves encryption of data in transit from addressable to required, meaning TLS is no longer optional.
What to test: The tests here seem obvious (check that HTTPS is enforced) but the failure modes are more subtle. The real tests are whether HTTP connections are rejected (not redirected), whether TLS version is enforced, and whether your internal service-to-service communication uses encryption (not just your public-facing API).
# test_transmission_security.py
import pytest
import requests
import ssl
import socket
class TestTransmissionSecurity:
"""Tests for HIPAA 164.312(e)(1) - Transmission Security (2026: required)"""
def test_http_connections_rejected_not_redirected(self):
"""
PHI endpoints must reject plain HTTP connections outright.
A redirect to HTTPS is insufficient -- the initial request
already traveled in plaintext.
"""
try:
response = requests.get(
"http://api.yourapp.com/api/patients",
allow_redirects=False,
timeout=5
)
# If we get any 2xx or redirect, that's a failure
assert response.status_code not in [200, 301, 302], (
f"HTTP request to PHI endpoint returned {response.status_code}. "
f"Plain HTTP must be rejected at the connection level (HSTS or firewall), "
f"not redirected. 2026 HIPAA encryption requirement."
)
except requests.exceptions.ConnectionError:
# Connection refused at network level = correct behavior
pass
def test_tls_version_minimum_enforced(self):
"""TLS 1.0 and 1.1 must not be accepted; minimum TLS 1.2 required"""
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
context.maximum_version = ssl.TLSVersion.TLSv1_1
try:
with socket.create_connection(("api.yourapp.com", 443), timeout=5) as sock:
with context.wrap_socket(sock) as ssock:
# If TLS 1.1 handshake succeeds, the server accepts it
pytest.fail(
f"Server accepted TLS 1.1 connection. "
f"Minimum TLS 1.2 required for HIPAA transmission security. "
f"Negotiated: {ssock.version()}"
)
except ssl.SSLError:
# Handshake failure = correct behavior
pass
def test_phi_api_enforces_https_strict_transport(self, auth_tokens):
"""PHI API responses must include HSTS header"""
response = requests.get(
f"{BASE_URL}/api/patients",
headers={"Authorization": f"Bearer {auth_tokens['provider']}"}
)
hsts = response.headers.get("Strict-Transport-Security", "")
assert "max-age=" in hsts, (
f"PHI endpoint missing Strict-Transport-Security header. "
f"HSTS is required to enforce HTTPS at the client level."
)
max_age = int(hsts.split("max-age=")[1].split(";")[0].strip())
assert max_age >= 31536000, (
f"HSTS max-age is {max_age} seconds. "
f"Minimum 1 year (31536000s) recommended for PHI endpoints."
)Common failure modes: HTTPS enforced on the public API but internal microservice communication runs over HTTP. TLS 1.0/1.1 still accepted for backward compatibility. HSTS header present but with a short max-age that browsers don't honor. If your team is deciding between static and dynamic security testing approaches for these checks, our SAST vs DAST comparison covers the trade-offs.
Encryption at Rest (2026 Security Rule): No Longer Addressable
This was addressable under the original rule, which is why so many teams treated it as optional. Under the 2026 rule, encryption of ePHI at rest is required. If you store PHI in a database, object storage, or backup, it must be encrypted.
The test for encryption at rest is different from the others in this checklist. You cannot write an API-level test that verifies database encryption, because by the time the API responds, the decryption has already happened. The verification has to happen at the infrastructure level.
# test_encryption_at_rest.py
import pytest
import boto3 # AWS example; adapt for your cloud provider
class TestEncryptionAtRest:
"""Tests for 2026 HIPAA encryption-at-rest requirement"""
def test_rds_storage_encrypted(self):
"""RDS instances storing PHI must have storage encryption enabled"""
rds = boto3.client("rds", region_name="us-east-1")
instances = rds.describe_db_instances()["DBInstances"]
phi_instances = [
i for i in instances
if any(tag["Key"] == "contains-phi" and tag["Value"] == "true"
for tag in rds.list_tags_for_resource(
ResourceName=i["DBInstanceArn"])["TagList"])
]
for instance in phi_instances:
assert instance["StorageEncrypted"], (
f"RDS instance {instance['DBInstanceIdentifier']} storing PHI "
f"does not have storage encryption enabled. "
f"2026 HIPAA rule requires encryption at rest. Not addressable."
)
def test_s3_buckets_with_phi_encrypted(self):
"""S3 buckets tagged as containing PHI must enforce server-side encryption"""
s3 = boto3.client("s3", region_name="us-east-1")
buckets = s3.list_buckets()["Buckets"]
for bucket in buckets:
try:
tags = s3.get_bucket_tagging(Bucket=bucket["Name"])
tag_dict = {t["Key"]: t["Value"] for t in tags["TagSet"]}
except s3.exceptions.ClientError:
continue # No tags = no PHI
if tag_dict.get("contains-phi") != "true":
continue
encryption = s3.get_bucket_encryption(Bucket=bucket["Name"])
rules = encryption["ServerSideEncryptionConfiguration"]["Rules"]
assert len(rules) > 0, (
f"S3 bucket {bucket['Name']} tagged as containing PHI "
f"has no server-side encryption configured. "
f"2026 HIPAA encryption-at-rest requirement not met."
)Common failure modes: Database encryption enabled but database backups stored unencrypted. PHI in application logs (which are often stored without encryption). Object storage used for file exports or report generation with no encryption policy.
The Full HIPAA Compliance Checklist: Safeguards to Test Cases

| Regulation | Safeguard | Test to Write | 2026 Change |
|---|---|---|---|
| 164.312(a)(1) | Access Control | Unauthenticated requests return 401; role-based access enforced; cross-patient access blocked | No change; still required |
| 164.312(a)(2)(i) | Unique User Identification | No shared credentials in test fixtures; every audit log entry has a non-null user ID | No change |
| 164.312(a)(2)(iii) | Automatic Logoff | Session tokens expire server-side; expired tokens return 401 | No change |
| 164.312(b) | Audit Controls | Every PHI read/write generates a log with user, time, resource, IP, outcome | New: logging for security incidents required within 24 hours |
| 164.312(c)(1) | Integrity | Records carry integrity hashes; bulk deletion requires elevated auth | No change |
| 164.312(d) | Authentication / MFA | Pre-MFA tokens do not access PHI; admin routes require MFA session | MFA now required (was addressable) |
| 164.312(e)(1) | Transmission Security | Plain HTTP rejected; TLS 1.0/1.1 rejected; HSTS header present with 1y max-age | Encryption now required (was addressable) |
| 164.312(e)(2)(ii) | Encryption at Rest | Infrastructure tests: RDS/S3 tagged as PHI storage have encryption enabled | Required (was addressable) |
Running HIPAA Compliance Tests in CI

The tests in this checklist fall into two categories that need different CI placement.
API-level tests (access control, MFA, audit logs, transmission security) can run on every pull request against a staging environment that mirrors production. They are fast, deterministic, and catch regressions immediately. Put them in the same test suite as your existing end-to-end tests.
Infrastructure-level tests (encryption at rest) run against real cloud resources, which means they need cloud credentials and should run on a schedule (nightly or on deployment) rather than on every PR. Keep them in a separate CI job that fails loudly and pages the on-call team.
# .github/workflows/hipaa-compliance.yml
name: HIPAA Compliance Tests
on:
push:
branches: [main, staging]
schedule:
- cron: '0 2 * * *' # Nightly infrastructure checks
jobs:
api-safeguards:
name: API-Level HIPAA Safeguards
runs-on: ubuntu-latest
environment: staging
steps:
- uses: actions/checkout@v4
- name: Run access control tests
run: pytest tests/hipaa/test_access_controls.py -v
- name: Run MFA enforcement tests
run: pytest tests/hipaa/test_mfa_enforcement.py -v
- name: Run audit control tests
run: pytest tests/hipaa/test_audit_controls.py -v
- name: Run transmission security tests
run: pytest tests/hipaa/test_transmission_security.py -v
infrastructure-safeguards:
name: Infrastructure-Level HIPAA Safeguards
runs-on: ubuntu-latest
if: github.event_name == 'schedule' || github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_HIPAA_AUDIT_ROLE }}
aws-region: us-east-1
- name: Run encryption at rest tests
run: pytest tests/hipaa/test_encryption_at_rest.py -vThe key discipline is treating HIPAA compliance tests the same as any other test: they live in source control, they run automatically, and a failure blocks deployment. The alternative, which is periodic manual audits, is what creates the compliance gaps that enterprise deals surface.
Where HIPAA Automated Testing Fits the Full Picture
A checklist like this covers the "technical safeguards" section of HIPAA. The full Security Rule also requires administrative safeguards (workforce training, access management procedures, contingency planning) and physical safeguards (facility access, workstation security). Those cannot be automated in the same way. But the technical safeguards can be, and they should be.
The shift that matters most is from "we have a policy" to "we have a passing test." A policy says you enforce MFA. A passing test proves it. An enterprise security reviewer knows the difference immediately.
For health-tech teams running compliance automation at scale, Autonoma connects to your codebase and generates these test cases automatically. The Planner agent reads your routes, authentication flows, and PHI-touching endpoints, then generates test cases covering the access control, audit, and transmission security surfaces described in this checklist. When your code changes, the tests update. When requirements change (as they did with the 2026 Security Rule), you re-run the planner against the updated spec.
That is the difference between compliance as a quarterly audit exercise and compliance as a continuous engineering property. The first approach produces a document. The second approach produces a passing CI pipeline.
If you are building a compliance testing strategy that goes beyond HIPAA, our GDPR compliance testing guide covers the equivalent safeguard-to-test mapping for European data protection regulations. For teams handling PHI in non-production environments, our data masking tools comparison covers how to protect sensitive data in test environments, and our data anonymization guide explains the techniques behind masking, pseudonymization, and synthetic data generation.
A HIPAA compliance checklist for engineering teams maps the Security Rule's technical safeguards (45 CFR 164.312) to specific automated test cases. Unlike compliance officer checklists that focus on policies and documentation, an engineering checklist specifies what to test: access control means testing that unauthenticated requests to PHI endpoints return 401; audit controls mean testing that every PHI access generates a log entry with user ID, timestamp, resource, and outcome; transmission security means testing that plain HTTP is rejected and TLS 1.0/1.1 are not accepted. Tools like Autonoma can generate and run these test cases from your codebase automatically.
The 2026 HIPAA Security Rule Final Rule made two major changes relevant to engineering teams. First, MFA (multi-factor authentication) is now required for all workforce members accessing ePHI, removing the previous 'addressable' classification that allowed exceptions. Second, encryption of ePHI at rest and in transit is now required, not addressable. This means teams that previously used compensating controls or documented exceptions for either MFA or encryption are now out of compliance. The rule also adds requirements for network segmentation, vulnerability scanning, and incident response testing.
HIPAA access control tests (164.312(a)(1)) should include: negative-path tests that verify unauthenticated requests return 401 (not 200 or 403); role-based access tests that verify users with the wrong role cannot access PHI they are not authorized for; horizontal privilege escalation tests that verify patient A cannot access patient B's records; and session expiry tests that verify expired tokens return 401. These tests should run against a staging environment on every pull request. The most common gaps are missing tests for the negative path (unauthorized access) rather than the happy path.
Under the 2026 HIPAA Security Rule Final Rule, yes, encryption of ePHI at rest is now required. Previously it was classified as 'addressable,' which allowed organizations to use documented compensating controls instead. That flexibility no longer exists. For cloud-hosted applications, this means RDS instances and S3 buckets storing PHI must have server-side encryption enabled, and database backups must also be encrypted. Infrastructure-level tests using your cloud provider's SDK (AWS boto3, GCP SDK, Azure SDK) can verify these settings automatically in a nightly CI job.
HIPAA 164.312(b) requires audit controls that record and examine activity in systems containing ePHI, but does not specify exact fields. In practice, defensible audit logs for HIPAA should capture: user ID (not just session ID), timestamp with timezone, resource type (e.g., 'patient_record'), resource ID, action (READ, WRITE, UPDATE, DELETE), IP address or request origin, and outcome (SUCCESS or DENIED). Denied access attempts must be logged, not just successful ones. Audit logs must be stored in a system that application-level tokens cannot modify or delete.
HIPAA compliance cost for a SaaS startup varies widely based on your starting point. If you are building greenfield with compliance in mind, the incremental cost is primarily engineering time to implement the technical safeguards (access controls, audit logging, encryption) plus tooling for compliance documentation and vendor BAAs. A realistic estimate for a Series A company starting from scratch is 2-4 engineer-months to build the technical controls, plus ongoing audit and policy work. The highest-ROI action is writing automated tests for the technical safeguards from the start, which prevents compliance debt from accumulating as you scale. Tools like Autonoma reduce the ongoing cost by keeping HIPAA test coverage current as your code changes.
HIPAA compliance for SaaS companies means implementing the technical, administrative, and physical safeguards required under the HIPAA Security Rule (45 CFR Part 164) when your product creates, receives, maintains, or transmits protected health information (PHI). For SaaS, the most important requirements are: signing Business Associate Agreements (BAAs) with any vendor that processes PHI on your behalf (AWS, GCP, your database provider); implementing the technical safeguards (access control, audit logging, encryption, integrity controls, transmission security); training your workforce on HIPAA requirements; and maintaining documentation of your compliance program. The 2026 Security Rule Final Rule adds MFA and encryption as explicitly required controls.
