Skip to main content

AI & assistant-friendly summary

This section provides structured content for AI assistants and search engines. You can cite or summarize it when referencing this page.

Summary

HIPAA on AWS build guide: BAA via Artifact, eligible services, KMS/VPC/RDS/S3 patterns. July 2026 engineering checklist.

Key Facts

  • HIPAA on AWS build guide: BAA via Artifact, eligible services, KMS/VPC/RDS/S3 patterns
  • July 2026 engineering checklist
  • Compliance Leads assembling BAA + risk assessment evidence should start with HIPAA on AWS: The Compliance Lead's Audit-Ready Checklist
  • Clinical data-plane (HealthLake, HealthImaging): Healthcare Digital Health on AWS (2026)
  • AWS does not “make you HIPAA compliant” by account creation alone

Entity Definitions

Lambda
Lambda is an AWS service discussed in this article.
EC2
EC2 is an AWS service discussed in this article.
S3
S3 is an AWS service discussed in this article.
RDS
RDS is an AWS service discussed in this article.
DynamoDB
DynamoDB is an AWS service discussed in this article.
CloudWatch
CloudWatch is an AWS service discussed in this article.
IAM
IAM is an AWS service discussed in this article.
VPC
VPC is an AWS service discussed in this article.

How to Implement a HIPAA-Compliant Architecture on AWS — An Engineer's Build Guide

Quick summary: HIPAA on AWS build guide: BAA via Artifact, eligible services, KMS/VPC/RDS/S3 patterns. July 2026 engineering checklist.

Key Takeaways

  • HIPAA on AWS build guide: BAA via Artifact, eligible services, KMS/VPC/RDS/S3 patterns
  • July 2026 engineering checklist
  • Compliance Leads assembling BAA + risk assessment evidence should start with HIPAA on AWS: The Compliance Lead's Audit-Ready Checklist
  • Clinical data-plane (HealthLake, HealthImaging): Healthcare Digital Health on AWS (2026)
  • AWS does not “make you HIPAA compliant” by account creation alone
How to Implement a HIPAA-Compliant Architecture on AWS — An Engineer's Build Guide
Table of Contents

Looking for the audit-prep checklist? This is the engineering build manual. Compliance Leads assembling BAA + risk assessment evidence should start with HIPAA on AWS: The Compliance Lead’s Audit-Ready Checklist. Clinical data-plane (HealthLake, HealthImaging): Healthcare Digital Health on AWS (2026).

As of July 2026, HIPAA on AWS still means four gates: (1) accept the AWS BAA in Artifact, (2) put PHI only on HIPAA-eligible services, (3) configure encryption / logging / least privilege, (4) collect continuous evidence (Config, CloudTrail, access reviews). AWS does not “make you HIPAA compliant” by account creation alone.

First-party benchmark (illustrative): a healthtech SaaS with PHI in RDS + S3 typically needs org CloudTrail, CMKs, private subnets, and Config rules before go-live — retrofit encryption is weeks of cutover, not a checkbox.

Reproduce this: HIPAA AWS build checklist

Counter-case: encrypting everything without a BAA (or using a non-eligible service on the PHI path) still fails an audit.

This guide is for architects/engineers: KMS, VPC, RDS/S3/Lambda patterns, IaC, and validation.

Step 1: Understand HIPAA Architecture Requirements

HIPAA compliance requires three layers:

Layer 1: Data Protection

  • Encryption at rest (data stored on disk)
  • Encryption in transit (data moving over network)
  • Access controls (who can read/write data)

Layer 2: Audit & Monitoring

  • CloudTrail logs (all API calls)
  • CloudWatch logs (application and system logs)
  • Config rules (resource compliance checking)
  • VPC Flow Logs (network traffic)

Layer 3: Incident Response & Governance

  • Incident response plan (documented, tested)
  • Data breach notification process
  • Business continuity/disaster recovery
  • Access reviews (quarterly)
  • Encryption key management

Example compliant architecture:

Patient Data

API Gateway (TLS, WAF)

Lambda (encrypted environment variables, no logging of PHI)

RDS (encrypted at rest, encrypted backups)

CloudTrail (all API calls logged)

S3 (encrypted, versioning, MFA delete enabled)

Audit Trail (CloudWatch Logs → S3 → Glacier for retention)

Step 2: Request a Business Associate Agreement (BAA)

