DEV Community

Bala Paranj
Bala Paranj

Posted on

Your HIPAA CloudFormation template was correct on day 1. Is it correct today?

✓ Human-authored analysis; AI used for formatting and proofreading.

The template

A GitHub project demonstrates HIPAA-compliant AWS infrastructure for a pharmacy called GoodBuy. The CloudFormation template deploys:

  • CloudTrail — logs every API call to S3 as zipped JSON
  • Lambda — parses CloudTrail logs, matches security keywords
  • SNS — sends alerts on suspicious API calls
  • CloudWatch — monitors metrics, sets alarms, triggers reactions
  • KMS — key management for encryption
  • IAM — role-based access controls
  • S3 — stores CloudTrail logs and application data

The README cites HIPAA §164.312:

(a)(1) "allow access only to those persons or software programs that have been granted access rights"
(a)(2)(iv) Encryption and decryption
(b) Audit controls
(c)(1) Integrity — protect PHI from improper alteration or destruction
(d) Person or entity authentication

Good architecture. Correct citations. The template handles the day-1 deployment.

What the template can't verify

A CloudFormation template is a declaration of intent. It describes what you want AWS to create. It cannot answer these questions after deployment:

1. Did anyone change the S3 bucket policy via the console?

The template creates an S3 bucket for CloudTrail logs with a scoped policy. Six months later, an engineer adds Principal: * to troubleshoot a cross-account issue and forgets to remove it. The CloudTrail log bucket containing every API call in the account is now public.

The template still looks correct. The infrastructure is not correct.

2. Is the KMS key customer-managed or AWS-managed?

The template references KMS encryption. But there's a critical difference:

  • AWS-managed key (alias/aws/s3): You cannot revoke it during a breach. AWS controls the key lifecycle.
  • Customer-managed key: You can disable it immediately, rendering all encrypted data unreadable.

HIPAA §164.312(a)(2)(iv) requires encryption. But during a breach response, you need the ability to revoke access to encrypted data. Only a CMK gives you that power. The template may use either and the difference isn't visible from the template alone.

3. Does the CloudTrail log bucket have Object Lock?

HIPAA §164.316(b)(2) requires 6 years of PHI retention. CloudTrail logs are audit evidence. Without Object Lock in Compliance mode, those logs can be:

  • Deleted by an attacker who compromises an admin role
  • Removed by a lifecycle rule that expires objects too early
  • Overwritten by a misconfigured Lambda

The template creates the bucket. It may enable Object Lock and Object Lock can only be enabled at bucket creation time. If it was missed on day 1, the bucket must be recreated.

4. Is Public Access Block enabled on every bucket?

The GoodBuy template creates multiple S3 buckets (CloudTrail logs, application data, configuration). Each needs Public Access Block. A template might enable PAB on the main bucket but miss the log bucket. Or PAB might be disabled at the account level, overriding bucket-level settings.

5. How long has any misconfiguration persisted?

The template was deployed 18 months ago. Has every bucket been compliant for all 18 months? Or did a Terraform apply with a stale state file briefly expose the CloudTrail log bucket 6 months ago?

No template can answer this. Duration tracking requires evaluating observed state over multiple points in time.

What Stave verifies

Run the HIPAA profile against the deployed infrastructure:

stave evaluate --snapshot goodbuy-pharmacy.json --profile hipaa --format text
Enter fullscreen mode Exit fullscreen mode

Stave checks the same §164.312 requirements the template claims to satisfy:

HIPAA Section Template Intent Stave Verification
§164.312(a)(1) Access control IAM roles in template ACCESS.001 — is PAB actually enabled?
§164.312(a)(2)(i) Unique identification IAM users in template ACCESS.002 — are there wildcard actions?
§164.312(a)(2)(iv) Encryption KMS referenced in template CONTROLS.001.STRICT — is it CMK, not AWS-managed?
§164.312(b) Audit controls CloudTrail in template AUDIT.001 — is logging still enabled? AUDIT.002 — are S3 data events captured?
§164.312(c)(1) Integrity Versioning implied CONTROLS.002 — is versioning actually on? RETENTION.002 — is Object Lock in compliance mode?
§164.312(e)(2)(ii) Transmission HTTPS assumed CONTROLS.004 — is there a Deny for non-TLS?

Plus compound risks the template can't express:

[critical] COMPOUND.001
Public access + wildcard IAM = lateral movement
Enter fullscreen mode Exit fullscreen mode
[high] COMPOUND.002
Encryption enabled + bucket public = false security
Enter fullscreen mode Exit fullscreen mode

The timeline test

The most powerful verification is re-running Stave on snapshots captured over time:

Snapshot 1 (deploy day):      PASS — 14/14 controls
Snapshot 2 (3 months later):  FAIL — AUDIT.001 (logging disabled)
Snapshot 3 (6 months later):  FAIL — ACCESS.001 (PAB removed)
Snapshot 4 (today):           FAIL — 3 findings, 4,300 hours past SLA
Enter fullscreen mode Exit fullscreen mode

The template was correct on day 1. The infrastructure drifted. Duration tracking shows when each control started failing and how long it's been non-compliant.

The lesson

CloudFormation templates are necessary. They encode your security architecture as code, enable peer review, and make deployments reproducible. The GoodBuy pharmacy template is well-designed with CloudTrail, KMS, IAM, monitoring, alerting.

But a template is a blueprint. It describes what you built. It can't tell you what you have.

Stave evaluates what you have right now, with temporal evidence of how long it's been that way. Run it against every HIPAA environment, not just the ones you're deploying, but the ones that have been running for months without anyone checking whether the blueprint still matches reality.

stave evaluate --snapshot current-state.json --profile hipaa
Enter fullscreen mode Exit fullscreen mode

If it doesn't say PASS, the template was correct and the infrastructure is not. That's the gap between intent and reality. Stave closes it.


The GoodBuy pharmacy CloudFormation template referenced in this article is available at github.com/shaza4061/aws-hipaa-example.

Top comments (0)