SaveMyCert
Log in
5 of 5 free questions left today·for 30 a day
Infrastructure Security

Securing Compute Workloads: EC2, Containers, and Lambda

26 min readSCS-C03 · Infrastructure SecurityUpdated

Compute workload security is the set of controls that harden, authorize, scan, patch, and administer EC2 instances, containers, and Lambda functions, and that protect the generative AI applications running on them. Every workload runs with credentials, an attack surface, and a patch state you are responsible for. Task 3.2 tests whether you can harden each form factor (IMDSv2 and golden AMIs on EC2, scanned and immutable images in ECR, correctly split roles on ECS, pod-level identity on EKS, scoped resource policies on Lambda), run the vulnerability loop with Amazon Inspector and GuardDuty, give administrators access without open ports, scan code in the pipeline, and put Bedrock Guardrails around LLM applications. It also tests the failures those controls produce, from an instance Systems Manager cannot see to a task that cannot read its secret. The recurring theme: give each workload exactly one tightly scoped identity, and know which role or policy does which job.

What you’ll learn
  • Enforce IMDSv2 for existing and future instances: tokens, the hop limit, launch-versus-account-versus-AMI precedence, account-level enforcement, declarative policies, and ec2:MetadataHttpTokens denies.
  • Authorize EC2 workloads with instance profiles rather than stored secrets, and pin role credentials to their VPC with aws:Ec2InstanceSourceVpc.
  • Build and keep golden images current with EC2 Image Builder, and patch fleets with Patch Manager patch policies validated by Amazon Inspector.
  • Run a vulnerability and runtime-threat loop with Amazon Inspector (EC2, ECR, Lambda), its scores, and GuardDuty Runtime Monitoring and Lambda Protection.
  • Harden the container supply chain and roles: ECR scanning frequencies and re-scan durations, cross-account pull, and the ECS execution, task, service-linked and infrastructure roles.
  • Secure Lambda invocation with aws:SourceArn and aws:SourceAccount, and tell EventBridge rules from EventBridge Scheduler.
  • Secure EKS workloads with per-pod IAM (IRSA or EKS Pod Identity) instead of node-role permissions, control-plane audit logs and a private API endpoint.
  • Choose between Session Manager, port forwarding, SSH over Session Manager and EC2 Instance Connect Endpoint for administrative access.
  • Scan code and images in the pipeline with Amazon Q Developer and Inspector, and protect LLM applications with Bedrock Guardrails against OWASP Top 10 for LLM risks.
  • Troubleshoot compute security failures: unmanaged nodes (agent, profile or DHMC, endpoints), image-pull and secret errors, and denied invocations.

IMDSv2: closing the SSRF door to instance credentials

IMDSv2 protects an instance role's credentials by making the instance metadata service at 169.254.169.254 require a session token, which the request primitives behind most server-side request forgery (SSRF) flaws cannot obtain. With IMDSv1, a single GET returns the role's temporary credentials, so any SSRF flaw, misconfigured proxy, or open redirect that makes the application fetch an internal URL becomes credential theft.

Under IMDSv2, a client first sends a PUT with the X-aws-ec2-metadata-token-ttl-seconds header to get a token, then presents it in the X-aws-ec2-metadata-token header on every read. Typical SSRF primitives can issue simple GETs but not a custom-header PUT, so the chain breaks. Security groups and network ACLs do not help here: metadata traffic never leaves the instance, so it is not filtered by them.

The hop limit

HttpPutResponseHopLimit is the IP TTL on the token response. With a hop limit of 1, the response dies at the first network hop, so processes on the host (such as the CloudWatch or SSM agents) still get tokens, but containers on a bridged network, which sit one hop further away, do not. A hop limit of 2 is what lets containers reach IMDSv2. The hop limit only constrains the token response, so it does nothing while IMDSv1 is still allowed: a container can simply use a token-less GET. Blocking containers needs HttpTokens=required and a hop limit of 1 together. Setting HttpEndpoint=disabled turns the service off for everything on the instance, host agents included.

Enforcing IMDSv2 for existing and future instances

The settings that decide an instance's metadata options apply in a fixed order of precedence: launch parameters win over the account-level IMDS defaults for the Region, which win over the AMI's ImdsSupport=v2.0 setting. A default is therefore only a default: a launch that explicitly asks for HttpTokens=optional still succeeds. Only two things make an IMDSv1 launch fail:

  • A deny: an SCP or IAM policy that denies ec2:RunInstances when ec2:MetadataHttpTokens is not required (and denies ec2:ModifyInstanceMetadataOptions so running instances cannot be switched back).
  • Account-level IMDSv2 enforcement (the HttpTokensEnforced account setting), which rejects launches and modifications that would leave IMDSv1 enabled.