Before deploying anything, sign a BAA with AWS.

  1. Go to AWS ConsoleComplianceBusiness Associate Addendum
  2. Click Request BAA
  3. Fill in organization info, expected data volumes
  4. Submit (AWS reviews in 5-10 business days)
  5. Once approved, sign electronically

Cost: Free. BAA is not a product; it’s a legal agreement that makes AWS services HIPAA-eligible for your account.

Step 3: Use HIPAA-Eligible AWS Services

Must-Use Services:

  • Compute: EC2, Lambda, Fargate
  • Storage: S3, EBS
  • Database: RDS (MySQL, PostgreSQL, Oracle), DynamoDB
  • Logging: CloudTrail, CloudWatch Logs
  • Encryption: KMS, Secrets Manager
  • Networking: VPC, API Gateway, NLB
  • Monitoring: Config, GuardDuty, Security Hub

Must-Avoid Services:

  • Alexa (voice, not HIPAA-eligible)
  • Amazon Connect (speech recognition)
  • Public S3 buckets (unless intentional)
  • Default VPC (use custom VPC for isolation)

Verify Your Architecture

Before building, audit the services:

  • No ineligible services
  • All storage encrypted by default
  • All data in transit uses TLS
  • Logging enabled on all resources

Step 4: Configure Encryption at Rest

S3 Buckets

Create S3 bucket with encryption enforced:

aws s3api create-bucket \
  --bucket my-hipaa-bucket \
  --region us-east-1

# Enable default encryption (AES-256)
aws s3api put-bucket-encryption \
  --bucket my-hipaa-bucket \
  --server-side-encryption-configuration '{
    "Rules": [{
      "ApplyServerSideEncryptionByDefault": {
        "SSEAlgorithm": "aws:kms",
        "KMSMasterKeyID": "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012"
      },
      "BucketKeyEnabled": true
    }]
  }'

# Block public access
aws s3api put-public-access-block \
  --bucket my-hipaa-bucket \
  --public-access-block-configuration "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"

# Enable versioning (for audit trail)
aws s3api put-bucket-versioning \
  --bucket my-hipaa-bucket \
  --versioning-configuration Status=Enabled

# Enable MFA delete (requires root account MFA)
aws s3api put-bucket-versioning \
  --bucket my-hipaa-bucket \
  --versioning-configuration Status=Enabled,MFADelete=Enabled \
  --mfa "arn:aws:iam::123456789012:mfa/root-account-mfa-device 123456"

RDS Database

Create encrypted RDS instance:

aws rds create-db-instance \
  --db-instance-identifier hipaa-db \
  --db-instance-class db.t4g.medium \
  --engine postgres \
  --allocated-storage 100 \
  --storage-encrypted \
  --kms-key-id arn:aws:kms:us-east-1:123456789012:key/12345 \
  --backup-retention-period 30 \
  --copy-tags-to-snapshot \
  --enable-cloudwatch-logs-exports postgresql \
  --storage-type gp3 \
  --no-publicly-accessible \
  --db-subnet-group-name hipaa-db-subnet-group

EBS Volumes

Encrypt all EC2 EBS volumes:

# Enable default EBS encryption in region
aws ec2 enable-ebs-encryption-by-default --region us-east-1
aws ec2 create-volume \
  --size 100 \
  --availability-zone us-east-1a \
  --volume-type gp3 \
  --encrypted \
  --kms-key-id arn:aws:kms:us-east-1:123456789012:key/12345

Step 5: Configure Encryption in Transit

API Gateway (TLS Enforced)

# Create REST API with TLS enforced
aws apigateway create-rest-api \
  --name hipaa-api \
  --endpoint-configuration types=REGIONAL

# Create deployment with TLS 1.2+ only
aws apigateway create-deployment \
  --rest-api-id xxxxx \
  --stage-name prod \
  --stage-variables {"minTlsVersion": "TLS1.2"}

RDS Connection (SSL/TLS)

import psycopg2
import ssl

connection = psycopg2.connect(
    host="hipaa-db.xxxxx.us-east-1.rds.amazonaws.com",
    user="postgres",
    password="password",
    database="hipaa_db",
    sslmode="require"  # Enforce TLS
)

Lambda Environment Variables (Encrypted)

import boto3
import json

secrets_client = boto3.client('secretsmanager', region_name='us-east-1')

