CLI tool
aws/amazon-ssm-agent avatar
aws/amazon-ssm-agent

Amazon SSM Agent: the Go process behind Run Command and Session Manager

An agent to enable remote management of your EC2 instances, on-premises servers, or virtual machines (VMs).

1,161 stars358 forksGoApache-2.0

At a glance

What is it?
The Amazon SSM Agent is the component that makes Systems Manager Run Command and Session Manager work on an instance, and it is open source in Go under Apache-2.0. It also brings an IAM surface, a sudo-capable ssm-user account and a vendored, locally patched copy of the AWS SDK, all of which belong in your review before you install it on a host.
Who is it for?
The Amazon SSM Agent is a good fit when you need Systems Manager Run Command or Session Manager on EC2 or on premises hybrid hosts and want the agent source, the packaging and the build reproducible. It is the wrong tool if you need a general purpose remote shell across heterogeneous fleets, since the feature set is tied to AWS documents and IAM, and it is a poor fit for a machine where you cannot accept a root-capable ssm-user account or the instance role.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 11 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the agent actually does on an instance

The Amazon EC2 Simple Systems Manager Agent is the software developed for the Simple Systems Manager Service, and the README states it is the primary component of a feature called Run Command. The mechanism is document driven. The agent runs on EC2 instances, and when you execute a command, the agent on the instance processes the SSM document and configures the instance as specified. The documents are the AWS-defined contracts, and the README notes that currently the agent and Run Command let you run Shell scripts on an instance using the AWS-RunShellScript document.

The second capability is Session Manager, which the README says lets you manage an EC2 instance through an interactive one-click browser-based shell or through the AWS CLI. The agent is the transport for that session, not just a helper for it.

One behaviour here deserves attention before you install anything. The README states that the first time a Session Manager session is started on an instance, the agent will create a user called ssm-user with sudo or administrator privilege, and that Session Manager sessions are launched in context of this user. So a session you might think of as a low privilege operator session is actually rooted on the machine, and the agent creates the account for you on first use. Whether that matches your expectations depends on your fleet's access model, and the README's setup section points at dedicated pages for configuring IAM roles and users for both Run Command and Session Manager.

The platform floor is stated plainly: Linux systems require kernel version 3.2 or above. The setup section links to the Run Command prerequisites and to the Session Manager prerequisites and supported operating systems pages, so the supported matrix is maintained on the AWS side rather than in this repository. For Windows, the README states that Session Manager is only supported on Windows Server 2008 R2 through Windows Server 2019 64-bit versions, and that the agent must be built with winpty binaries present for the Session Manager shell on Windows.

Building in the Docker image the project recommends

The README labels the container build as recommended, and it is a two step process. First you build the image from the repository's Dockerfile:

bash
docker build -t ssm-agent-build-image .

Then you run the build inside it, mounting the working directory so the artifacts land back on your host:

bash
docker run -it --rm --name ssm-agent-build-container -v `pwd`:/amazon-ssm-agent ssm-agent-build-image make build-release

The Dockerfile is deliberately thin. It starts from public.ecr.aws/docker/library/golang:1.24, installs the packaging tools the Makefile needs with apt, and creates the /amazon-ssm-agent working directory:

dockerfile
FROM public.ecr.aws/docker/library/golang:1.24

RUN apt -y update && apt -y upgrade && apt -y install rpm tar gzip wget zip && apt clean all

RUN mkdir /amazon-ssm-agent
WORKDIR /amazon-ssm-agent

The presence of rpm and zip in that apt line is a good clue about the output. This is a project that ships operating system packages, not just a binary.

There is one wrinkle here that will confuse you if you hit it without warning. The go.mod file declares go 1.26, while the Dockerfile pins golang:1.24. Those two statements are not compatible, and if the build fails on a language version directive, that mismatch is the first thing to look at.

If you would rather build on Linux directly, the README's alternative path is to install Go, install rpm-build and rpmdevtools, and run make build for Linux, Debian and Windows targets, or make build-release to also produce packages. The generated folders are:

code
bin/debian_386
bin/debian_amd64
bin/linux_386
bin/linux_amd64
bin/linux_arm
bin/linux_arm64
bin/windows_386
bin/windows_amd64

The make build target is described as the default, and it covers Linux, Debian, Darwin and Windows in amd64 and 386, while the folder list shows arm and arm64 outputs as well.

The Make targets split build, check and static analysis

