Join our Newsletter — 33% off our NHI Course
Home› Guides› Amazon ECS and Fargate Security Guide: Task Roles…
Guide Cloud Security

Amazon ECS and Fargate Security Guide: Task Roles and Secrets

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 27 October 2026 12 min read
On this page

Most Amazon ECS security problems come down to confusing two IAM roles: the task execution role that the platform uses to start a task, and the task role that the application uses at runtime, and then giving one or both far more access than the workload needs. Add secrets passed as environment variables, ECS Exec left open on production and containers on EC2 hosts that can reach the instance profile, and a single container compromise becomes an account compromise. This guide covers ECS identity end to end on both Fargate and the EC2 launch type: the two roles, iam:PassRole, secrets injection, ECS Exec, logging, runtime monitoring and a hardening baseline. It complements the broader Container Security Guide and is written for platform engineers and cloud security teams running ECS.

Key takeaways

  • Two roles, two audiences. The task execution role is used by the ECS and Fargate agents and is not accessible to containers; the task role is what your code gets. Never merge them.
  • PassRole is the escalation path. Anyone who can register a task definition and run a task, and can pass a powerful role, can run code with that role's permissions.
  • Secrets are injected once. Values from Secrets Manager or Parameter Store arrive as environment variables at container start and are not refreshed on rotation.
  • Fargate isolates tasks; EC2 does not. AWS states containers are not a security boundary; on EC2 hosts a container may reach other tasks' credentials and the instance role unless you block it.
  • ECS Exec is a shell as root. Gate ecs:ExecuteCommand with conditions, log sessions, and deny direct ssm:StartSession on tasks.

How identity and access work in Amazon ECS

IdentityUsed byTypical permissionsReachable from the container?
Task execution roleECS container agent and Fargate agentPull images from ECR, write awslogs to CloudWatch Logs, fetch referenced secrets and parameters, private registry credentials, Runtime MonitoringNo
Task roleApplication code in the task, through the credentials endpoint at 169.254.170.2Whatever the app calls: S3, DynamoDB, SQS and so onYes
Container instance role (EC2 launch type)The ECS agent on the hostRegister the instance, pull tasksYes, through instance metadata, unless blocked
Service-linked roleAmazon ECS serviceManage load balancer targets, ENIsNo
Human and pipeline principalsEngineers and CI/CDecs:* actions, iam:PassRole, ecs:ExecuteCommandNot applicable

Task role

  • Trust policy: allow the ecs-tasks.amazonaws.com service principal, with aws:SourceAccount and an ArnLike aws:SourceArn condition such as arn:aws:ecs:us-west-2:111122223333:* to prevent confused deputy use. AWS notes aws:SourceArn does not yet support scoping to a single cluster.
  • Granularity: the task role page recommends a separate role per task definition or service with only the permissions it needs. AWS's ECS IAM best practices also suggest treating the cluster as an administrative boundary to avoid unmanageable role sprawl. A workable compromise is one role per service in production and per cluster in development.
  • Auditability: task credentials carry the taskArn in the session context, so CloudTrail shows which task used them. See the AWS CloudTrail Guide.
  • SDK behaviour: containers using a task role do not inherit instance permissions; the SDKs read credentials from the container credential provider endpoint.

Task execution role

Start from the managed policy AmazonECSTaskExecutionRolePolicy (ECR pull and CloudWatch Logs), then add only the secret retrieval you need: ssm:GetParameters, secretsmanager:GetSecretValue and kms:Decrypt scoped to the specific parameter, secret and key ARNs. Restrict image pulls to your VPC endpoint with aws:SourceVpce, and when the role reads configuration files from S3, require aws:ResourceAccount so a recreated bucket in another account cannot serve them.

Admin roles and privileged access

  • Control iam:PassRole: registering a task definition or running a task that names a role requires iam:PassRole on it. Allow it only on specific role ARNs and add iam:PassedToService equal to ecs-tasks.amazonaws.com. A developer with ecs:RegisterTaskDefinition, ecs:RunTask and PassRole on * effectively holds every role in the account. See the AWS IAM Policies and Roles Guide.
  • Deploy through pipelines: AWS recommends automated pipelines create, update and delete tasks so end users do not need direct ECS API access in production.
  • Use conditions: require MFA for destructive actions such as ecs:DeleteCluster and restrict RunTask, StartTask and StopTask by resource tags (service tags propagate to tasks).
  • Gate ECS Exec: allow ecs:ExecuteCommand only with conditions such as ecs:cluster, ecs:container-name or ecs:ResourceTag/environment, and deny it for production containers by default. Grant time-bound access through your privileged access process. See the Cloud PAM and CIEM Guide.