Across an organization, EC2 declarative policies in AWS Organizations set these account-level IMDS settings centrally, and member accounts cannot change them locally. Existing instances are not altered by any default: change each one with ModifyInstanceMetadataOptions (Systems Manager Automation can do this at scale), and find stragglers with the AWS Config rule ec2-imdsv2-check or the CloudWatch MetadataNoToken metric, which counts IMDSv1 calls still being made.

The detection backstop is GuardDuty's UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS, which fires when an instance role's credentials are used from outside AWS: evidence the metadata service has already leaked.

Instance profiles and pinning role credentials to your network

An instance profile is the right way to give an EC2 workload AWS permissions because it delivers the role's temporary, automatically rotated credentials through the metadata service, so nothing long-lived is ever stored on the host. The alternatives people reach for each reintroduce a stored secret:

ApproachWhat the host must holdVerdict for EC2
Instance profile (IAM role)Nothing; credentials come from IMDS and rotate automaticallyCorrect
IAM user access keys in a file or environment variableLong-term keysAvoid; rotation and leakage are your problem
sts:GetSessionTokenThe IAM user's long-term keys, because only an IAM user can call itStill a stored secret
IAM Roles AnywhereAn X.509 certificate and its private keyBuilt for workloads outside AWS; on EC2 it swaps a role for a stored private key

Making stolen instance credentials useless off the instance

Even role credentials can be copied. AWS adds two condition keys to every request signed with EC2 role credentials: aws:Ec2InstanceSourceVpc (the VPC the instance runs in) and aws:Ec2InstanceSourcePrivateIPv4 (its primary private IP). Comparing them with where the request actually came from pins the credentials to their network. A typical deny statement in an SCP says:

  • deny when aws:Ec2InstanceSourceVpc does not equal ${aws:SourceVpc} (or aws:Ec2InstanceSourcePrivateIPv4 does not equal ${aws:VpcSourceIp});
  • only for EC2 role credentials: scope it with a Null condition that ec2:SourceInstanceARN is present, or the statement also denies IAM users and every other role;
  • except when aws:ViaAWSService is true, so services calling onward on the role's behalf (for example S3 to KMS) still work.

This works only where requests reach AWS through VPC endpoints, because aws:SourceVpc and aws:VpcSourceIp exist only for endpoint traffic. The near-misses are instructive: aws:SourceIp is not present on requests that arrive through a VPC endpoint, so comparing the instance IP with it never matches; and merely requiring that aws:SourceVpc is non-null admits an attacker who replays the credentials through an endpoint in their own VPC. The comparison between the instance's VPC and the request's VPC is what does the work.

Golden AMIs and patching: Image Builder, Patch Manager, and encrypted defaults

A golden AMI is a hardened, tested base image that every instance launches from, so fleet hardening happens before boot instead of on each running host. EC2 Image Builder turns that into a managed pipeline: a base image, an ordered list of build components (install agents, remove packages, apply hardening; Amazon-managed STIG hardening components, and CIS hardening components published by CIS through AWS Marketplace), test components that validate the result, and distribution of the finished AMI or container image across Regions and accounts. Images inherit the baseline, including IMDSv2-required metadata defaults and pre-installed SSM and CloudWatch agents.

Keeping the golden image current

An Image Builder pipeline runs manually or on a schedule, and the schedule has a start condition:

  • EXPRESSION_MATCH_ONLY: build every time the cron expression matches, even if nothing changed.
  • EXPRESSION_MATCH_AND_DEPENDENCY_UPDATES_AVAILABLE: at each match, build only if a newer base image or component version resolves.

Image Builder can only detect an update when the recipe refers to versions with semantic-version wildcards (for example x.x.x). A recipe that pins exact versions always resolves to the same inputs, so the dependency-driven condition never fires. Rebuilding promptly after an upstream change, and never when nothing changed, therefore takes all three pieces: a frequent schedule, the dependency-update start condition, and wildcard versions in the recipe.

Choosing the image-building tool

ToolWhat you getWhat you build yourself
EC2 Image BuilderManaged hardening (STIG) and test components, distribution, schedules, dependency-driven rebuilds, Inspector scanning of outputsOnly your own custom components
Systems Manager Automation (for example AWS-UpdateLinuxAmi) or Packer in a pipelineA patched AMI from a runbook or templateHardening, tests, cross-Region copy and sharing scripts
AWS Backup or CreateImage on an existing instanceA copy of what is already runningNo hardening or testing at all; it is a backup, not a golden image

Patching running fleets

