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 compliance on AWS requires encryption, audit logging, access controls, and Business Associate Agreements. This guide covers architecture patterns, AWS service configurations, and compliance validation for healthcare applications.

Key Facts

  • HIPAA compliance on AWS requires encryption, audit logging, access controls, and Business Associate Agreements
  • This guide covers architecture patterns, AWS service configurations, and compliance validation for healthcare applications
  • HIPAA compliance on AWS requires encryption, audit logging, access controls, and Business Associate Agreements
  • This guide covers architecture patterns, AWS service configurations, and compliance validation for healthcare applications

Entity Definitions

compliance
compliance is a cloud computing concept discussed in this article.
HIPAA
HIPAA is a cloud computing concept discussed in this article.

How to Implement a HIPAA-Compliant Architecture on AWS

Quick summary: HIPAA compliance on AWS requires encryption, audit logging, access controls, and Business Associate Agreements. This guide covers architecture patterns, AWS service configurations, and compliance validation for healthcare applications.

Key Takeaways

  • HIPAA compliance on AWS requires encryption, audit logging, access controls, and Business Associate Agreements
  • This guide covers architecture patterns, AWS service configurations, and compliance validation for healthcare applications
  • HIPAA compliance on AWS requires encryption, audit logging, access controls, and Business Associate Agreements
  • This guide covers architecture patterns, AWS service configurations, and compliance validation for healthcare applications
Table of Contents

HIPAA (Health Insurance Portability and Accountability Act) compliance is non-negotiable for healthcare organizations and vendors processing patient data. AWS is HIPAA-eligible, but compliance requires more than using AWS — it requires proper architecture, encryption, access controls, and continuous monitoring.

This guide walks through building a HIPAA-compliant system: encrypting data at rest and in transit, centralizing audit logs, enforcing access controls, validating compliance, and maintaining evidence for audits.

Building HIPAA-Compliant Healthcare on AWS? FactualMinds helps healthcare organizations architect secure, compliant systems on AWS and navigate audit requirements. See our compliance services or talk to our team.

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

Next Steps

  1. Request BAA (5-10 days)
  2. Set up CloudTrail and CloudWatch Logs
  3. Encrypt all data (S3, RDS, EBS)
  4. Enable AWS Config and Security Hub
  5. Schedule quarterly compliance audits
  6. Test incident response plan
  7. Talk to FactualMinds if you need help auditing or maintaining HIPAA compliance on AWS
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

Ready to discuss your AWS strategy?

Our certified architects can help you implement these solutions.

Recommended Reading

Explore All Articles »

How to Set Up AWS Security Hub for Compliance Monitoring

AWS Security Hub aggregates security findings from 200+ sources (GuardDuty, Config, IAM Access Analyzer, Inspector). This guide covers setup, compliance standards (PCI-DSS, CIS, NIST), automated remediation, and building a compliance dashboard without hiring a SOC team.

How to Protect AWS Infrastructure from Cost-Based Attacks

How to Protect AWS Infrastructure from Cost-Based Attacks

Attackers do not need to take down your service to hurt you — they can send traffic designed to maximize your AWS bill. DDoS amplification, Lambda invocation bombs, and SQS message flooding are billing attacks, not just availability attacks.