aws ecs ssm security claude-curated

ECS Exec gives you docker exec-style access into a running ECS task without SSH, bastion hosts, or open inbound ports. It is built on SSM Session Manager — the agent inside the task brokers the session through the SSM control plane, no inbound network path required.

Why it exists

Before ECS Exec, debugging a misbehaving task in production usually meant:

  • Adding an SSH daemon to the container (a bad idea).
  • Running a sidecar bastion + tailing audit logs.
  • Reproducing locally and hoping the bug repeats.
  • Reading logs and metrics until something gave.

ECS Exec replaces that with a managed equivalent: short-lived, audited shell access into a task, with no inbound network surface to attack.

How it works

operator --[StartSession]--> SSM control plane --[broker]--> SSM agent inside task
  • The ECS task definition includes the SSM agent (Fargate provides it; on EC2 the ECS-optimised AMIs bundle it).
  • When ECS Exec is enabled on the service, ECS injects the agent and configures it.
  • aws ecs execute-command starts an SSM session that connects to the agent.
  • The agent spawns the requested command (typically /bin/sh or /bin/bash) inside the container’s namespaces.

No SSH key, no inbound port, no public IP needed. The task’s outbound path to the SSM endpoints is the only network requirement.

Requirements

  • Service flag--enable-execute-command on the ECS service (or enableExecuteCommand: true in the task definition for standalone tasks).
  • Task role permissions — the task role needs ssmmessages:CreateControlChannel, ssmmessages:CreateDataChannel, ssmmessages:OpenControlChannel, ssmmessages:OpenDataChannel. Note this goes on the task role, not the execution role (see ECS Task Roles vs Execution Roles) — the SSM agent runs alongside the application and uses the task role’s credentials.
  • Operator permissionsecs:ExecuteCommand (resource-scoped to cluster/service/task), plus ssm:StartSession.
  • ECS agent / Fargate platform version — Fargate platform version 1.4.0 or later. EC2 launch type needs ECS agent ≥ 1.50.2.
  • Session Manager plugin installed locally for the AWS CLI.

Invocation

aws ecs execute-command \
  --cluster prod-cluster \
  --task TASK_ID \
  --container app \
  --interactive \
  --command "/bin/sh"

For non-interactive one-shot commands, omit --interactive and pass the command directly.

Use cases

  • Debugging in-production tasks — inspecting environment variables, file system state, network reachability from inside the task.
  • Post-incident forensics — capturing process state or in-memory caches before a task is replaced.
  • One-off database migrations — running a Rails / Django / Alembic migration from a task with the right config baked in, instead of pre-baking a separate migration image.
  • Verifying configuration — confirming the running container actually has the env vars / mounted secrets you expect.

Audit and tracking

ECS Exec is auditable end-to-end. The pieces:

  • CloudTrailExecuteCommand API events with requestParameters containing cluster/task/container and the operator identity (user or assumed role).
  • CloudTrail (SSM)StartSession events for the underlying SSM session. See CloudTrail Auditing.
  • Session content logging — configure on the cluster (executeCommandConfiguration) to send keystrokes and command output to:
  • Session Manager preferences — at the SSM-document level, additional logging of every command in the session.

A typical compliance setup:

  • KMS-encrypted S3 bucket for session transcripts, with object-lock retention.
  • CloudWatch metric filter on the CloudTrail log group for ExecuteCommand events; SNS alert to the security channel on every invocation in production.
  • Weekly review of session transcripts (or sampling, depending on volume).

This pattern replaces “SSH bastion + tail audit logs” with a managed equivalent that is harder to bypass — there is no SSH daemon for an attacker to reach, and the audit trail is enforced by AWS rather than by an in-host config.

Limitations and gotchas

  • Fargate platform version — versions before 1.4.0 do not support ECS Exec. Pin LATEST or set explicitly.
  • Existing tasks — enabling Exec on a service applies only to new tasks. To exec into a currently-running task, redeploy first.
  • Read-only root filesystem — if the task definition sets readonlyRootFilesystem, the SSM agent cannot write its working files. Either disable read-only or grant a writable scratch volume.
  • VPC endpoints in private subnets — tasks without internet (no NAT) need interface endpoints for com.amazonaws.REGION.ssmmessages and com.amazonaws.REGION.ssm. Without these, the agent cannot reach the SSM control plane and Exec hangs at session start.
  • Long-running sessions — sessions are killed when the task stops. Do not exec into a task and start a long process expecting it to outlive your shell.
  • Multiple containers in a task--container is required when more than one container is defined; otherwise the call fails with an ambiguous error.

Operational guardrails

  • Treat ECS Exec like sudo: scoped IAM, not granted by default to engineers. Apply least privilege.
  • Wrap with a “break-glass” workflow that pages on use in production.
  • Disable Exec on services where the runtime should be immutable (anything regulatory) by setting enableExecuteCommand: false and denying ecs:ExecuteCommand in the task’s resource policy.
  • Rotate the cluster’s session-log encryption key and review log access policies during audits.

See also

References