ECS Exec in detail

ECS Exec uses Systems Manager Session Manager: the agent bind-mounts the SSM agent into the container and the task role needs Session Manager (ssmmessages) permissions. Points that matter for security:

  • Commands run as root, even if the container defines a non-root user.
  • It cannot be combined with readonlyRootFilesystem, so enabling it weakens that control.
  • It must be enabled with --enable-execute-command when a task starts, so a policy that blocks the flag in production prevents it entirely (condition key ecs:enable-execute-command).
  • Session logging is configured on the cluster in executeCommandConfiguration (NONE, DEFAULT or OVERRIDE to CloudWatch Logs or S3, optionally KMS encrypted). The image needs script and cat for logging to work.
  • Sessions started directly with ssm:StartSession bypass ECS Exec logging; deny ssm:StartSession on task resources.

Integrations, API tokens and service accounts

Secrets injection options

MethodHow it worksExposureUse when
Plaintext environmentValue written in the task definitionVisible to anyone who can describe task definitions; flagged by Security Hub ECS.8Never for secrets
secrets with valueFromExecution role fetches from Secrets Manager or Parameter Store at start; injected as environment variableCan appear in logs and docker inspect; not refreshed on rotationDefault for most services
Sidecar to shared volumeA sidecar reads the secret and writes it to a volume before the app startsFile on task storage, deleted when the task stopsHigh-sensitivity values
Application reads at runtime with task roleApp calls Secrets Manager directly using its task roleOnly in process memory; supports rotation without restartRotating database credentials
  • JSON keys and versions: valueFrom accepts secret-name:json-key:version-stage:version-id, so inject only the field you need rather than a whole JSON document.
  • Rotation: after rotating an injected secret, force a new deployment of the service or replace standalone tasks. Build that into the rotation runbook. See the Cloud Secrets Managers Guide.
  • Logging drivers and registries: use secretOptions in logConfiguration for log platform tokens and repositoryCredentials for private registries rather than embedding them.
  • Images: never bake secrets into images. The Docker Hub secrets leak found 10,456 public images exposing secrets, and about three quarters of secrets removed from images were still active. See the Secrets in Container Images and Build Artefacts Guide.

Machine identities beyond AWS

Tasks often hold third-party API keys and database passwords as well as AWS roles. Give each a named owner, store it in Secrets Manager with a resource policy limited to the task's execution role or task role, and track it in your non-human identity inventory. Where the third party supports workload identity federation, prefer it over static keys. See the Cloud Workload Identity Guide.

Fargate versus the EC2 launch type

AspectFargateEC2 launch type
Task isolationEach task in its own isolated environment; no shared ENI, ephemeral storage, CPU or memory with other tasksNo task isolation; co-located tasks may reach each other's credentials and data
Instance role exposureNo instance profile available to containersReachable via instance metadata unless blocked
Privileged containersNot available; only SYS_PTRACE can be addedPossible; must be blocked by policy (Security Hub ECS.4)
Host accessNeither customers nor AWS operators can connect to the hostYou patch and secure the host OS
PatchingPlatform versions; keep services on the latest (ECS.10)AMI and agent updates are your responsibility

On the EC2 launch type, block metadata access from tasks: set ECS_AWSVPC_BLOCK_IMDS=true in the agent configuration for awsvpc tasks, add an iptables rule in the DOCKER-USER chain dropping traffic to 169.254.169.254 for bridge tasks, and keep the instance role minimal. Avoid host network mode (ECS.17), which bypasses both. See the Cloud Instance Metadata Services Compared Guide.

Choose Fargate where workloads of different trust levels or tenants share a cluster, or where the team cannot run a host patching programme. Choose EC2 where you need GPUs, privileged daemons or host-level agents, and then separate trust levels onto different capacity providers or clusters.

Logging and detection

  • CloudTrail control plane: alert on RegisterTaskDefinition introducing a new task role, RunTask outside pipelines, UpdateService enabling execute command, ExecuteCommand in production and IAM changes to task roles.
  • Task role use: CloudTrail events from task credentials carry the task ARN; alert when a task role is used from an IP outside your VPC NAT ranges, which suggests stolen credentials. GuardDuty's credential exfiltration findings cover EC2 instance credentials; for task roles, build your own detection on source IP and VPC endpoint.
  • ECS Exec sessions: ship session logs to a protected log group or bucket.
  • Container logs: every task definition should have a log configuration (ECS.9); Container Insights (ECS.12) adds metrics.
  • Runtime: GuardDuty Runtime Monitoring for Fargate attaches a managed sidecar agent at task launch, covering new tasks only. Clusters tagged GuardDutyManaged:false are excluded, so protect that tag with SCPs. See the Amazon GuardDuty Guide.