# Store PHI-related secrets in Secrets Manager (encrypted by default)
secret_response = secrets_client.create_secret(
    Name='hipaa/db-password',
    SecretString=json.dumps({'password': 'xxxxxx'}),
    KmsKeyId='arn:aws:kms:us-east-1:123456789012:key/12345'
)

# Lambda retrieves at runtime
def lambda_handler(event, context):
    secret = secrets_client.get_secret_value(SecretId='hipaa/db-password')
    return {'statusCode': 200}

Step 6: Configure Audit Logging

CloudTrail (API Calls)

Enable CloudTrail to log all API activity:

aws cloudtrail create-trail \
  --name hipaa-trail \
  --s3-bucket-name hipaa-cloudtrail-logs \
  --is-multi-region-trail

# Enable logging
aws cloudtrail start-logging --trail-name hipaa-trail

# Enable CloudTrail Insights (detects unusual activity)
aws cloudtrail put-insight-selectors \
  --trail-name hipaa-trail \
  --insight-selectors '{"InsightType": "ApiCallRateInsight"}'

CloudWatch Logs (Application & System Logs)

import logging
import json
from datetime import datetime

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def log_hipaa_event(action, user_id, resource_id):
    """Log HIPAA-relevant events without logging PHI"""
    log_entry = {
        'timestamp': datetime.utcnow().isoformat(),
        'action': action,
        'user_id': user_id,
        'resource_id': resource_id,
        'status': 'success'
    }
    logger.info(json.dumps(log_entry))

# In Lambda or application
log_hipaa_event('patient_record_accessed', 'user-123', 'patient-456')

VPC Flow Logs (Network Traffic)

aws ec2 create-flow-logs \
  --resource-type VPC \
  --resource-ids vpc-12345 \
  --traffic-type ALL \
  --log-destination-type cloud-watch-logs \
  --log-group-name /aws/vpc/hipaa-flow-logs

CloudWatch Alarms (Anomaly Detection)

aws cloudwatch put-metric-alarm \
  --alarm-name "Unauthorized-S3-Access" \
  --alarm-description "Alert on unusual S3 access patterns" \
  --metric-name UnauthorizedAPICallsEventCount \
  --namespace CloudTrailMetrics \
  --statistic Sum \
  --period 300 \
  --threshold 1 \
  --comparison-operator GreaterThanOrEqualToThreshold \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:hipaa-alerts

Step 7: Enforce Access Controls

IAM Policy (Least Privilege)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ReadPatientData",
      "Effect": "Allow",
      "Action": ["rds:DescribeDBInstances", "secretsmanager:GetSecretValue"],
      "Resource": [
        "arn:aws:rds:us-east-1:123456789012:db:hipaa-db",
        "arn:aws:secretsmanager:us-east-1:123456789012:secret:hipaa/*"
      ],
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": "10.0.0.0/8"
        }
      }
    }
  ]
}

VPC Security Groups (Network Isolation)

# Only allow database access from app tier
aws ec2 authorize-security-group-ingress \
  --group-id sg-db \
  --protocol tcp \
  --port 5432 \
  --source-security-group-id sg-app

# Deny all inbound by default
aws ec2 describe-security-groups \
  --group-ids sg-db \
  --query 'SecurityGroups[0].IpPermissions' empty (no inbound rules except app tier)

Step 8: Validate HIPAA Compliance

AWS Config Rules

Set up Config rules to continuously check compliance:

aws configservice put-config-rule --config-rule '{
  "ConfigRuleName": "s3-bucket-server-side-encryption-enabled",
  "Description": "S3 buckets must have encryption enabled",
  "Source": {
    "Owner": "AWS",
    "SourceIdentifier": "S3_BUCKET_SERVER_SIDE_ENCRYPTION_ENABLED"
  }
}'

aws configservice put-config-rule --config-rule '{
  "ConfigRuleName": "encrypted-volumes",
  "Description": "EBS volumes must be encrypted",
  "Source": {
    "Owner": "AWS",
    "SourceIdentifier": "ENCRYPTED_VOLUMES"
  }
}'

aws configservice put-config-rule --config-rule '{
  "ConfigRuleName": "rds-encryption-enabled",
  "Description": "RDS must have encryption enabled",
  "Source": {
    "Owner": "AWS",
    "SourceIdentifier": "RDS_STORAGE_ENCRYPTED"
  }
}'

Security Hub (Compliance Dashboard)