The Makefile exposes a small set of targets, and reading them tells you what the project considers a release gate. The default target is build, which builds the agent for Linux, Debian, Darwin and Windows in amd64 and 386. build-release checks code style and coverage, builds the agent and packages it into RPM, DEB and ZIP. The release target is the strictest: it checks code style and coverage, runs tests and packages all dependencies into the bin folder. package alone packages the build result into RPM, DEB and ZIP.

So the difference between build and build-release is that build-release gates on style and coverage, and release additionally runs the test suite. That is a sensible ladder for a project that produces installable packages.

Two targets are about static analysis rather than compilation. analyze-install installs the static analysis dependencies for local use, and analyze runs the static analysis script to find possible vulnerabilities. The vulnerability scan is a separate target rather than part of the build, which means it is not automatically applied to every commit unless CI wires it that way.

Other targets handle housekeeping. pre-build goes through the Tools/src folder to make sure all the script files are executable, and checkstyle runs the checkstyle script. That pre-build step is a small but telling detail: the packaging scripts live in the repository and are expected to carry their executable bit.

For linting there is a separate tool. The lint-all target executes golangci-lint on all packages in the module, and the configuration lives in the .golangci.yml file at the top level of the repository. The README links to the golangci-lint installation and configuration pages, and the presence of .golangci.yml at the root means the lint rules are in version control rather than being whatever a developer's machine had installed.

One more note for anyone working with the vendored dependencies. The GOPATH section says that to use vendor dependencies, the suggested GOPATH format is :<packagesource>/vendor:<packagesource>. That is a workspace style layout, and it reflects a project that has carried a vendor directory for a long time.

The AWS SDK is vendored and locally replaced, and that changes the upgrade path

The go.mod file is the most consequential file in this repository for anyone auditing the supply chain, because it does something unusual. Three modules are redirected to local paths inside the repository with replace directives:

code
replace github.com/aws/aws-sdk-go-v2 => ./extra/aws-sdk-go-v2

replace github.com/aws/aws-sdk-go-v2/service/ssm => ./extra/aws-sdk-go-v2/service/ssm

replace github.com/nightlyone/lockfile => ./extra/lockfile

The AWS SDK v2 and its SSM service package are not taken from the module proxy as published. They come from copies under extra/ in this tree. That means the version constraint in the require block, github.com/aws/aws-sdk-go-v2 v1.41.5, is not necessarily the code you are compiling. Somebody is shipping a patched SDK inside the agent, and the reason is not written in the go.mod file.

Two other entries in the require list carry explicit warnings. github.com/hectane/go-acl is marked with the comment Don't update -- breaks, and github.com/nightlyone/lockfile, which is the module used for the single instance lock that prevents two agents running on one host, is also replaced by a local copy. Both are signs of code that depends on specific dependency behaviour.

A third dependency has a comment attached to it, and it explains a build setting. The go.mod contains:

code
godebug containermaxprocs=0 // disable consideration of cgroup limits

That is a Go runtime debug directive that disables the container-aware GOMAXPROCS behaviour, so the agent does not size its thread pool from cgroup limits. It is a small decision with a visible consequence: on a host with CPU limits applied through cgroups, the agent will size itself from the machine rather than from its allocation.

For maintainers, the lock discipline works differently here than in a project with a generated lock file. The Go project uses go.sum for the module graph, but the local SDK copies under extra/ are not covered by that mechanism, since they are source in this repository. That makes the replace directives the operative mechanism. The practical rule is the same either way: an upgrade of the vendored SDK is a code change to this repository, and it deserves the same review as any other patch.

Code layout, packaging and the parts of the agent you will not touch

The README describes the code layout in four lines, and it is worth memorising if you ever need to trace a behaviour. Core functionality such as worker management is under core/. Agent worker code is under agent/. Other functionality such as IPC is under common/. Vendor package source code is under vendor/src, rpm and dpkg artifacts are under packaging, and build scripts are under Tools/src.

The top level listing shows the rest: agent/, common/, core/, extra/, internal/, src/, Tools/, packaging/, vendor/, plus the .golangci.yml, .travis.yml, CODE_OF_CONDUCT.md, CONTRIBUTING.md, LICENSE, NOTICE.md, RELEASENOTES.md, VERSION, amazon-ssm-agent.json.template, amazon-ssm-agent.spec, seelog_unix.xml, seelog_windows.xml.template, go.mod and go.sum. The .template and .spec suffixes show how the agent handles platform differences: the configuration and packaging definitions are templates that get filled in at build time for the target platform.