Metrics

  • Percentage of task definitions with a dedicated task role and no wildcard actions.
  • Number of principals with iam:PassRole on * and ECS run permissions (target: zero).
  • Number of task definitions with secrets in plaintext environment (ECS.8 failures).
  • Percentage of production services with ECS Exec disabled.
  • GuardDuty Runtime Monitoring coverage of running Fargate tasks.

Hardening baseline

  1. Inventory: list task definitions, their task and execution roles, policies attached, secrets referenced and whether execute command is enabled. Turn on Security Hub ECS controls to score them.
  2. Split and scope roles: create per-service task roles with confused deputy conditions, slim execution roles to named secret and key ARNs, and remove any task that uses the execution role as its task role.
  3. Fix PassRole: restrict PassRole to named roles with iam:PassedToService, and move production deployments to pipelines.
  4. Move secrets: replace plaintext environment values with secrets references, and use runtime retrieval for credentials that rotate. Test in a staging service, then roll forward with a new deployment; roll back by redeploying the previous task definition revision.
  5. Harden containers: non-root users (ECS.20), read-only root filesystem where ECS Exec is not needed (ECS.5), no privileged mode, no host network or PID namespace (ECS.3), no automatic public IPs (ECS.2).
  6. Lock down Exec: deny execute command in production by SCP or IAM, enable session logging in non-production, and deny direct ssm:StartSession on tasks.
  7. Monitor: Runtime Monitoring, CloudTrail alerts above and Container Insights.

Small teams with a handful of services usually get most of the benefit from steps 2 to 4 and from running everything on Fargate. Large organisations with many teams sharing clusters should enforce the same controls centrally: SCPs that deny execute command and privileged task definitions in production accounts, a pipeline that rejects task definitions failing Security Hub ECS controls, and a role-naming convention that makes task role ownership obvious in CloudTrail.

Common misconfigurations

  • One role for both jobs: the execution role doubles as the task role, so application code can read every secret the platform fetches for every service using it.
  • AdministratorAccess on a task role: added "temporarily" to unblock a deployment and never removed.
  • Secrets in plaintext environment: visible to anyone with ecs:DescribeTaskDefinition, and retained in every revision.
  • Rotation without redeploy: the secret is rotated, running tasks keep the old value, and either the app breaks or the old credential is never actually retired.
  • Instance metadata reachable from tasks on EC2: a server-side request forgery bug yields the container instance role.
  • ECS Exec open in production: anyone with the API permission gets a root shell next to production data.

Framework mapping

FrameworkReferenceECS control
NIST SP 800-53 Rev. 5AC-6Per-service task roles, scoped execution roles, PassRole limits
NIST SP 800-53 Rev. 5IA-5Secrets Manager references, rotation with redeploy
NIST SP 800-53 Rev. 5CM-6, CM-7Non-root, read-only root filesystem, no privileged or host mode
NIST SP 800-53 Rev. 5AU-2, SI-4CloudTrail, Exec session logs, Runtime Monitoring
NIST CSF 2.0PR.AA-05, PR.PS-01, DE.CM-09Least privilege, configuration management, monitoring
MITRE ATT&CKT1552.005, T1610, T1078.004Cloud instance metadata API, deploy container, cloud accounts

Practitioner checklist

  • Keep task roles and task execution roles separate for every task definition.
  • Add aws:SourceAccount and aws:SourceArn conditions to task role trust policies.
  • Restrict iam:PassRole to named roles with iam:PassedToService.
  • Scope execution role secret access to specific secret, parameter and key ARNs.
  • Remove secrets from plaintext environment variables and baked images.
  • Redeploy services after every secret rotation, or read secrets at runtime.
  • Block instance metadata from tasks on the EC2 launch type.
  • Disable ECS Exec in production and log it everywhere else.
  • Enable GuardDuty Runtime Monitoring and protect the GuardDutyManaged tag.
  • Track Security Hub ECS controls across all accounts.

Standards and references

Related NHI Mgmt Group resources: Container Security Guide · EKS Identity Hardening Guide · AWS STS and AssumeRole Guide · Container Runtime Security Guide · AWS Security Guide

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 27 October 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org