Enable AWS Security Hub for continuous monitoring:

aws securityhub create-hub --region us-east-1

# Enable HIPAA standards
aws securityhub batch-enable-standards \
  --standards-subscription-requests '[{
    "StandardsArn": "arn:aws:securityhub:us-east-1::standards/aws-foundational-security-best-practices/v/1.0.0"
  }]'

View compliance status in the console: AWS Security HubComplianceHIPAA Status

Step 9: Production Compliance Patterns

Pattern 1: Data Classification

Tag all resources with data sensitivity:

aws ec2 create-tags --resources vol-12345 --tags Key=DataClassification,Value=PHI

# Use tags to restrict access
aws iam put-role-policy --role-name app-role --policy-name tag-policy --policy-document '{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": "ec2:*",
    "Resource": "*",
    "Condition": {
      "StringEquals": {
        "ec2:ResourceTag/DataClassification": "PHI"
      }
    }
  }]
}'

Pattern 2: Audit Trail Retention

Archive logs to Glacier for 7-year retention (HIPAA requirement):

# S3 Lifecycle policy for CloudTrail logs
aws s3api put-bucket-lifecycle-configuration \
  --bucket hipaa-cloudtrail-logs \
  --lifecycle-configuration '{
    "Rules": [{
      "ID": "Archive-CloudTrail-Logs",
      "Status": "Enabled",
      "Transitions": [{
        "Days": 90,
        "StorageClass": "GLACIER"
      }],
      "Expiration": {
        "Days": 2555
      }
    }]
  }'

Pattern 3: Quarterly Access Reviews

import boto3
from datetime import datetime

iam = boto3.client('iam')

def audit_iam_access():
    """Generate quarterly IAM access audit"""
    users = iam.list_users()['Users']

    for user in users:
        access_keys = iam.list_access_keys(UserName=user['UserName'])
        inline_policies = iam.list_user_policies(UserName=user['UserName'])

        print(f"User: {user['UserName']}")
        print(f"  Access Keys: {len(access_keys['AccessKeyMetadata'])}")
        print(f"  Inline Policies: {inline_policies['PolicyNames']}")
        print(f"  Last Used: {access_keys['AccessKeyMetadata'][0].get('CreateDate', 'N/A')}")
        print()

audit_iam_access()

Common Mistakes to Avoid

  1. Storing PHI in application logs

    • logger.info(f"Patient {patient.name} with SSN {patient.ssn} logged in")
    • logger.info(f"Patient {patient_id} logged in")
    • Log user IDs and actions, not sensitive data
  2. Using unencrypted backups

    • Every backup must be encrypted
    • Verify StorageEncrypted=True on RDS snapshots
  3. Forgetting to enable versioning

    • S3 versioning allows audit trail recovery
    • Enable on all HIPAA buckets
  4. Not rotating encryption keys

    • Rotate KMS keys annually
    • AWS KMS handles this automatically if enabled
  5. Leaving default AWS settings

    • Default VPC is public (create custom VPC)
    • Default security groups allow all inbound (restrict)
    • Default S3 buckets don’t block public (enable)

Compliance Checklist

Before going live:

  • BAA signed with AWS
  • All data encrypted at rest (S3, RDS, EBS)
  • All data encrypted in transit (TLS)
  • CloudTrail enabled and logging
  • CloudWatch Logs configured
  • VPC Flow Logs enabled
  • Security groups restrict access
  • IAM policies follow least privilege
  • AWS Config rules pass (encryption, logging)
  • Security Hub enabled and monitoring
  • Incident response plan documented
  • Data breach notification process in place
  • Disaster recovery tested
  • Quarterly access reviews scheduled

What to Do This Week

  1. Confirm BAA status in Artifact; freeze PHI to eligible services only.
  2. Walk the build checklist against staging.
  3. Turn on org CloudTrail + Config encryption rules before production PHI.

What This Post Doesn’t Cover

Workforce training records, BAAs with your subprocessors, and OCR investigation response — see the compliance-lead checklist for the evidence pack.

Compliance services · Contact us

PP
Palaniappan P

AWS Cloud Architect & AI Expert

AWS-certified cloud architect and AI expert with deep expertise in cloud migrations, cost optimization, and generative AI on AWS.

AWS ArchitectureCloud MigrationGenAI on AWSCost OptimizationDevOps

Related Architecture Patterns

Recommended Reading

Explore All Articles »