How to Enforce IMDSv2 and Lock Down EC2 Instance Role Permissions
Retrospective: this article looks back at events from July 2019, written in 2026 with the benefit of hindsight.
IMDSv2 protects EC2 instance credentials from server-side request forgery, the technique used in the Capital One breach. Combined with least-privilege instance roles, it closes one of the most important AWS attack paths.
Step 1: Find instances allowing IMDSv1
aws ec2 describe-instances \
--query "Reservations[].Instances[?MetadataOptions.HttpTokens=='optional'].[InstanceId]" \
--output text
Run in every region and account, or use AWS Security Hub control EC2.8 (instances should use IMDSv2) for an organization-wide view.
Step 2: Check application compatibility
Most current AWS SDKs and the CLI support IMDSv2 automatically. Older SDKs, custom scripts calling the metadata endpoint directly, and some third-party agents may not. Use the CloudWatch metric MetadataNoToken to see whether instances are still making IMDSv1 calls.
Step 3: Enforce on existing instances
aws ec2 modify-instance-metadata-options --instance-id i-1234567890abcdef0 \
--http-tokens required --http-put-response-hop-limit 1
Use a hop limit of 1 unless containers on the host need metadata access (then 2).
Step 4: Make it the default
- Set the account-level default for new instances to require IMDSv2.
- Update launch templates and AMIs.
- Consider an SCP or IAM condition (
ec2:MetadataHttpTokens) requiring IMDSv2 onRunInstances.
Step 5: Shrink instance roles
Review each instance role with IAM Access Analyzer's unused access findings and last-accessed data. Remove permissions not used in 90 days, and scope S3 access to specific buckets.
Verify
Zero instances with HttpTokens=optional, and no instance role with broad s3:* or * permissions.