Running instances still drift, which is Systems Manager Patch Manager's job. Patch baselines define which classifications and severities are approved (with auto-approval delays); patch policies, created through Quick Setup, apply scan and install schedules across an organization's accounts and Regions in one configuration (the older approach pairs patch groups with maintenance windows per account). Compliance flows into Systems Manager Compliance and on to Security Hub CSPM.

Know the boundary: Patch Manager patches operating system packages. Amazon Inspector also reports vulnerable language packages (pip, npm, Maven JARs) that an application bundles. A server can therefore be "patch compliant" while Inspector shows an open critical finding; that fix is a dependency update in the application build and a redeploy, not another patch run. That is the continuous-validation loop in Skill 3.2.4: Patch Manager acts, Inspector verifies.

Storage defaults close the loop. Enable EBS encryption by default per Region so every new volume and snapshot is KMS-encrypted, and build AMIs from encrypted snapshots. Key policies and cross-account snapshot sharing belong to Domain 5.

Amazon Inspector: continuous vulnerability management as a loop

Amazon Inspector is the continual vulnerability scanner for EC2, ECR images, and Lambda: you enable it (organization-wide through a delegated administrator) and it discovers and re-assesses resources automatically instead of running one-off assessments.

  • EC2: agent-based scanning uses the SSM Agent to inventory packages, so the instance must be a Systems Manager managed node; agentless scanning (hybrid scan mode) assesses EBS snapshots for instances that are not.
  • ECR: images in repositories with enhanced scanning, covered in the ECR section below.
  • Lambda: standard scanning finds vulnerable dependencies in function packages and layers; code scanning also inspects your own function code for flaws such as injection and embedded credentials.

Reading a finding's scores

ScoreWhat it measuresUse it for
CVSS base scoreThe vendor's severity of the vulnerability in the abstractHow bad the flaw is anywhere
EPSS scoreProbability the CVE is exploited in the wild soon (Exploit Prediction Scoring System)Threat likelihood across everyone
Inspector scoreCVSS adjusted for your environment, such as network reachability and exploit availabilityPrioritising remediation in this account

A critical CVE on an unreachable instance can rank below a moderate one on an internet-facing host, so prioritise by the Inspector score.

The pattern the exam rewards is the remediation loop: findings flow to Security Hub CSPM for aggregation and to EventBridge for action, such as running Patch Manager, starting an Image Builder pipeline to rebuild the golden AMI, notifying the owner, or failing a deployment. Inspector sees what is installed; GuardDuty Runtime Monitoring (next section) sees what is happening.

GuardDuty runtime threat detection for containers, EC2, and Lambda

GuardDuty Runtime Monitoring detects threats inside running workloads, such as a process starting a cryptocurrency miner, a reverse shell, or a binary being modified, which complements Inspector's static view of known vulnerabilities. It uses a GuardDuty security agent that reports process, file, and network events, and it covers three targets:

TargetHow the agent arrives
Amazon EKSThe GuardDuty EKS add-on, managed by GuardDuty with automated agent configuration
Amazon ECS on FargateA sidecar container GuardDuty injects into new tasks
Amazon EC2 (including ECS on EC2)An agent installed through Systems Manager, so the instance must be a managed node

Automated agent configuration also creates the VPC endpoint the agent uses to send telemetry.

Fargate prerequisites that fail quietly

On Fargate, tasks that run without the sidecar simply show as uncovered. Check that:

  • tasks run on platform version 1.4.0 or later;
  • the task execution role can pull from ECR (ecr:GetAuthorizationToken plus the pull actions), because the sidecar image comes from a GuardDuty-owned ECR repository even when your own images come from elsewhere;
  • tasks have a network path to ECR (NAT or ECR endpoints);
  • no SCP or permissions boundary denies guardduty:SendSecurityTelemetry.

Lambda and the other protection plans

Runtime Monitoring does not support Lambda. GuardDuty Lambda Protection covers functions agentlessly by analysing their network activity logs, which is how it flags a hijacked function talking to a cryptocurrency mining pool (finding type CryptoCurrency:Lambda/BitcoinTool.B). EKS Protection analyses Kubernetes audit logs (control-plane activity), while Runtime Monitoring watches inside the nodes and containers; enabling both gives the fullest EKS coverage.

ECR: securing the image supply chain

Amazon ECR is where container security starts, because every downstream control depends on trusting what is in the registry. Four controls matter: scanning, immutable tags, repository policies, and encryption.

Scanning: type, frequency, and re-scan duration

SettingOptionsWhat it means
Basic scanningScan on push, or manualOperating system packages only; no rescans when new CVEs appear
Enhanced scanning: scan on pushPer-repository filterAmazon Inspector scans OS and language packages once, at push
Enhanced scanning: continuousPer-repository filterScans at push, then rescans whenever Inspector learns of a new CVE

