HIPAA compliant AWS architecture is not a checkbox list. It's a set of technical, physical, and administrative safeguards that — if not implemented correctly — create real liability exposure for your organization and the covered entities you work with.
The most common mistake: assuming that enabling encryption on S3 and RDS makes your environment "HIPAA compliant." Encryption is one control. HIPAA requires dozens. This post covers what actually needs to be built for a defensible HIPAA-eligible AWS environment.
The Foundation: AWS BAA and HIPAA-Eligible Services
First: AWS requires a Business Associate Agreement (BAA) before PHI can be stored or processed. The BAA is signed through AWS Artifact. Without it, you cannot legally use AWS for PHI workloads regardless of your technical controls.
Second: not all AWS services are HIPAA-eligible. AWS maintains a list of HIPAA-eligible services. PHI must only touch eligible services.
Key eligible services for most architectures: - EC2, ECS, EKS, Lambda - RDS, Aurora, DynamoDB - S3 - CloudFront (with restrictions) - SQS, SNS, EventBridge - Secrets Manager, KMS - CloudWatch, CloudTrail
Services that are NOT eligible: many third-party integrations, and some AWS services in beta or preview. If your data pipeline touches a non-eligible service, that's a gap.
HIPAA Technical Safeguards: What AWS Architecture Implements
HIPAA Technical Safeguards (45 CFR § 164.312) require:
Access Control (§ 164.312(a))
Unique user identification: Every human and service accessing PHI must have a unique identifier. No shared credentials. No service accounts shared across applications.
Emergency access procedure: Documented process for accessing PHI when normal authentication is unavailable (break-glass procedure). In AWS terms: a dedicated IAM role with broad PHI access, tightly controlled, with all usage alerted.
Automatic logoff: Application sessions must time out. Web apps handling PHI need session timeout configured — typically 15 minutes for idle sessions.
Encryption and decryption: All PHI must be encrypted at rest and in transit.
Implementation in AWS:
# KMS key with CloudTrail logging for all PHI encryption
resource "aws_kms_key" "phi_encryption" {
description = "PHI encryption key"
deletion_window_in_days = 30
enable_key_rotation = true
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "Enable CloudTrail logging"
Effect = "Allow"
Principal = {
Service = "cloudtrail.amazonaws.com"
}
Action = ["kms:GenerateDataKey*", "kms:DescribeKey"]
Resource = "*"
}
]
})
}
# S3 bucket for PHI — encryption enforced, public access blocked
resource "aws_s3_bucket" "phi_storage" {
bucket = "phi-storage-${var.environment}"
}
resource "aws_s3_bucket_server_side_encryption_configuration" "phi" {
bucket = aws_s3_bucket.phi_storage.id
rule {
apply_server_side_encryption_by_default {
kms_master_key_id = aws_kms_key.phi_encryption.arn
sse_algorithm = "aws:kms"
}
bucket_key_enabled = true
}
}
resource "aws_s3_bucket_public_access_block" "phi" {
bucket = aws_s3_bucket.phi_storage.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
Audit Controls (§ 164.312(b))
HIPAA requires recording activity on systems containing PHI. In AWS:
CloudTrail: All API calls recorded. Multi-region trail with log file validation and integrity checking.
VPC Flow Logs: Network access to PHI systems logged.
Application-level audit log: Who accessed what PHI, when. This is application code — not AWS infrastructure. It must log: - User identity - Patient/record identifier accessed - Timestamp - Action performed (read/write/delete)
Audit logs must be retained for 6 years under HIPAA (longer than most people assume).
# Application audit logging for PHI access
def log_phi_access(user_id: str, record_id: str, action: str, metadata: dict):
event = {
"event_type": "phi_access",
"user_id": user_id,
"record_id": record_id,
"action": action, # "read" | "write" | "delete"
"timestamp": datetime.utcnow().isoformat(),
"ip_address": metadata.get("ip"),
"user_agent": metadata.get("user_agent"),
"session_id": metadata.get("session_id")
}
# Write to immutable audit log (CloudWatch Logs with retention policy)
audit_logger.info(json.dumps(event))
# Also write to S3 for long-term retention (6 years)
s3_client.put_object(
Bucket=AUDIT_BUCKET,
Key=f"phi-audit/{event['timestamp'][:10]}/{record_id}/{uuid4()}.json",
Body=json.dumps(event),
ServerSideEncryption="aws:kms"
)
Integrity (§ 164.312(c))
PHI must not be improperly altered or destroyed. Controls:
- S3 Object Lock or versioning on PHI storage
- Database backups with restore testing
- CloudTrail log integrity validation
- Checksums on PHI records before transmission
Transmission Security (§ 164.312(e))
PHI in transit must be encrypted. In AWS: - HTTPS everywhere. ACM certificates, TLS 1.2 minimum, TLS 1.3 preferred. - No unencrypted internal service communication (even within VPC). - VPC endpoints for S3 and DynamoDB (avoids transit over public internet). - PrivateLink for service-to-service within AWS.
# Enforce TLS on ALB
resource "aws_lb_listener" "https" {
load_balancer_arn = aws_lb.app.arn
port = "443"
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
certificate_arn = aws_acm_certificate.app.arn
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.app.arn
}
}
# Redirect HTTP to HTTPS
resource "aws_lb_listener" "http_redirect" {
load_balancer_arn = aws_lb.app.arn
port = "80"
protocol = "HTTP"
default_action {
type = "redirect"
redirect {
port = "443"
protocol = "HTTPS"
status_code = "HTTP_301"
}
}
}
Network Isolation for PHI Workloads
PHI systems must be isolated from non-PHI systems. The architecture:
- Dedicated VPC for PHI workloads (separate from general application infrastructure)
- Private subnets for all PHI data stores — no database in a public subnet
- Security groups that restrict database access to known application servers only
- No direct internet access for PHI data stores (NAT Gateway or no internet route at all)
- VPC endpoints for AWS service access
PHI VPC (10.0.0.0/16)
├── Public subnets (10.0.1.0/24, 10.0.2.0/24)
│ └── ALB only (no compute, no data)
├── Private App subnets (10.0.11.0/24, 10.0.12.0/24)
│ └── ECS/EKS compute, Lambda
└── Private Data subnets (10.0.21.0/24, 10.0.22.0/24)
└── RDS, DynamoDB, S3 VPC endpoint
For more on how these architecture patterns come together, see our AWS Cloud Infrastructure capability and our guide on SOC 2 ready AWS architecture.
Common HIPAA Architecture Gaps
PHI in CloudWatch Logs without encryption: CloudWatch Logs should be encrypted with KMS and have 6-year retention. Default CloudWatch Logs are unencrypted.
No PHI data flow mapping: HIPAA requires knowing where PHI flows. Most teams don't have a current data flow diagram. Build one as part of the architecture process.
Third-party integrations touching PHI without BAA: Every vendor that processes PHI on your behalf needs a BAA — not just AWS. This includes monitoring tools, error tracking, analytics.
Backup encryption with default keys: RDS and S3 backups encrypted with AWS-managed keys (not customer-managed KMS keys) are acceptable, but customer-managed keys are recommended for PHI for key rotation control and audit visibility.
Frequently Asked Questions
Is AWS GovCloud required for HIPAA?
No. HIPAA does not require GovCloud. Commercial AWS regions with the BAA in place and appropriate controls are HIPAA-eligible. GovCloud provides additional controls required for government programs (FedRAMP High, DoD IL4/IL5) — not required for HIPAA unless you're also serving federal programs.
What's the difference between HIPAA-eligible and HIPAA-compliant?
"HIPAA-eligible" means an AWS service can be used for PHI under the AWS BAA. "HIPAA-compliant" is what your architecture and processes must be — there's no AWS certification that makes you compliant. Compliance is your responsibility based on the controls you implement.
Do we need a dedicated AWS account for PHI?
It's a strong best practice, not a strict HIPAA requirement. A dedicated PHI account simplifies access control, audit scoping, and cost attribution. It also reduces blast radius if a non-PHI workload in a shared account is compromised.
How long must we retain PHI audit logs?
HIPAA requires retaining documentation of policies and procedures for 6 years from the date of creation or the date when last in effect. Audit logs that support PHI access accountability should align to this — CloudWatch Logs and S3 retention policies should be set to 6 years.
Can we use third-party monitoring tools (Datadog, Sentry) with PHI?
Only if those tools have signed a BAA with you and their service is configured to not receive actual PHI. Typically: send metrics and traces, never log PHI fields, scrub PHI from error messages before reporting. Verify BAA availability with each vendor.
Talk to us about your AWS architecture → rutagon.com/contact