Skip to content

NHC Account: Where We Are & Where We're Going

DA-15 — NHC HIPAA-Compliant Infrastructure · 30 March 2026 AWS Account: 794248400165 (NHC prod) · Region: us-east-2 (Ohio)


What Is This?

We are building the NHC AWS account into a fully HIPAA-compliant environment to host the MWE application suite — including a Django API that stores Protected Health Information (PHI). Phase 1 (the security baseline) is deployed. Phase 2 (the actual application servers) is in progress.


Compliance Score: 55%

11 of 20 controls implemented. Up from ~5% a week ago.

Category Done Total %
Encryption 1 3 33%
Audit & Logging 2 2 100%
Monitoring 3 3 100%
Network 1 1 100%
Access Control 0 2 0%
Policies / Docs 4 9 ~44%
Total 11 20 55%

Phase 1 — What Was Deployed ✅

84 resources applied via OpenTofu in the NHC account.

What Detail
5 KMS CMKs EBS · S3 · CloudTrail · RDS · Backup vault
VPC Private + public subnets · NAT Gateway · 2 AZs (us-east-2a/b)
CloudTrail Multi-region trail · KMS encrypted · log file validation
GuardDuty Threat detection · SNS alert on High/Critical findings
AWS Config 21-rule HIPAA conformance pack (encryption, audit, access, network, backup)
Security Hub NIST 800-53 Rev 5 standard activated
AWS Backup Encrypted vault · daily backup plan
IAM / SSM Instance profile for SSM Session Manager (no SSH port needed)

Apps Being Migrated (from MWE)

App Type PHI? Hosting Status
Django API REST API — primary data store YES — full HIPAA EC2 private + ALB + WAF Phase 2 — In progress
Portals Frontend for Django API Auth sessions only Shared EC2 with Django (for now) Phase 2 — In progress
WP CMS Headless WordPress (content only) No EC2 + MySQL RDS Phase 2 — In progress
Gatsby Static site — consumes WP via GraphQL No Build on EC2 → S3 + CloudFront Phase 4 — Pending
Astro (×4 domains) Static site monorepo No Build on EC2 → S3 + CloudFront Phase 4 — Pending

Account-level controls (CloudTrail, GuardDuty, Config, Security Hub) cover all apps regardless of PHI status.


Delivery Roadmap

✅ Phase 1 — Security Baseline (Complete)

  • KMS CMKs (EBS, S3, CloudTrail, RDS, Backup)
  • VPC: private & public subnets, NAT Gateway, 2 AZs
  • CloudTrail multi-region trail (encrypted + log validation)
  • GuardDuty threat detection
  • AWS Config + 21-rule HIPAA conformance pack
  • Security Hub + NIST 800-53 Rev 5
  • AWS Backup: encrypted vault + daily plan
  • IAM SSM instance profile (no SSH required)

🔄 Phase 2 — App Servers: EC2 + RDS (In Progress)

  • EC2 (ec2-app): WP CMS + Gatsby/Astro builds — encrypted EBS, IMDSv2, SSM
  • EC2 (ec2-django): Django API + Portals — encrypted EBS, IMDSv2, SSM
  • RDS MySQL 8.0 (rds-django) — encrypted, private subnet, PHI-tagged
  • RDS MySQL 8.0 (rds-wordpress) — encrypted, private subnet
  • Ansible: Debian 13, Docker CE, GitLab Runner, deploy user, 4GB swap
  • Secrets → SSM Parameter Store (no .env files on disk)

⬜ Phase 3 — HTTPS Enforcement (Closes last Critical gap)

  • ALB module: public-facing, HTTPS-only, HTTP → redirect
  • WAF v2: managed rules + rate limiting on Django ALB
  • ACM certificates for all domains
  • TLS 1.2 minimum enforced on all listeners

⬜ Phase 4 — Static Site Delivery (Gatsby + Astro)

  • S3 bucket per site: private, SSE-KMS, versioned
  • CloudFront distribution: HTTPS-only, TLS 1.2, OAC
  • ACM certs in us-east-1 (CloudFront requirement)
  • GitLab CI pipeline: build → push dist → CloudFront invalidation

⬜ Phase 5 — Hardening & State

  • S3 + DynamoDB state backend for NHC
  • TerraformDeployRole via IaC (restore assume_role pattern)
  • Cross-region backup DR vault (us-west-2)
  • VPC Flow Logs → CloudWatch
  • SSM read IAM policy attached to EC2 instance profiles

⬜ Phase 6 — Screenshot PHI Controls (Blocked on DA-16)

  • NVS screenshot S3 bucket: KMS-encrypted, access logging, versioning
  • CloudWatch alarm on anomalous GetObject access
  • 90-day lifecycle / deletion policy

Remaining Gaps

Risk Gap Resolution
🔴 Critical HTTPS not yet enforced on Django API ALB + WAF — Phase 3
🟠 High EC2 + RDS not yet running Phase 2 apply — needs DB passwords
🟠 High NVS EC2 on public IP (Tokyo, legacy) DA-13 migration
🟠 High No MFA enforcement SCP at Org level Phase 5 / separate ticket
🟠 High VPC Flow Logs not yet active in NHC Phase 5
🟠 High NVS legacy EBS not encrypted DA-14 (maintenance window required)

For Non-Technical Stakeholders

Why a separate AWS account? Isolating PHI workloads into their own account means a security event in another app cannot reach patient data. AWS even requires this pattern for HIPAA workloads.

What is "encryption at rest"? Every file stored on disk — database rows, backups, server drives — is scrambled using unique keys we control. Even if someone copied the raw disk, they'd see gibberish.

What is GuardDuty? An AWS service that monitors all activity 24/7 and alerts us if anything looks like an attack — unusual logins, API abuse, crypto-mining attempts, and more.

What is still missing? The application servers themselves (EC2 + database) aren't running yet — that's Phase 2, in progress now. HTTPS enforcement (Phase 3) is the last critical security gap.

When does PHI flow in? Not until Phase 3 is complete. The Django API must be behind HTTPS + WAF before any patient data is migrated into it.

Is NVS affected? NVS (the current VA management system) is a separate account. It is not currently handling PHI — screenshot feature and data migration are separate, later milestones.


Immediate Next Actions

# Action Blocker
1 Set DB passwords in SSM Parameter Store (/nhc/django/db_password, /nhc/wordpress/db_password)
2 Run tofu plan + apply for Phase 2 (EC2 + RDS) Item 1
3 Update Ansible inventory with instance IDs from tofu output Item 2
4 Run Ansible bootstrap playbook (Docker CE, GitLab Runner, deploy user) Item 3
5 Register GitLab Runner on each EC2 instance Item 4
6 Begin Phase 3: ALB module + ACM certificates Domain names confirmed

DA-15 — NHC HIPAA-Compliant Infrastructure · 2026-03-30 · DevOps Team