Compute hardening
Golden AMIs with EC2 Image Builder, hardened container images, IMDSv2, instance profiles vs service and execution roles, Session Manager, EC2 Instance Connect and its endpoint, removing SSH keys, and host-based controls.
Exam tasks: 3.2 (hardened AMIs and container images with Systems Manager and Image Builder; instance profiles, service roles and execution roles; secure administrative access with Session Manager and EC2 Instance Connect)
The decision: what does a workload start with (image), what can it do once running (role and metadata), and how do humans get onto it (access path) without leaving a standing door open?
The hardened image pipeline
EC2 Image Builder and golden AMIs
- A pipeline runs an image recipe (parent image plus ordered components) or a container recipe on a schedule or when a dependency changes.
- Components are YAML documents with build, validate and test phases. AWS provides hardening components for CIS benchmarks and DISA STIGs, plus agents such as the CloudWatch agent.
- Image Builder can run an Inspector scan on the build output and fail the pipeline on findings above a threshold.
- Distribution settings copy AMIs to other Regions, share them with accounts or OUs, and re-encrypt with a
KMS key per Region. Target accounts need
kms:Decryptandkms:CreateGranton the key in its key policy. - Lifecycle policies deprecate and delete old images, so nobody launches a two-year-old AMI.
- The build instances use an instance profile with
EC2InstanceProfileForImageBuilderandAmazonSSMManagedInstanceCore. Image Builder drives them through Systems Manager, so they need no SSH.
Keep people on the golden images:
- Allowed AMIs (an EC2 account setting, managed by declarative policies in Organizations) restricts which AMI owners or names can be launched.
- Block public access for AMIs stops accidental public sharing.
- Treat instances as immutable: fix the image and replace instances rather than patching the fleet by hand. Use Patch Manager for long-lived servers (see Vulnerability and patch management).
Exam signal
"Every new AMI must include the security agent and pass the CIS benchmark before any team can use it, across 20
accounts" is an Image Builder pipeline with hardening and test components, an Inspector scan, and distribution
to the OUs. Pair it with Allowed AMIs or an SCP condition on ec2:Owner to make the golden images mandatory.
Hardened container images
- Start from a minimal base (distroless, Alpine, Bottlerocket for nodes). Fewer packages mean fewer CVEs.
- Run as a non-root user, drop Linux capabilities, and use a read-only root file system in the task definition or pod spec.
- Never bake secrets into layers. Every layer is readable by anyone who can pull the image. Inject secrets at run time from Secrets Manager or Parameter Store.
- Turn on ECR tag immutability so a trusted tag can't be overwritten, and deploy by digest.
- Sign images (AWS Signer with Notation) and verify signatures at admission in EKS.
- Scan with Inspector enhanced scanning on push and continuously.
Instance metadata: require IMDSv2
- IMDSv2 requires a session token obtained with an HTTP
PUT. It blocks the classic SSRF attack, where a web app is tricked into fetching169.254.169.254credentials through a GET, and open reverse proxies. - Set
HttpTokens=requiredon launch templates and existing instances. Make it the account-level default for new instances, and enforce with an SCP onec2:RunInstancesusing theec2:MetadataHttpTokenscondition. - The hop limit of 1 keeps IMDS responses from reaching containers on the host (AMIs flagged for IMDSv2, such as Amazon Linux 2023, default to 2). Use 2 only when containers legitimately need IMDS. Use 1 on EKS nodes where pods should use Pod Identity instead.
- Turn IMDS off entirely for instances that don't need it.
- Detect stolen instance credentials: GuardDuty flags them when they're used from outside AWS or from another
account. Limit them with the
aws:EC2InstanceSourceVPCandaws:EC2InstanceSourcePrivateIPv4condition keys.
Giving workloads an identity
| Mechanism | Who assumes it | Used for |
|---|---|---|
| Instance profile | EC2 instance (container for one role) | Software on the instance calling AWS APIs. Credentials rotate through IMDS |
| Service role | An AWS service acting in your account | Image Builder, CodeBuild, Config, Systems Manager Automation |
| Service-linked role | A service, with a policy the service defines | Predefined by the service. You can't edit its permissions |
| Lambda execution role | Lambda | Everything the function's code does |
| ECS task role | Containers in the task | App calls to S3, DynamoDB and so on |
| ECS task execution role | The ECS agent | Pull from ECR, write logs, fetch secrets for the task definition |
| EKS Pod Identity / IRSA | A Kubernetes service account | Per-pod AWS permissions instead of the node role |
- One role per workload, least privilege, no access keys on disk. Use IAM Access Analyzer policy generation to trim roles from CloudTrail activity (see Least privilege tooling).
- A user who attaches a role to a resource needs
iam:PassRolefor that role. Scope it with theiam:PassedToServicecondition. - An instance holds one role at a time. Replace the profile association to change it, and running processes pick up new credentials on the next refresh.
Task role vs task execution role
If containers get AccessDenied calling S3, fix the task role. If the task fails to start because it can't
pull the image or read a secret referenced in the task definition, fix the task execution role. Distractors
often swap the two.
Administrative access without SSH
| Session Manager | EC2 Instance Connect | EC2 Instance Connect Endpoint | |
|---|---|---|---|
| Inbound ports | None. The SSM Agent calls out | 22 from the client (public IP or VPN) | 22 or 3389 only from the endpoint |
| Auth | IAM (ssm:StartSession), with tag-based conditions | IAM pushes a one-time public key (SendSSHPublicKey), valid 60 seconds | IAM (ec2-instance-connect:OpenTunnel), then SSH key or pushed key |
| Needs on instance | SSM Agent + instance profile or Default Host Management Configuration | EC2 Instance Connect package (for pushed keys) | Nothing extra if you use your own key |
| Session logging | Full transcript to S3 or CloudWatch Logs, encrypted with KMS | Only the API call in CloudTrail | Tunnel open in CloudTrail |
| Private subnet | Yes, with ssm, ssmmessages, ec2messages VPC endpoints | No, needs a network path | Yes, no IGW or bastion needed |
- Session Manager also does port forwarding (for example to an RDS database through an instance) and runs
sessions as a configured OS user (
Run As). - A session preferences document sets logging, KMS encryption of the session stream, idle timeout and shell
profile. Deny
ssm:StartSessionon the default document so users can't bypass it. - The EC2 Instance Connect Endpoint is an identity-aware TCP proxy: up to 20 concurrent connections, sessions up to 1 hour, and one endpoint per VPC.
Exam signal
"No inbound ports, no bastion, and every command must be logged" is Session Manager with S3 or CloudWatch Logs session logging. "Engineers must use their normal SSH client to reach private instances without a bastion or public IP" is the EC2 Instance Connect Endpoint.
Removing SSH keys and handling a leaked one
- Deleting a key pair in the EC2 console doesn't remove it from instances. The public key stays in
~/.ssh/authorized_keysuntil you remove it. - To remove a compromised key across a fleet: use Run Command (or State Manager, to keep it removed) with a
script that deletes that key from
authorized_keyson every instance, then rotate any other credentials the key holder could reach. - Lost the key for a single instance: connect with Session Manager and add a new public key, or use the
AWSSupport-ResetAccessautomation. - Then remove SSH altogether: close port 22 in security groups, move admins to Session Manager, and alert on
security groups that open 22 or 3389 to
0.0.0.0/0with AWS Config. - For forensic steps on a compromised host, see Compromised workloads.
Host-based controls
Security groups and NACLs see addresses and ports. On-host controls see processes, files and payloads.
- Host firewall (iptables, nftables, Windows Defender Firewall) as a second layer, for example blocking IMDS for all users except root.
- HIDS, antivirus and file integrity monitoring from third parties, deployed and kept running with State Manager associations or Distributor packages.
- GuardDuty Runtime Monitoring agent for process, file and network events on EC2, ECS and EKS (see Threat detection).
- CloudWatch agent to ship OS and application logs for detection.
- EBS encryption by default, and Nitro Enclaves for processing highly sensitive data in isolation.
Scenarios
IMDSv2 requires a PUT to get a session token, which a typical SSRF can't do, so requiring it fixes the flaw. The SCP stops anyone launching instances that allow IMDSv1. Metadata traffic never leaves the host, so a NACL can't block it. Instance role credentials already rotate automatically, and replacing roles with access keys makes things worse.
Session Manager needs no inbound rules because the agent connects out through the VPC endpoints, and it records full session transcripts, encrypted with the KMS key you choose. An Instance Connect Endpoint requires an inbound rule for SSH from the endpoint, and CloudTrail records only that a tunnel opened, not the commands. Client VPN needs inbound SSH and doesn't log commands. Plain EC2 Instance Connect needs a network path to port 22.
Secrets referenced in the task definition are fetched by the ECS agent using the task execution role before the container starts, so that role needs read access to the one secret and its key. The task role is what the application code uses once running, for example for S3. A broad managed policy on both roles breaks least privilege, and plain-text environment variables expose the password.
Further reading
Edge protection
AWS WAF rules, managed rule groups, rate limiting, Bot Control and Fraud Control, Shield Standard and Advanced, CloudFront security headers and origin protection, S3 CORS, Firewall Manager, OCSF integrations and AWS IoT policies.
Vulnerability and patch management
Amazon Inspector for EC2, ECR, Lambda and code repositories, GuardDuty Runtime Monitoring, Systems Manager Patch Manager and State Manager, and security scanning inside CI/CD pipelines with Amazon Q Developer and Inspector.