Continuous scanning is a frequency of enhanced scanning only. It does not run forever: Inspector's ECR re-scan duration decides how long an image stays monitored, and images outside the window become inactive and are no longer rescanned. You set two durations:

  • a push date duration: 3, 7, 14, 30, 60, 90 or 180 days, or Lifetime;
  • an image re-scan duration in one of two modes, either last in use (the default) or last pull date, from 3 to 180 days. Last-in-use tracking only sees images running on ECS or EKS clusters; an image run some other way, such as directly with Docker on an EC2 host, records no in-use activity, so only its pull and push dates count.

New accounts start with short (14-day) windows, so a long-running image deployed outside ECS or EKS silently drops out of monitoring unless the push-date duration is extended (Lifetime keeps it monitored indefinitely).

Immutable tags

With tag immutability, a tag can never be overwritten to point at a different image. Without it, someone can push a new image as myapp:prod and every task definition using that tag silently deploys the replacement, a supply-chain attack scanning does not stop. Referencing images by digest is the strictest form of the same idea.

Repository policies and cross-account pull

A cross-account pull needs permission on both sides. The registry account's repository policy grants the consuming principals the three pull actions: ecr:BatchGetImage, ecr:GetDownloadUrlForLayer and ecr:BatchCheckLayerAvailability. The puller also needs ecr:GetAuthorizationToken, which is a registry-wide action on resource *: it cannot be granted in a repository policy and must sit in the puller's own identity policy (for ECS, the task execution role). Keep push rights to the CI/CD role.

Encryption and provenance

Repositories encrypt images with AES-256 or KMS; choose a customer managed key for key-level access control and CloudTrail visibility of decryption. Lifecycle policies expire stale images. Image signing (AWS Signer with Notation) addresses provenance, not vulnerabilities.

ECS and Fargate: task roles, execution roles, and task hardening

The most reliably tested distinction in container security is the two roles attached to an ECS task — because they answer different questions:

AspectTask execution roleTask role
Who uses itThe ECS agent / Fargate infrastructure, on your behalfYour application code inside the containers
WhenTask startup: pulling the image, setting up logging, injecting secretsRuntime: every AWS API call the app makes
Typical permissionsecr:GetAuthorizationToken, image pull actions, logs:CreateLogStream/PutLogEvents, secretsmanager:GetSecretValue for secrets referenced in the task definitionDynamoDB, S3, SQS — whatever the workload actually needs, least-privilege
Failure mode when wrongTask fails to start: cannot pull image, cannot inject secretRunning app gets AccessDenied on its own API calls

The trap: secrets referenced in the task definition's secrets block — injected as environment variables from Secrets Manager or SSM Parameter Store at startup — are fetched by the execution role. Secrets fetched by application code at runtime use the task role (delivered via the container credentials endpoint, per-task, so co-located tasks never share credentials). Granting the wrong role is the classic broken deployment, walked through in the final section.

Fargate hardens the substrate: each task runs in its own isolated environment with a dedicated kernel — no shared host to escape to, no privileged containers, no host-path mounts, and AWS patches the underlying infrastructure. Within any task, set readonlyRootFilesystem in the container definition so a compromised process cannot modify its own filesystem, drop non-root users in the image, and keep containers from running with elevated Linux capabilities.

The other two ECS roles

Two more roles act for ECS itself, never for your containers. The service-linked role (AWSServiceRoleForECS) is created automatically and lets ECS manage network interfaces for awsvpc tasks and register targets with load balancers. The ECS infrastructure role is one you create so ECS can manage infrastructure for specific features, such as Amazon EBS volumes attached to tasks or VPC Lattice. Neither grants the application anything: runtime API access is always the task role.

EKS essentials: pod identity, audit logs, and the private control plane

EKS security at specialty level reduces to three controls; deep Kubernetes administration is out of scope, but these are fair game.

Least-privilege pod identity. The anti-pattern is giving the node's instance role every permission any pod might need — every pod on the node then holds the union. The fix is per-pod credentials: IAM Roles for Service Accounts (IRSA) associates an IAM role with a Kubernetes service account through the cluster's OIDC identity provider — pods assume the role with sts:AssumeRoleWithWebIdentity using a projected service account token, and the role's trust policy names the specific service account. The newer EKS Pod Identity feature reaches the same goal with less setup: an EKS-run agent and a direct association between role and service account, no per-cluster OIDC provider registration. Either way, the exam answer to "one pod needs S3 access, others must not have it" is pod-level identity, never node-role inflation. Blocking pods from the node's instance metadata (or enforcing IMDSv2 with hop limit 1) closes the fallback path to node credentials.

