DEV Community

ConformScan
ConformScan

Posted on

How to audit your AWS infrastructure for NIS2 and DORA compliance (practical guide)

With NIS2 mandatory since October 2024 and DORA in force since January 2025, EU cloud teams are scrambling to figure out what actually needs to change in their AWS infrastructure. This guide walks through the specific checks, the tooling, and the common gaps we see.

What NIS2 and DORA actually require on AWS

NIS2 Art. 21 defines minimum security measures for "essential" and "important" entities. For AWS infrastructure, the relevant requirements translate to:

  • Encryption at rest and in transit (Art. 21(2)(h))
  • Access control and least privilege (Art. 21(2)(i))
  • Multi-factor authentication (Art. 21(2)(j))
  • Logging and audit trails — minimum 12 months retention
  • Incident response capability (Art. 21(2)(b))
  • Backup and recovery procedures (Art. 21(2)(c))

DORA Art. 9 (for financial services: banks, insurance, investment firms) adds:

  • ICT risk management framework documented and tested
  • Encryption of data at rest AND in transit with current standards
  • Full logging coverage across all regions (not just primary)
  • Incident classification and reporting: 72h initial report, 1 month final (Art. 19)
  • Third-party ICT provider risk assessment (Art. 28-44) — this includes AWS itself

The overlap between NIS2 and DORA is roughly 40%. If you're a fintech or bank, you're essentially auditing the same infrastructure twice without proper tooling.

The most common AWS compliance gaps

After running automated checks across many AWS accounts, these are the findings that appear most frequently:

1. S3 encryption disabled (~60% of accounts)

# Check all S3 buckets for encryption
aws s3api list-buckets --query 'Buckets[].Name' --output text | \
  xargs -I{} aws s3api get-bucket-encryption --bucket {} 2>&1
Enter fullscreen mode Exit fullscreen mode

Fix: Enable default encryption on all buckets. SSE-S3 satisfies basic requirements; SSE-KMS with CMK satisfies stricter DORA requirements.

aws s3api put-bucket-encryption \
  --bucket your-bucket-name \
  --server-side-encryption-configuration \
  '{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"aws:kms","KMSMasterKeyID":"your-key-id"}}]}'
Enter fullscreen mode Exit fullscreen mode

2. CloudTrail not enabled in all regions

NIS2 and DORA require comprehensive logging for incident reconstruction. CloudTrail must be active in all regions, not just your primary one.

# Check which regions have CloudTrail enabled
for region in $(aws ec2 describe-regions --query 'Regions[].RegionName' --output text); do
  echo -n "$region: "
  aws cloudtrail describe-trails --region $region \
    --query 'trailList[?IsMultiRegionTrail==`false`].Name' --output text
done
Enter fullscreen mode Exit fullscreen mode

Fix: Create a multi-region trail that logs to a dedicated S3 bucket with 12+ months retention.

3. MFA not enforced on IAM users

# Find IAM users without MFA enabled
aws iam generate-credential-report
aws iam get-credential-report --query 'Content' --output text | \
  base64 -d | awk -F',' 'NR>1 && $4=="false" {print $1, "- no MFA"}'
Enter fullscreen mode Exit fullscreen mode

4. RDS instances without encryption

# Check RDS encryption status
aws rds describe-db-instances \
  --query 'DBInstances[?StorageEncrypted==`false`].[DBInstanceIdentifier,Engine]' \
  --output table
Enter fullscreen mode Exit fullscreen mode

Note: You cannot encrypt an existing unencrypted RDS instance in-place. The process requires creating a snapshot, copying it with encryption enabled, and restoring from the encrypted snapshot.

5. No VPC Flow Logs

Without VPC Flow Logs, incident reconstruction under DORA Art. 19 (72h reporting) becomes nearly impossible.

# Check which VPCs have Flow Logs enabled
aws ec2 describe-vpcs --query 'Vpcs[].VpcId' --output text | \
  xargs -I{} aws ec2 describe-flow-logs \
  --filter Name=resource-id,Values={} \
  --query 'FlowLogs[].{VpcId:ResourceId,Status:FlowLogStatus}' --output table
Enter fullscreen mode Exit fullscreen mode

6. Security groups with 0.0.0.0/0 on sensitive ports

# Find overly permissive security groups
aws ec2 describe-security-groups \
  --query 'SecurityGroups[?IpPermissions[?IpRanges[?CidrIp==`0.0.0.0/0`] && (ToPort==`22` || ToPort==`3389` || ToPort==`3306`)]].[GroupId,GroupName]' \
  --output table
Enter fullscreen mode Exit fullscreen mode

Integrating compliance checks into CI/CD

The most effective approach is running these checks automatically after every Terraform apply in staging. Here's a GitHub Actions step:

- name: NIS2/DORA compliance check
  run: |
    curl -s -X POST https://conformscan.com/api/v1/scans \
      -H "X-API-Key: ${{ secrets.CONFORMSCAN_KEY }}" \
      -H "Content-Type: application/json" \
      -d '{
        "account_id": "${{ vars.AWS_ACCOUNT_ID }}",
        "frameworks": ["nis2", "dora"],
        "fail_on": "critical"
      }'
Enter fullscreen mode Exit fullscreen mode

If a critical finding is introduced — open S3 bucket, unencrypted RDS, missing CloudTrail — the pipeline fails before it reaches production.

Drift detection: the underrated compliance tool

The initial scan is embarrassing (everyone has gaps). The second scan is where compliance gets hard: drift.

Drift happens when:

  • Someone clicks in the AWS Console to "quickly fix" something
  • A Terraform module is updated and changes a default
  • A temporary exception becomes permanent

Comparing your live AWS state against your Terraform declarations automatically catches these regressions before your next audit.

Key differences between NIS2 and DORA for AWS teams

Requirement NIS2 DORA
Incident reporting No fixed timeframe specified 72h initial + 1 month final
Log retention Not explicitly specified Full audit trail required
Cloud provider risk Implicit Explicit Art. 28-44
Sector scope All "essential/important" entities Financial sector only
Encryption standard Current standards "State of the art"

If you're in financial services, prioritize DORA — NIS2 compliance typically follows.

Checklist

  • [ ] S3: Default encryption enabled (SSE-KMS preferred)
  • [ ] CloudTrail: Multi-region trail active, 12+ months retention
  • [ ] IAM: MFA enforced for all users (especially root)
  • [ ] RDS/EBS: All storage encrypted at rest
  • [ ] VPC: Flow Logs enabled, exported to CloudWatch or S3
  • [ ] GuardDuty: Active in all regions
  • [ ] Security Groups: No 0.0.0.0/0 on SSH/RDP/DB ports
  • [ ] KMS: Customer-managed keys for sensitive data
  • [ ] Config: AWS Config enabled for resource change tracking

Resources

  • ConformScan — automated NIS2/DORA/ISO27001 scanner for AWS and Azure (free tier: 1 account/month)
  • NIS2 Directive full text: EUR-Lex 2022/2555
  • DORA Regulation full text: EUR-Lex 2022/2554

Top comments (0)