The seelog files are the logging configuration for the agent itself, split by platform, with a template for Windows. The agent's own logs are a separate thing from the Run Command output it collects, and they are where you look when the agent itself misbehaves rather than the command it ran.

For Windows Session Manager, the build needs extra binaries. The README asks you to clone the winpty repository, follow its build instructions for 64-bit binaries, and copy winpty.dll and winpty-agent.exe into the bin/SessionManagerShell folder. That is a manual step outside the Makefile, and it is the kind of thing that breaks on a fresh Windows build machine.

The Windows support statement is dated in a way that matters. The README says Session Manager is only supported on Windows Server 2008 R2 through Windows Server 2019 64-bit versions, which excludes Windows Server 2022 and any Windows client SKU from the stated range. If your fleet includes newer Windows servers, verify the supported matrix on the AWS Session Manager prerequisites page before you rely on this.

Maintenance signals and the deprecation already in the tree

The project is clearly alive. The repository is not archived, the last push was on 2026-10-12, and the release tags are frequent: 3.3.5538.0 on 2026-10-12, 3.3.5512.0 on 2026-10-08 and 3.3.5390.0 on 2026-09-17. The version scheme with four components is a packaging convention rather than semver, and the release title strings follow the pattern Amazon SSM Agent - Release <version> - <date>. The repository carries a VERSION file and a RELEASENOTES.md, which is where you should look before pinning a version.

The licence is Apache-2.0, and the repository also carries a NOTICE.md file, which is the required companion for redistribution of an Apache-licensed product. For a self-hosted hybrid fleet where you ship the agent to on premises servers, the practical note is that you must carry the NOTICE and licence text with the binary, and the packaging directory holds the rpm and dpkg artifacts that carry them.

There is one deprecation already recorded in the README, and it is a signal about the direction of travel. The CloudWatch plugin for Windows is deprecated and no longer supported, and the README says to migrate to the Amazon CloudWatch Agent. So the agent's plugin surface is not static, and the Windows CloudWatch plugin is being retired in favour of a separate agent. Expect the same pattern for anything else bolted onto the SSM agent, and check RELEASENOTES.md rather than assuming a feature you rely on is permanent.

For a component that runs with root-equivalent privilege on every managed host, the practical upgrade cost is the recurring one, not the initial build. The release cadence is roughly weekly by the dates above, which means a fleet operator has to decide on a patch and rollout policy, and that decision is about your fleet's exposure window rather than about compiling the Go code.

Editorial conclusion

The Amazon SSM Agent is a good fit when you need Systems Manager Run Command or Session Manager on EC2 or on premises hybrid hosts and want the agent source, the packaging and the build reproducible. It is the wrong tool if you need a general purpose remote shell across heterogeneous fleets, since the feature set is tied to AWS documents and IAM, and it is a poor fit for a machine where you cannot accept a root-capable ssm-user account or the instance role. Before adopting, read the IAM configuration pages in the setup list, confirm the ssm-user creation and privilege level matches your policy, and check the RELEASENOTES.md file for what changed in the release you plan to pin.

Frequently asked questions

What does the Amazon SSM Agent do on an EC2 instance?

It is the primary component of Systems Manager Run Command. When you execute a command, the agent on the instance processes the SSM document and configures the instance as specified, and it also enables Session Manager for interactive browser-based or CLI shells.

Does the SSM Agent create a user on the instance?

Yes. The README states that the first time a Session Manager session is started on an instance, the agent creates a user called ssm-user with sudo or administrator privilege, and sessions are launched in the context of that user.

How do I build the SSM Agent?

The recommended path is Docker: build the image with docker build -t ssm-agent-build-image . and then run make build-release inside it with the working directory mounted. On Linux directly you need Go plus rpm-build and rpmdevtools, and make build produces the agent binaries while make build-release also packages RPM, DEB and ZIP.

Why does the SSM Agent vendor its own copy of the AWS SDK?

The go.mod file redirects github.com/aws/aws-sdk-go-v2 and its service/ssm package to local paths under extra/ with replace directives, so the compiled agent does not use the SDK as published. The go.mod file does not give a reason for those local copies.

Official sources

  1. aws/amazon-ssm-agent on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/aws-amazon-ssm-agent.svg)](https://hysenlabs.com/projects/aws-amazon-ssm-agent)

Was this useful?