Control-plane audit logs. EKS can ship five control-plane log types to CloudWatch Logs — api, audit, authenticator, controllerManager, and scheduler. They are off by default; the audit and authenticator streams are the ones that answer "who did what to the cluster," and GuardDuty's EKS audit log monitoring consumes this activity for threat detection.

Private endpoint. The cluster API server endpoint is public by default. Disable public access (or restrict it to allowlisted CIDRs) and enable the private endpoint so kubectl and node-to-control-plane traffic stay inside the VPC — an internet-reachable API server is an unnecessary attack surface even with authentication in front of it.

Lambda security: execution roles, resource policies, and the confused deputy

Lambda has two independent permission surfaces, and questions turn on which one is broken. The execution role governs what the function can do: the service assumes it at invocation and hands its credentials to your code. Least privilege means one role per function, not a shared role with accreted permissions.

The resource-based policy governs who may invoke the function. When S3, SNS, or an EventBridge rule invokes a function, the service principal (for example s3.amazonaws.com) needs lambda:InvokeFunction in the function's policy. That grant creates the confused-deputy risk: without conditions, a resource in a stranger's account could trigger your function through the trusted service.

Scoping service grants: aws:SourceArn and aws:SourceAccount

aws:SourceArn names the triggering resource, and aws:SourceAccount names the account that owns it. For S3 you need both: S3 bucket ARNs contain no account ID, so if your bucket is deleted and someone re-creates the same name in another account, a SourceArn-only condition still matches. aws:ResourceAccount is not a substitute: it describes the account owning the resource being called, which is the function's own account, not the bucket's.

EventBridge rules versus EventBridge Scheduler

InvokerHow it is authorized
EventBridge ruleThe function's resource-based policy allows events.amazonaws.com, scoped to the rule's ARN
EventBridge SchedulerAn execution role that scheduler.amazonaws.com assumes, whose identity policy allows lambda:InvokeFunction

The console adds a rule's resource-policy statement automatically; infrastructure as code does not, so a CloudFormation or CDK deployment must declare the permission (for example an AWS::Lambda::Permission resource) or the rule's invocations fail.

VPC attachment, environment variables, signing

VPC attachment is about egress, not ingress: it lets the function reach private resources like RDS and removes default internet access (add a NAT gateway or VPC endpoints), but it does not change who can invoke the function; invocation always flows through the Lambda API and IAM. Environment variables are encrypted at rest with KMS; prefer Secrets Manager for real secrets so rotation exists. Code signing with AWS Signer lets Lambda reject unsigned or modified packages.

Secure administrative access: Session Manager and EC2 Instance Connect

The secure way to administer compute is Systems Manager Session Manager: IAM-authorized shells with no inbound ports, no bastion hosts, no SSH keys, and session logging to S3 or CloudWatch Logs. The other options each give up one of those properties, and the exam separates them by requirement.

MethodInbound rule on the instanceKeysSession data logged
Session Manager shellNone; the SSM Agent connects outboundNoneYes, to S3 and/or CloudWatch Logs
Session Manager port forwarding (to the node, or to a remote host such as an RDS endpoint through the node)None on the managed nodeNoneNo; the tunnel's traffic is not recorded
SSH over Session ManagerNoneSSH key pair still requiredNo
EC2 Instance Connect (public)Port 22 from the EC2 Instance Connect service rangeShort-lived key pushed per connectionNo
EC2 Instance Connect EndpointPort 22 (or 3389) from the endpoint's security group or VPC CIDRPushed key for SSH; your own credentials for RDPNo; connections are recorded in CloudTrail

Two details trip people up. First, an EC2 Instance Connect Endpoint removes the need for a public IP or bastion, but it still needs the instance's security group to allow port 22 or 3389 from the endpoint (and the endpoint's outbound rules to reach the instance); inbound rules on the endpoint's own security group are not used. Because this is a network rule, getting it wrong shows up as a connection timeout rather than an IAM access-denied error. Second, port forwarding is how a laptop GUI client reaches a private database without opening any inbound rule: Session Manager forwards a local port through a managed node to the remote host. Only native Session Manager shell sessions record what was typed and shown; SSH over Session Manager and port-forwarding sessions carry an encrypted or opaque stream, so their contents are not logged.

Finding vulnerabilities in the pipeline: Amazon Q Developer and Inspector code security

Pipeline vulnerability scanning means finding flaws in code, dependencies, and infrastructure as code before they reach production, at each stage from the developer's editor to the image registry. The exam guide names Amazon CodeGuru Security, but AWS ended support for CodeGuru Security on 20 November 2025; its jobs moved to Amazon Q Developer and Amazon Inspector. (CodeGuru Profiler, a performance tool, is a different product.)

