Getting a shell on an EC2 instance traditionally means an open port 22, a distributed SSH key, and often a bastion host as a chokepoint. Session Manager replaces all of that with a secure, auditable, WebSocket-based session brokered entirely through the SSM service - no inbound port, no key to rotate, no bastion to maintain.
StartSession is the SDK call that initiates a session against a managed instance. It is worth being precise about what this call actually returns: a session ID, a token, and a stream URL - not a live terminal.
That SessionId/TokenValue/StreamUrl trio is exactly what the Session Manager plugin needs to open the actual interactive channel. The SDK call establishes the session server-side; it does not hand your Python or Node.js process a shell.
In practice, the everyday path to an interactive terminal is the AWS CLI's aws ssm start-session command, which internally does the equivalent of the SDK call above and then hands the result to the locally installed Session Manager plugin, which speaks the WebSocket protocol and renders the terminal.
# --- Python (boto3) ---import subprocess# The CLI (with the Session Manager plugin installed) handles the# actual interactive terminal; the SDK call above is what it does internally.subprocess.run(["aws", "ssm", "start-session", "--target", "i-0abc123"])
// --- TypeScript (AWS SDK v3) ---import { execSync } from "node:child_process";// The CLI (with the Session Manager plugin installed) handles the// actual interactive terminal; the SDK call above is what it does internally.execSync("aws ssm start-session --target i-0abc123", { stdio: "inherit" });
Calling the CLI from your own code is a legitimate pattern for tooling that wraps start-session with your own instance-selection logic (for example, resolving an instance ID from a tag before invoking it). But if you find yourself parsing StreamUrl and hand-rolling the WebSocket protocol from the raw StartSession SDK response, stop - that protocol is exactly what the plugin already implements, and reimplementing it is not a supported or documented path.
The direct SDK StartSession call is most useful for two things: (1) programmatically confirming a session can be established (permissions, connectivity, managed-instance status) before handing off to the CLI/plugin, and (2) building tooling that needs to start a session and pass its details to something else that speaks the Session Manager protocol - a browser-based terminal, for instance, is how the AWS Console's own "Connect" button works.
For a human simply wanting a shell, always route through aws ssm start-session (or the Console's Session Manager tab), not a bespoke SDK integration.
StartSession accepts an optional DocumentName for session types beyond a plain shell - AWS-StartPortForwardingSession tunnels a local port to a port on the instance (handy for reaching a database or admin UI that only listens on localhost), and AWS-StartSSHSession tunnels actual SSH traffic through the Session Manager channel for tools that expect SSH specifically.
As with the plain shell case, the plugin (via aws ssm start-session --document-name AWS-StartPortForwardingSession ...) is what actually opens and maintains the tunnel; the SDK call sets it up.
Every session start, end, and (if configured) full command output is logged. Session Manager preferences let you route session logs to CloudWatch Logs and/or an S3 bucket, and every action is recorded in CloudTrail regardless - giving you a durable record of who connected to what, when, without depending on SSH auth.log scattered across every instance.
Expecting an interactive shell directly from the SDK response.StartSession returns connection details, not a terminal; the actual interactive session is established by the Session Manager plugin.
Reimplementing the WebSocket protocol. Parsing StreamUrl/TokenValue yourself to build a custom terminal client duplicates what the plugin already does and is not a documented integration path.
Forgetting the plugin is a separate install.aws ssm start-session fails with a clear error if the Session Manager plugin is not installed alongside the CLI - it is a separate download, not bundled.
Assuming Session Manager needs no IAM. Both the caller (to start a session) and the instance's role (AmazonSSMManagedInstanceCore) need the right permissions; missing either fails the connection.
Not enabling session logging. Without CloudWatch Logs or S3 logging configured in Session Manager preferences, you get session start/end audit events but not full command transcripts.
Leaving stale sessions open. Idle sessions do time out, but explicit cleanup via TerminateSession is useful for immediate revocation (for example, offboarding).
Traditional SSH with a bastion host still works and is well understood, but requires managing keys, an open port, and a bastion's own security posture that Session Manager eliminates entirely.
Run Command is better when the task is a single predetermined command across many instances rather than open-ended interactive exploration.
EC2 Instance Connect offers browser-based SSH for a single instance without a persistent key, but lacks Session Manager's centralized logging and its port-forwarding session type.
Session Manager is the right default for interactive access to managed instances in 2026: no inbound port, no key management, and a built-in audit trail that ad hoc SSH access does not provide.
A session ID, a token value, and a stream URL - the connection details the Session Manager plugin needs. It does not itself hand you an interactive terminal.
How do I get an actual interactive shell?
Run aws ssm start-session --target <instance-id> with the AWS CLI and the Session Manager plugin installed. That is the supported path to an interactive terminal.
Do I need to open port 22 for Session Manager?
No. Session Manager uses an outbound WebSocket connection from the SSM Agent; no inbound port needs to be open on the instance.
Can I forward a local port to a service on the instance?
Yes, using DocumentName: "AWS-StartPortForwardingSession" with StartSession, then connecting through the Session Manager plugin.
How do I end a session from code?
Call TerminateSession with the session ID. This is useful for administrative cleanup of sessions you did not personally start.
Is Session Manager activity logged?
Session start/end is always recorded in CloudTrail. Full command transcripts are optional and require enabling CloudWatch Logs or S3 logging in Session Manager preferences.
What does the target instance need?
It must be a managed instance: the SSM Agent running, plus an IAM instance profile that includes AmazonSSMManagedInstanceCore.
Can I use Session Manager for SSH-specific tooling?
Yes, DocumentName: "AWS-StartSSHSession" tunnels real SSH traffic through the Session Manager channel for tools that require an actual SSH connection.