JSTGTECH
← Back to blog

Service spotlight: SSH-less, bastion-less EC2 access with SSM

3 min read

I still see security groups with port 22 open to a bastion host’s IP range, a bastion host someone has to patch, and an SSH key rotation process nobody actually follows. Session Manager has been GA for years and solves this completely, and yet the bastion pattern persists mostly out of habit — worth a clear-eyed look at what actually changes when you switch.

What it actually is

Session Manager is a feature of AWS Systems Manager that opens an interactive shell session to an EC2 instance (or on-prem/other-cloud server running the SSM agent) entirely over the agent’s outbound HTTPS connection to the SSM service — no inbound port needs to be open on the instance at all, not even 22. Authentication and authorization happen through IAM: if your IAM identity has ssm:StartSession permission (typically scoped by resource tag) and the instance has SSM’s managed policy on its instance role, you get a shell. No SSH key to distribute, no bastion host to maintain, no security group rule to remember to remove later.

Every session is logged: session start/end, the identity that connected, and — if you enable it — the full session transcript to CloudWatch Logs or S3, plus KMS encryption of session data in transit. That’s a meaningfully better audit story than SSH access, where “who ran what command on this box” usually means reconstructing it from shell history files that a user can edit or delete.

Where it earns its keep

  • Removing SSH entirely from your security posture. No open port 22 means one less thing for a port scanner to find and one less credential (an SSH key) to leak, rotate, or worry about ending up in a public repo.
  • Instances with no public IP. A fully private-subnet EC2 instance with no NAT and no bastion is normally unreachable for interactive access; Session Manager works over a VPC endpoint (com.amazonaws.region.ssm plus the two related endpoints), so instances with zero internet egress are still reachable for administration.
  • Temporary, auditable access grants. Because access is IAM policy, not a distributed key, revoking someone’s shell access to production is an IAM policy change that takes effect immediately — no key rotation across a fleet, no bastion account cleanup.
  • Port forwarding without a bastion. aws ssm start-session --document-name AWS-StartPortForwardingSession tunnels a local port to a remote one (handy for reaching an RDS instance in a private subnet from a laptop) without opening the database to the internet or standing up a jump host at all.

What still trips people up

The SSM agent has to be installed, running, and able to reach the SSM service endpoints — most current AMIs (Amazon Linux 2023, recent Ubuntu/ Windows AMIs) ship with it preinstalled, but older custom AMIs and minimal/hardened base images often don’t, and “Session Manager isn’t working” on those turns out to be a missing or outdated agent, not an IAM problem. The instance also needs outbound HTTPS reachability to the SSM endpoints — either a NAT gateway/instance, or the three SSM-related VPC interface endpoints for fully private subnets — and forgetting the VPC endpoints on a private-subnet instance is the most common “it works in one VPC and not another” support ticket.

The other gap: Session Manager solves interactive shell access, but it’s not a substitute for scoped, least-privilege instance role permissions. Someone with ssm:StartSession on an instance whose instance role has broad S3 or IAM permissions still inherits that instance’s blast radius once they’re in the shell — Session Manager changes how you get access, it doesn’t change what that access can do once you’re there.

A practical tip

Turn on session logging to CloudWatch Logs and set a retention/alerting policy on it from day one — the audit trail is the single biggest advantage over SSH, and it’s only useful if someone’s actually watching or alarming on it, not just accumulating in a log group nobody queries until an incident forces the question.

Related posts