StageToolWhat it does
Writing codeAmazon Q Developer code reviews in the IDEFinds hardcoded credentials, injection flaws, vulnerable dependencies and IaC misconfigurations before commit, with suggested fixes
RepositoryAmazon Inspector code securityConnects to GitHub or GitLab; runs SAST (first-party code), SCA (third-party dependencies) and IaC rule sets on pull requests or pushes, or on a weekly or monthly schedule
BuildInspector CI/CD integration (SBOM Generator plus the Scan API)Generates an SBOM for the built image or artifact in CodeBuild, Jenkins or similar, and fails the build on findings above a threshold before anything is pushed
Registry and runtimeECR enhanced scanning, Inspector for EC2 and LambdaContinuous rescans of what is already deployed

The distinction to hold: registry scanning happens after push, so it can report a bad image but cannot keep one out of a shared registry. Gating means scanning in the build. Remediation is the same loop as runtime: findings to Security Hub CSPM and EventBridge, fixes through the dependency file or the base image, then a rebuild.

Guardrails for generative AI applications: OWASP LLM risks and Bedrock Guardrails

Protecting a generative AI application means mitigating the risks in the OWASP Top 10 for LLM Applications with controls around the model, because the model itself cannot be trusted to refuse. The risks most often mapped to AWS controls:

OWASP riskWhat goes wrongAWS controls
Prompt injection (direct and indirect)User text, or content the app retrieves (documents, emails, tool results), overrides the instructionsBedrock Guardrails prompt attack filter on tagged user input; treat retrieved content as untrusted; limit what the model can do
Sensitive information disclosurePII or secrets appear in prompts, responses, or logsGuardrails sensitive information filters; CloudWatch Logs data protection; least-privilege data access
Excessive agencyAn agent's tools can do more than the task needsLeast-privilege action group roles, limits in code, human confirmation
Improper output handlingModel output is passed unchecked to a shell, browser, or SQLValidate and encode output like any untrusted input
Unbounded consumptionRunaway cost or denial of serviceQuotas, throttling, WAF rate limits on the front end

Amazon Bedrock Guardrails

A guardrail is a reusable, versioned policy evaluated on input and output, with content filters, denied topics, word filters, sensitive information filters, contextual grounding checks and a prompt attack filter. It applies when you pass its ID and version on an inference call, or on any text through the ApplyGuardrail API.

  • Sensitive information filters take an action per entity type (or custom regex) and per direction: block rejects the whole input or response; mask (anonymize) replaces the entity with a placeholder such as {PHONE} and lets the rest through. Choose block when any occurrence must stop the exchange; choose mask when the rest of the content is still useful without the entity.
  • The prompt attack filter only evaluates input you mark as user input. With InvokeModel or InvokeModelWithResponseStream, wrap the user's text in the guardrail's input tags; with the Converse API, use guard content blocks. Untagged text, including user content embedded in an untagged prompt template, is not checked for prompt attacks, and tagging the developer's own instructions would make them look like attacks.

Logs keep the original

Bedrock model invocation logging records the request and response as sent, so a guardrail masking PII in the application does not mask it in the logs. Attach a CloudWatch Logs data protection policy to the log group to mask identifiers at rest in the log view, and grant logs:Unmask only to those who may see the originals (S3 log destinations need their own controls).

Agents and excessive agency

A Bedrock agent acts through action groups, usually Lambda functions. Limit the blast radius in layers: give each action group function a least-privilege role; enforce business limits (amounts, record scope) in the function code rather than trusting the model to respect them; and turn on user confirmation for high-impact functions so a person approves each call. These matter most when an agent reads untrusted content, such as emails returned by another tool, because instructions hidden in that content (indirect prompt injection) arrive as tool output rather than as tagged user input.

Troubleshooting compute controls: the four classic failures

