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
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"}}]}'
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
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"}'
4. RDS instances without encryption
# Check RDS encryption status
aws rds describe-db-instances \
--query 'DBInstances[?StorageEncrypted==`false`].[DBInstanceIdentifier,Engine]' \
--output table
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
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
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"
}'
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)