Instance not a Systems Manager managed node. An instance missing from Fleet Manager (so Session Manager, Patch Manager, Inspector agent-based scanning and GuardDuty's EC2 agent all fail) has one of three causes, checked in this order:

  1. Agent: the SSM Agent is not installed, not running, or too old.
  2. Permissions: either an instance profile with AmazonSSMManagedInstanceCore, or Default Host Management Configuration (DHMC), which lets Systems Manager manage instances with no instance profile by having the agent use the AWSSystemsManagerDefaultEC2InstanceManagementRole service role.
  3. Network path: in private subnets, interface endpoints for ssm and ssmmessages (recent agents use ssmmessages where older ones used ec2messages, so many setups still create all three), or NAT egress.

DHMC has prerequisites of its own: SSM Agent 3.2.582.0 or later and IMDSv2 on the instance (it uses the instance identity from the metadata service). If an instance profile is attached, the agent uses it only when it allows ssm:UpdateInstanceInformation; otherwise it falls back to DHMC. An agent older than that minimum cannot use DHMC at all, so the agent version baked into an image matters as much as the setting itself.

Inspector not scanning an instance. Usually the same root cause, because agent-based EC2 scanning rides on SSM management. Fix SSM coverage first; agentless snapshot scanning is the fallback.

Scenario: the task that cannot read its secret. A new ECS service's tasks stop immediately with ResourceInitializationError: unable to pull secrets or registry auth. The failure is at startup, so this is execution-role territory. Check, in order: (1) the execution role grants secretsmanager:GetSecretValue on the secret ARN in the task definition's secrets block, plus kms:Decrypt if the secret uses a customer managed key; (2) it can pull the image (ecr:GetAuthorizationToken plus the pull actions, and the repository policy if ECR is cross-account); (3) tasks in private subnets can reach Secrets Manager and ECR: interface endpoints for secretsmanager, ecr.api and ecr.dkr, plus the S3 gateway endpoint ECR uses for image layers. Permissions added to the task role cannot fix a startup failure.

Lambda AccessDenied on invoke. The caller is refused before the function runs, so inspect the resource-based policy (or, for EventBridge Scheduler, the schedule's execution role): the invoker needs lambda:InvokeFunction, with aws:SourceArn and aws:SourceAccount matching the real source. The function's execution role is irrelevant to who may invoke it.

Tip. Task 3.2 scenarios map a symptom or requirement to the right control. "An SSRF flaw exposed instance credentials" means IMDSv2; "containers must lose IMDS but the host agent must keep it" means tokens required plus hop limit 1; "IMDSv1 launches must fail" needs a deny on ec2:MetadataHttpTokens or account-level enforcement, not a default. "Stolen instance credentials must not work elsewhere" is the aws:Ec2InstanceSourceVpc comparison. Startup failures (image pull, secret injection, a missing GuardDuty sidecar) point at the execution role or network path, never the task role. "Rescan images when new CVEs appear" is enhanced continuous scanning, and images that stopped being rescanned point at the re-scan duration. "AccessDenied invoking the function" is the resource-based policy, scoped with aws:SourceArn and aws:SourceAccount. Admin-access questions turn on inbound rules, keys and logging; pipeline questions on the stage (IDE, repository, build); GenAI questions on block versus mask, tagged input, and agent permissions.

Key takeaways
  • IMDSv2 defeats SSRF credential theft; a hop limit of 1 keeps bridged containers out only when HttpTokens is required. Launch parameters beat account defaults, which beat the AMI setting, so only an ec2:MetadataHttpTokens deny or account-level IMDSv2 enforcement makes an IMDSv1 launch fail.
  • Instance profiles store nothing on the host; GetSessionToken and IAM Roles Anywhere both depend on a stored secret. Pin role credentials with aws:Ec2InstanceSourceVpc compared to ${aws:SourceVpc}, scoped to ec2:SourceInstanceARN and excluding aws:ViaAWSService.
  • Image Builder rebuilds only on new dependencies with EXPRESSION_MATCH_AND_DEPENDENCY_UPDATES_AVAILABLE and x.x.x recipe versions; Patch Manager patches OS packages, so open Inspector findings on language packages are fixed in the application build.
  • Prioritise by the Inspector score (CVSS adjusted for reachability and exploitability), not raw CVSS; EPSS estimates exploitation likelihood.
  • GuardDuty Runtime Monitoring covers EKS, ECS on Fargate and EC2 with an agent; Lambda is covered by Lambda Protection through network activity logs.
  • ECR continuous scanning is an enhanced-scanning frequency bounded by Inspector re-scan durations; cross-account pull needs the repository policy for the three pull actions and ecr:GetAuthorizationToken in the puller's identity policy.
  • Execution role at task startup, task role at runtime; the service-linked and infrastructure roles act for ECS, never for your code.
  • On EKS, grant AWS access per pod with IRSA or EKS Pod Identity, never by inflating the node instance role; enable control-plane audit logs and prefer a private API endpoint.
  • Lambda's resource policy decides who invokes it: scope S3 grants with both aws:SourceArn and aws:SourceAccount; EventBridge Scheduler uses its own execution role instead.
  • Only native Session Manager shells log session data; EC2 Instance Connect Endpoint still needs port 22 or 3389 open on the instance from the endpoint.
  • CodeGuru Security has ended; scan in the IDE with Amazon Q Developer, in repositories with Inspector code security, and gate builds with the Inspector SBOM Generator and Scan API.
  • Bedrock Guardrails mask or block sensitive data per direction and check prompt attacks only on tagged user input; invocation logs keep the original text, so mask them with CloudWatch Logs data protection.

Frequently asked questions

How does IMDSv2 prevent SSRF attacks from stealing EC2 credentials?

IMDSv2 requires a session token obtained with a PUT request carrying the X-aws-ec2-metadata-token-ttl-seconds header, and every metadata read must present that token. Typical SSRF flaws let an attacker trigger simple GET requests but not custom-header PUTs, so the attacker never gets the token needed to read the instance role's credentials. A hop limit of 1 additionally stops the token response from reaching containers on a bridged network, but only when HttpTokens is set to required; while IMDSv1 is allowed, a token-less GET still works.

What is the difference between an ECS task role and a task execution role?

The task execution role is used by the ECS agent and Fargate infrastructure to start your task: pulling the container image from ECR, creating and writing CloudWatch log streams, and fetching secrets referenced in the task definition for injection as environment variables. The task role is assumed by your application code at runtime for its own AWS API calls, delivered through the per-task container credentials endpoint. Startup failures (image pull, secret injection) point at the execution role; runtime AccessDenied errors point at the task role.

Why does my ECS task fail with 'unable to pull secrets or registry auth'?

This is a startup-time ResourceInitializationError, so the task execution role or the network path is at fault. Verify the execution role has secretsmanager:GetSecretValue on the referenced secret (plus kms:Decrypt if it uses a customer managed key) and the ECR pull permissions; check any cross-account ECR repository policy; and for tasks in private subnets, confirm interface endpoints for secretsmanager, ecr.api, and ecr.dkr plus the S3 gateway endpoint exist. Adding permissions to the task role will not fix a startup failure.

How does Amazon Inspector scan EC2, ECR, and Lambda?

Inspector runs continually once enabled. EC2 instances are scanned through the SSM Agent when they are Systems Manager managed nodes, with agentless EBS-snapshot scanning for the rest. ECR images in repositories with enhanced scanning are scanned on push, and with the continuous frequency they are rescanned when new CVEs are published, for as long as the re-scan duration keeps them active. Lambda standard scanning covers dependency vulnerabilities, and code scanning inspects function code. Findings carry an Inspector score that adjusts CVSS for reachability and exploit availability.

Does putting a Lambda function in a VPC make it more secure?

Only for outbound traffic. VPC attachment controls where the function's egress goes — it can reach private resources such as RDS, loses default internet access unless you add NAT or VPC endpoints, and its traffic is subject to your network controls. It does not change who can invoke the function: invocation always goes through the Lambda API and is governed by IAM and the function's resource-based policy. To restrict invokers, scope the resource-based policy with aws:SourceArn and aws:SourceAccount.

How do pods on EKS get least-privilege access to AWS services?

Use IAM Roles for Service Accounts (IRSA) or the newer EKS Pod Identity. IRSA links an IAM role to a Kubernetes service account through the cluster's OIDC provider, and pods assume it via sts:AssumeRoleWithWebIdentity using a projected token; Pod Identity achieves the same per-pod credentials through an EKS-managed agent and a direct role-to-service-account association without per-cluster OIDC setup. Both avoid the anti-pattern of granting permissions to the node instance role, where every pod on the node would inherit them.

What is the difference between Session Manager and EC2 Instance Connect Endpoint?

Session Manager connects through the SSM Agent's outbound channel, so the instance needs no inbound security group rules, no SSH keys, and native shell sessions can be logged to S3 or CloudWatch Logs. EC2 Instance Connect Endpoint lets you reach instances in private subnets without a public IP or bastion, but the instance's security group must still allow port 22 (or 3389) from the endpoint, and session contents are not logged. Port forwarding and SSH over Session Manager also need no inbound rules, but neither records session data, and SSH still needs keys.

How do Amazon Bedrock Guardrails protect a generative AI application?

A Bedrock guardrail is a versioned policy applied to model inputs and outputs. Its sensitive information filters block or mask PII per entity type and direction, its prompt attack filter detects jailbreaks and prompt injection in input that is wrapped in the guardrail input tags (or guard content blocks with Converse), and content filters, denied topics and contextual grounding checks cover harmful or ungrounded output. Guardrails do not mask model invocation logs, which keep the original text, and they do not replace least-privilege permissions and human confirmation for agent actions.

Source

This lesson covers the "Infrastructure Security" domain of the official SCS-C03 exam guide. Vendors revise their guides — check the source for the current version.

Test yourself on this topic
Practice now

Sign up free to mark lessons complete, bookmark topics and track your exam readiness.

Spotted a mistake in this lesson?