Back to Blog

Secure Administrative Access to EC2 for the AWS Security Specialty Exam (SCS-C03): Session Manager vs EC2 Instance Connect vs EC2 Instance Connect Endpoint vs Bastion Hosts, IAM Condition Keys, Session Logging, Port Forwarding & the EC2 Serial Console

A practitioner's guide to Skill 3.2.5 of the AWS Certified Security - Specialty exam: how Systems Manager Session Manager works without inbound ports (agent, ssmmessages, session documents, ssm-user, Run As, KMS session encryption, idle and maximum timeouts, S3/CloudWatch logging and the SSH/port-forwarding logging gap), how EC2 Instance Connect pushes a 60-second key through instance metadata and what ec2:osuser and the managed prefix list control, how EC2 Instance Connect Endpoint acts as an identity-aware TCP proxy with remotePort/privateIpAddress/maxTunnelDuration conditions and client IP preservation, when a bastion host is still the right answer, where the EC2 Serial Console fits, plus a decision table, scenario drills, common mistakes and an FAQ.

By Sailor Team , October 27, 2026

Every Security Specialty candidate knows the slogan: close port 22 and delete the bastion. The exam, however, is not satisfied with the slogan. It wants you to know which of AWS’s four administrative-access paths closes the port, which one still needs an SSH key, which one records every keystroke, which one silently records nothing, and which IAM condition key makes each path least-privilege. Those details are exactly what the current exam guide asks for. Skill 3.2.5 of the AWS Certified Security - Specialty (SCS-C03) guide reads, verbatim: “Configure secure administrative access to compute resources (for example, Systems Manager Session Manager, EC2 Instance Connect).” Amazon EC2 is listed in scope “including EC2 Image Builder, EC2 Instance Connect”, and AWS Systems Manager is in scope under Management and Governance.

A quick note on exam versions, because it affects how you should read older material: AWS retired SCS-C02 in December 2025 and the live exam is SCS-C03. The compute-hardening content carried over almost unchanged (the SCS-C02 guide phrased the same idea as “secure remote access methods, for example SSH and RDP over Systems Manager Session Manager”), so everything in this article applies to both blueprints. If you are still orienting yourself, the SCS-C02 vs SCS-C03 comparison and the full Security Specialty exam guide cover the domain-level changes.

This article is the deep dive the infrastructure security domain guide deliberately skips. It assumes you already know what a security group is and focuses on the mechanics the exam actually tests: how each access path authenticates, what network state it needs, what it logs, which condition keys scope it, and the traps AWS likes to hide in a scenario.

The threat model behind “no inbound port 22”

Start with why the exam cares. A classic administrative path to a Linux instance is an SSH daemon listening on port 22, reachable through a security group rule, authenticated by a long-lived key pair that lives on laptops and in CI systems. Every element of that sentence is an attack surface:

  • The open port is reachable by anyone who can route to it. Even when the source is restricted to a corporate CIDR, the daemon itself is exposed to protocol-level vulnerabilities and brute-force noise.
  • The long-lived key is a shared secret. It is copied, forgotten, and rarely rotated. When an engineer leaves, nobody is sure which instances still trust their key.
  • The bastion host that fronts private instances is a server you have to patch, harden, monitor and scale. It also concentrates risk: compromise the bastion and you have a foothold in every subnet it can reach.
  • The audit trail is whatever the instance’s own logging captures. If the attacker has root, they can edit it.

The four AWS mechanisms below each remove some of those elements. The exam tests whether you know which elements each one removes, because the right answer depends on which element the scenario complains about.

The four access paths at a glance

Access pathInbound security-group rule needed?Public IP needed?SSH key pair needed?What authenticates youSession content logged by AWS?Protocol seen by the instance
Session ManagerNo (agent connects outbound on 443)NoNoIAM identity, checked by the Session Manager serviceYes for standard shell sessions (S3, CloudWatch Logs, CloudTrail for API calls); no for SSH and port-forwarding sessionsAgent-mediated shell, not SSH
EC2 Instance Connect (public path)Yes, port 22 from your IP or the AWS-managed EIC prefix listYes (or private connectivity you built yourself)No persistent key; a one-time key is pushed for 60 secondsIAM authorizes the key push (ec2-instance-connect:SendSSHPublicKey), then normal SSHAPI call in CloudTrail only; session content not recordedSSH
EC2 Instance Connect EndpointYes, but only from the endpoint’s security group or VPC rangeNoOptional: your own key with any AMI, or the EIC one-time key pushIAM authorizes the tunnel (ec2-instance-connect:OpenTunnel), then SSH or RDPOpenTunnel calls (success and failure) in CloudTrail; session content not recordedSSH or RDP over a TCP tunnel
Bastion hostYes, on the bastion (22) and on targets (22 from the bastion’s security group)Yes, on the bastionYesWhatever you configure on the bastionWhatever you configure on the bastionSSH hop

A fifth tool, the EC2 Serial Console, is not an administrative-access path at all. It is an out-of-band break-glass console that bypasses the VPC, and it has its own section below because the exam uses it as a distractor.

Session Manager internals

How a session actually flows

AWS Systems Manager Session Manager gives you an interactive shell or a tunnel to a managed node through the SSM Agent’s outbound connection. The sequence the exam expects you to be able to narrate:

  1. The user calls ssm:StartSession from the console, the EC2 console, or the AWS CLI with the Session Manager plugin installed.
  2. The service authenticates the IAM identity, evaluates the IAM policy, checks the session preferences (timeouts, logging, encryption, Run As) and sends a message to the SSM Agent on the node.
  3. The agent, which already maintains an outbound HTTPS connection, opens a bidirectional data channel to the ssmmessages endpoint. Traffic between client and node is TLS-encrypted and the create-connection request is SigV4-signed.
  4. Commands and output stream over that channel. Nothing listens on the instance, so no inbound rule is required and the instance does not need a public IP.

The prerequisites that fall out of this design are the ones scenarios probe:

  • SSM Agent version 2.3.68.0 or later for basic sessions; 2.3.539.0 or later for KMS session encryption; 3.0.222.0 or later for port forwarding and SSH sessions; 3.0.284.0 or later for streaming logs to CloudWatch Logs; 3.1.1374.0 or later for port forwarding to a remote host.
  • Outbound HTTPS (443) from the node to ssm.<region>.amazonaws.com, ssmmessages.<region>.amazonaws.com and ec2messages.<region>.amazonaws.com. For instances with no internet route, create interface VPC endpoints for those three services. “Private subnet, no NAT, must use Session Manager” is answered by interface endpoints, not by an internet gateway.
  • Instance permissions. Either an instance profile carrying AmazonSSMManagedInstanceCore (plus S3, CloudWatch Logs and KMS permissions if you enable those features), or the account-level Default Host Management Configuration, which lets Systems Manager manage every EC2 instance in a Region through the AWSSystemsManagerDefaultEC2InstanceManagementRole without an instance profile. Default Host Management Configuration requires IMDSv2 and SSM Agent 3.2.582.0 or later, and it is activated per Region. The IMDSv2 dependency is a nice bridge to the IMDSv2 deep dive: the agent reads its role credentials from instance metadata, so disabling IMDS breaks Session Manager.

The ssm-user account and Run As

Starting with SSM Agent 2.3.50.0, the agent creates a local account called ssm-user and gives it root or administrator rights: it is added to /etc/sudoers.d/ssm-agent-users on Linux and macOS (ssm-user ALL=(ALL) NOPASSWD:ALL) and to the Administrators group on Windows. On agent 2.3.612.0 and later, the account is created the first time a session starts on the node. By default, every session runs as this account.

The exam tests two ways to change that:

  • Remove sudo from ssm-user. Overwrite the sudoers file (Run Command with AWS-RunShellScript is the documented way: echo "#User rules for ssm-user" > /etc/sudoers.d/ssm-agent-users). Sessions still work, but the operator is no longer root.
  • Turn on Run As support (Linux and macOS only). Session Manager then authenticates sessions as a named OS user instead of ssm-user. The lookup order is: first the SSMSessionRunAs tag on the IAM user or role, then the OS user name in the account’s Session Manager preferences. If the OS account does not exist on the node, the session fails. Run As does not fall back to ssm-user, and it does not support the root account. The recommended pattern is tagging IAM entities so different teams land in different OS users, which also makes OS-level audit logs attributable.

Session preferences the exam quotes numbers from

PreferenceDefaultRange or behaviourWhy it matters on the exam
Idle session timeout20 minutes1 to 60 minutes. Keyboard input, window resizes and reconnects reset the timer”Sessions left open overnight” questions. Note that activity, not just commands, resets the timer
Maximum session durationNone1 to 1,440 minutes (24 hours)“Hard limit regardless of activity” questions. Pair it with idle timeout
KMS encryption of session dataOffSymmetric KMS key; adds a layer on top of TLS. The user needs kms:GenerateDataKey; the node needs kms:Decrypt. Supported for Standard_Stream, InteractiveCommands and NonInteractiveCommands session typesMissing either permission makes sessions fail to start. Also required to reset passwords through Fleet Manager
Run AsOffSSMSessionRunAs tag, then account-level user name; Linux/macOS only; no root; no fallbackAttributable OS identity and least privilege
Shell profilesNoneCommands, environment variables and working directory run at session startEnforce a restricted shell, umask, or banner
S3 loggingOffPer-session log to a bucket, optionally KMS-encrypted; the node needs s3:PutObject and KMS rightsArchival of what operators typed and saw
CloudWatch Logs loggingOffContinuous streaming (agent 3.0.284.0 or later) or upload at session endNear-real-time detection on operator commands

Two logging details are heavily tested. First, logging is not available for sessions that use SSH or port forwarding, because Session Manager is only a tunnel for that traffic; the content is encrypted end to end inside the tunnel. A question that says “the security team needs a transcript of everything the operator ran” is answered by a standard shell session with S3 or CloudWatch logging, and is wrong for the SSH-over-Session-Manager pattern. Second, session logs capture both input and output, so AWS documents stty -echo; read passwd; stty echo; to keep secrets out of the transcript, and recommends the screen utility be installed on Linux nodes to avoid truncated logs. CloudTrail separately records the StartSession, ResumeSession and TerminateSession API calls, and EventBridge can fire on session start and end for SNS notifications or automated responses.

Session types and documents

Every session runs a Session document. The account-level preferences live in a document called SSM-SessionManagerRunShell (session type Standard_Stream), which is why user policies reference that document ARN. The other AWS-provided documents define the non-shell session types:

# Interactive shell (uses SSM-SessionManagerRunShell preferences)
aws ssm start-session --target i-0abc123def456

# Local port 56789 -> port 80 on the instance
aws ssm start-session --target i-0abc123def456 \
  --document-name AWS-StartPortForwardingSession \
  --parameters '{"portNumber":["80"],"localPortNumber":["56789"]}'

# Tunnel through the instance to a remote host that is NOT an SSM node (RDS, AD, etc.)
aws ssm start-session --target i-0abc123def456 \
  --document-name AWS-StartPortForwardingSessionToRemoteHost \
  --parameters '{"host":["mydb.cluster-xyz.us-east-1.rds.amazonaws.com"],"portNumber":["3306"],"localPortNumber":["3306"]}'

The remote-host variant is the exam’s answer to “developers need to reach a private RDS instance from laptops without a bastion or VPN”. The EC2 instance acts as the tunnel endpoint, and the remote host needs no agent at all.

SSH over Session Manager uses the AWS-StartSSHSession document through an SSH ProxyCommand:

# ~/.ssh/config
Host i-* mi-*
    ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
    User ec2-user

Three facts about this pattern are exam gold: you still need a key pair that the instance trusts (you connect as the key’s OS user, not as ssm-user), the instance’s port 22 stays closed in the security group because the tunnel terminates inside the agent, and no session logging happens. It gives you SCP file copies and native SSH tooling at the cost of the transcript.

Finally, InteractiveCommands and NonInteractiveCommands session types let you write a custom Session document that runs a single command (for example, tailing a specific log file). This is how you grant an operator “run exactly this and nothing else” access.

Least-privilege IAM for Session Manager

The user-side policy has four moving parts. AWS’s quickstart end-user policy is the template:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "ssm:StartSession",
      "Resource": [
        "arn:aws:ec2:us-east-1:111122223333:instance/*",
        "arn:aws:ssm:us-east-1:111122223333:document/SSM-SessionManagerRunShell"
      ],
      "Condition": {
        "StringLike": { "ssm:resourceTag/Environment": ["prod-web"] }
      }
    },
    {
      "Effect": "Allow",
      "Action": "ssmmessages:OpenDataChannel",
      "Resource": "arn:aws:ssm:*:*:session/${aws:userid}-*"
    },
    {
      "Effect": "Allow",
      "Action": ["ssm:TerminateSession", "ssm:ResumeSession"],
      "Resource": "arn:aws:ssm:*:*:session/${aws:userid}-*"
    },
    {
      "Effect": "Allow",
      "Action": ["ssm:DescribeSessions", "ssm:GetConnectionStatus", "ssm:DescribeInstanceProperties", "ec2:DescribeInstances"],
      "Resource": "*"
    }
  ]
}

Read it the way the exam reads it:

  • ssm:StartSession on instance ARNs with ssm:resourceTag/<key> scopes which nodes a user may reach. Multiple tag conditions are ANDed, so “both tags must be present” is natural.
  • ssm:StartSession on the document ARN scopes which session type. Granting SSM-SessionManagerRunShell but not AWS-StartPortForwardingSession or AWS-StartSSHSession forbids tunnels and SSH. An explicit Deny on arn:aws:ssm:*:*:document/AWS-StartSSHSession is the documented way to block SSH-over-Session-Manager for a group. Because the CLI can also start a session with no document argument, AWS provides the ssm:SessionDocumentAccessCheck condition key; setting it to true on ssm:StartSession forces the document permission check even when the caller omits --document-name.
  • Session ARNs built from ${aws:userid}-* let a user resume or end only their own sessions. For federated identities, AWS also stamps every session with the system tags aws:ssmmessages:session-id and aws:ssmmessages:target-id, which you can match in a ssm:resourceTag condition on ssm:TerminateSession.
  • ssm:SendCommand sneaks into the EC2-console variant of the policy only because the console may need to update an old agent through Run Command first.

The administrator-side policy adds ssm:CreateDocument, ssm:UpdateDocument and ssm:GetDocument on SSM-SessionManagerRunShell, because editing preferences is editing that document. Locking preferences down means denying those actions to everyone except the security team. The same principle covers Default Host Management Configuration: AWS publishes an SCP that denies ssm:UpdateServiceSetting, ssm:ResetServiceSetting and iam:PassRole on the default role to anyone without an administrator principal tag.

For a broader treatment of the operational side of Systems Manager (Run Command, Patch Manager, Fleet Manager), the Systems Manager operations guide covers what this article skips.

EC2 Instance Connect: IAM-authorized SSH, 60 seconds at a time

EC2 Instance Connect (EIC) keeps SSH as the protocol but replaces the long-lived key with a one-time key authorized by IAM. The mechanism:

  1. The user calls ec2-instance-connect:SendSSHPublicKey with a freshly generated public key, an instance ID and an OS user name. The console does this for you and generates the key pair in the browser; with the CLI you can run aws ec2-instance-connect ssh --instance-id i-..., or push the key yourself and use any SSH client.
  2. The service writes the public key into the instance’s metadata, where it remains for 60 seconds.
  3. On the instance, the EIC package has configured sshd with AuthorizedKeysCommand /opt/aws/bin/eic_run_authorized_keys %u %f and AuthorizedKeysCommandUser ec2-instance-connect. When the SSH connection arrives, sshd runs that command, which fetches the key from metadata and authenticates the session.
  4. Every SendSSHPublicKey call is recorded in CloudTrail, so you can audit who connected to which instance as which user, even though SSH itself is not a logged session.

What the exam wants you to notice:

  • The security group still needs port 22 open. For CLI or SSH-client use, the source is your IP range. For the browser-based client, the connection originates from the EC2 Instance Connect service, so the inbound rule must allow the AWS-managed prefix list com.amazonaws.<region>.ec2-instance-connect (and the ipv6 variant for IPv6). A scenario where “the console says connection failed but SSH from a laptop works” is a missing prefix-list rule.
  • The instance needs a public IPv4 or IPv6 address and an internet route, unless you have built private connectivity (VPN, Direct Connect, peering) or you use EC2 Instance Connect Endpoint.
  • The package must be installed. It is preinstalled on AL2023 standard AMIs, Amazon Linux 2 (2.0.20190618 or later), Ubuntu 20.04 or later, and recent macOS images; it can be installed on CentOS Stream 8/9, RHEL 8/9, older Ubuntu, and the AL2023 minimal and ECS-optimized AMIs. If sshd already has a custom AuthorizedKeysCommand, the installer leaves it alone and EIC does not work.
  • It is Linux and macOS only. Windows instances use RDP, which EIC does not do (but EC2 Instance Connect Endpoint does).
  • IAM scoping uses ec2:osuser to pin the OS user (for example ec2-user or ubuntu), instance ARNs or aws:ResourceTag conditions to pin instances, and ec2:DescribeInstances for console use (ec2:DescribeVpcs too when connecting over IPv6). Without a resource restriction, anyone with SendSSHPublicKey can reach every instance in the account.
  • No additional cost, available in all commercial Regions, not supported in Local Zones.

EIC fixes the key-management problem and nothing else: the port is still open, the daemon is still exposed, and the session content is not recorded. It is also the AWS-recommended way to harden a bastion if you must keep one, because the bastion no longer holds any static keys.

EC2 Instance Connect Endpoint: the managed bastion

EC2 Instance Connect Endpoint (EICE) is what AWS built so you can reach private instances over SSH or RDP without a public IP, without an internet gateway and without a bastion. The docs describe it as an identity-aware TCP proxy: the EC2 Instance Connect Endpoint Service establishes a private tunnel from your computer to the endpoint using your IAM credentials, authenticates and authorizes the request, and only then forwards TCP into your VPC.

Mechanically:

  • You create one endpoint in a subnet. AWS provisions a network interface there (through a service-linked role) which becomes the entry point. Any instance in any subnet whose route table allows traffic from the endpoint’s subnet is reachable.
  • The client runs aws ec2-instance-connect ssh --instance-id i-... (which combines the tunnel with an EIC key push), or aws ec2-instance-connect open-tunnel --instance-id i-... --remote-port 22 --local-port 2222 and points any SSH or RDP client at the local port. If you bring your own key pair, any Linux AMI works; otherwise the instance needs the EIC package for the one-time key.
  • Windows instances are reachable on 3389 the same way, which is the clean answer to “RDP to a private Windows instance without a bastion”.

The IAM model is the richest of the four paths and the exam knows it:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "TunnelOnlyToSSHInAppSubnet",
      "Effect": "Allow",
      "Action": "ec2-instance-connect:OpenTunnel",
      "Resource": "arn:aws:ec2:us-east-1:111122223333:instance-connect-endpoint/eice-0123456789abcdef0",
      "Condition": {
        "NumericEquals": { "ec2-instance-connect:remotePort": "22" },
        "NumericLessThanEquals": { "ec2-instance-connect:maxTunnelDuration": "1800" },
        "IpAddress": {
          "ec2-instance-connect:privateIpAddress": "10.0.1.0/24",
          "aws:SourceIp": "203.0.113.0/24"
        }
      }
    },
    {
      "Sid": "OneTimeKey",
      "Effect": "Allow",
      "Action": "ec2-instance-connect:SendSSHPublicKey",
      "Resource": "arn:aws:ec2:us-east-1:111122223333:instance/*",
      "Condition": { "StringEquals": { "ec2:osuser": "ec2-user" } }
    },
    {
      "Sid": "Describe",
      "Effect": "Allow",
      "Action": ["ec2:DescribeInstances", "ec2:DescribeInstanceConnectEndpoints"],
      "Resource": "*"
    }
  ]
}

The three endpoint-specific condition keys:

  • ec2-instance-connect:remotePort restricts the destination port. Allow 22 for Linux fleets, 3389 for Windows fleets, nothing else.
  • ec2-instance-connect:privateIpAddress restricts the destination to a single IP or a CIDR, which is how you keep a team inside its own subnet.
  • ec2-instance-connect:maxTunnelDuration caps the tunnel at 1 to 3,600 seconds (the default and maximum is one hour). If the policy sets a value below 3,600, the caller must pass --max-tunnel-duration on the command line. Note the trap: the tunnel’s lifetime is independent of the caller’s credentials. Expired IAM credentials do not cut the tunnel; only the duration does.

Creation permissions are separate (ec2:CreateInstanceConnectEndpoint, ec2:CreateNetworkInterface, ec2:CreateTags, ec2:ModifyInstanceConnectEndpoint, iam:CreateServiceLinkedRole) and can be scoped by ec2:SubnetID, so a platform team can own endpoints while application teams only get OpenTunnel.

Security groups and client IP preservation

The endpoint has its own security group. Inbound rules on it are irrelevant (traffic arrives from the EICE service regardless), so who may connect is purely an IAM question. What matters is:

  • The endpoint’s security group must allow outbound to the targets: reference the instance security group, or allow the VPC CIDR on port 22/3389.
  • The instance’s security group must allow inbound from the endpoint: referencing the endpoint’s security group works whether client IP preservation is on or off, and is the recommended pattern because it means “only the endpoint can SSH here”.
  • Client IP preservation decides what source address the instance sees. Off (the default), the source is the endpoint network interface’s private IP, so an IP-based inbound rule must allow the VPC range. On, the source is the client’s real public IP, so the inbound rule must allow the client range; the instance must be in the same VPC as the endpoint; it works only on IPv4 endpoints (not dual-stack or IPv6); it fails on a short list of legacy instance types (C1, CG1, CG2, G1, HI1, M1, M2, M3, T1); and it is not supported through a transit gateway. The exam uses this as a troubleshooting question: “connections fail only after enabling client IP preservation” points at one of those constraints or at an inbound rule that still allows only the VPC CIDR.

Quotas and limits that show up in questions

LimitValue
Endpoints per VPC and per subnet1 (delete and recreate to move it to another AZ)
Concurrent connections per endpoint20
Maximum tunnel duration3,600 seconds, lower by IAM condition
Traffic profileManagement traffic only; high-volume transfers are throttled
Address familiesIPv4, IPv6 or dual-stack; the endpoint’s type must match the instance’s address
PricingNo charge for the endpoint; standard cross-AZ data transfer applies when the target is in another AZ
LoggingOpenTunnel success and failure in CloudTrail; no session content

Compare the two Instance Connect siblings carefully: EIC (public) authorizes a key; EICE authorizes a TCP tunnel. EIC needs a public address and an open port from your IP; EICE needs neither. Both leave SSH as the protocol and neither records what you typed. When a scenario needs a transcript, both lose to Session Manager.

When a bastion host is still the answer

The exam rarely rewards building a bastion, but it does test whether you know how to run one correctly when a constraint forces it (a third-party appliance that cannot run SSM Agent, a compliance rule mandating a jump host, or tooling that depends on raw SSH with agent forwarding). The hardening checklist AWS expects:

  • Place the bastion in a public subnet with its own security group allowing 22 only from the corporate range, and make every private instance’s security group allow 22 only from the bastion’s security group (security-group referencing, never the subnet CIDR).
  • Prefer ProxyJump (ssh -J bastion target) over SSH agent forwarding, so the private key never leaves the laptop and a compromised bastion cannot reuse the agent.
  • Put EC2 Instance Connect on the bastion so it holds no static keys, and scope SendSSHPublicKey to the bastion’s instance ARN.
  • Keep it stateless and disposable: an Auto Scaling group of one, built from a hardened AMI (EC2 Image Builder, Skill 3.2.1), patched by Patch Manager, with no application data on it.
  • Capture OS-level session logs (for example script or auditd) to CloudWatch Logs, and alarm on new SSH logins.

Then recognize that EC2 Instance Connect Endpoint is the managed replacement for exactly this design, and Session Manager removes the need for SSH at all. If the scenario does not state a constraint that forces SSH, the bastion is the distractor.

EC2 Serial Console: break-glass, not administration

The EC2 Serial Console attaches you to an instance’s virtual serial port, independent of networking. It exists for the moment an instance will not boot, has a broken sshd_config or a bad firewall rule, or has lost its network configuration. Because the connection is outside the VPC, security groups and network ACLs do not apply to it, which is why it is locked down three times over:

  • Account level, per Region: disabled by default; enable with aws ec2 enable-serial-console-access, or centrally through an Organizations declarative policy (then individual accounts cannot flip the setting themselves).
  • IAM level: ec2-instance-connect:SendSerialConsoleSSHPublicKey on specific instance ARNs or with aws:ResourceTag matched against aws:PrincipalTag. The action name tells you the mechanism: an ephemeral SSH public key is pushed to the serial console service, as with EIC.
  • OS level: on Linux you need a password-based OS user to log in at the console (AWS AMIs ship without one), so part of the setup is sudo passwd <user> while you still have normal access. On Windows, granting serial console access is equivalent to granting administrator rights.

Serial console sessions persist across reboot and stop, which is what makes them useful for watching boot messages. The exam distractor pattern: an operator wants routine access without opening ports, and one answer is “enable the EC2 Serial Console”. That is wrong. Routine access is Session Manager or an Instance Connect Endpoint; the serial console is the fire extinguisher.

Decision table: requirement to answer

Scenario requirementBest answerWhy not the others
Interactive admin shell with no inbound ports, no public IP, no SSH keysSession ManagerEIC needs port 22 and a public address; EICE still uses SSH
Full transcript of operator commands for auditorsSession Manager standard session with S3 or CloudWatch Logs loggingSSH and port-forwarding sessions are not logged; EIC/EICE never log content
Private instance has no internet access and no NAT but must use Session ManagerInterface VPC endpoints for ssm, ssmmessages, ec2messagesNAT or IGW widens exposure unnecessarily
Manage every instance in a Region without touching instance profilesDefault Host Management ConfigurationRequires IMDSv2 and agent 3.2.582.0 or later
Operators must not be root during sessionsRemove sudo from ssm-user, or turn on Run As with SSMSessionRunAs tagsRun As never uses root and never falls back to ssm-user
Developers need a private RDS endpoint from laptops without a bastionAWS-StartPortForwardingSessionToRemoteHost through an SSM-managed instanceThe database needs no agent
Team needs native SSH/SCP tooling but port 22 must stay closedSSH over Session Manager (AWS-StartSSHSession ProxyCommand)Accept that these sessions are not logged
Block one team from tunnelling or SSH while allowing shellsDeny ssm:StartSession on the AWS-StartPortForwardingSession / AWS-StartSSHSession document ARNs; add ssm:SessionDocumentAccessCheckInstance-level conditions do not distinguish session types
Browser-based SSH from the EC2 console works on a laptop but fails in the consoleInbound 22 from the com.amazonaws.<region>.ec2-instance-connect prefix listConsole traffic comes from the service, not the user’s IP
SSH or RDP to private instances in a VPC with no IGW, no agentEC2 Instance Connect EndpointSession Manager needs the agent and outbound reachability; a bastion needs a public IP
Limit tunnel users to port 22 in one subnet for 30 minutesec2-instance-connect:OpenTunnel with remotePort, privateIpAddress, maxTunnelDuration conditionsSecurity groups cannot express per-user limits
Instance stopped responding to SSH after a bad firewall changeEC2 Serial Console (account enabled, IAM granted, OS user with a password)Nothing network-based will work
Centrally forbid serial console access in all member accountsDeclarative policy (or SCP denying ec2:EnableSerialConsoleAccess)Per-account settings can be re-enabled locally

IAM condition keys cheat sheet

Access pathPrimary actionScope which targetsScope howScope who-as
Session Managerssm:StartSessionInstance ARNs, ssm:resourceTag/<key>Document ARN (SSM-SessionManagerRunShell, AWS-StartSSHSession, AWS-StartPortForwardingSession), ssm:SessionDocumentAccessCheckSSMSessionRunAs tag on the principal (Run As)
Session ownershipssm:TerminateSession, ssm:ResumeSession, ssmmessages:OpenDataChannelarn:aws:ssm:*:*:session/${aws:userid}-*ssm:resourceTag/aws:ssmmessages:session-id and target-idn/a
EC2 Instance Connectec2-instance-connect:SendSSHPublicKeyInstance ARNs, aws:ResourceTag/<key>n/a (SSH follows)ec2:osuser
EC2 Instance Connect Endpointec2-instance-connect:OpenTunnelEndpoint ARN, ec2-instance-connect:privateIpAddressec2-instance-connect:remotePort, ec2-instance-connect:maxTunnelDuration, aws:SourceIpec2:osuser on the companion SendSSHPublicKey
EC2 Serial Consoleec2-instance-connect:SendSerialConsoleSSHPublicKeyInstance ARNs, aws:ResourceTag = aws:PrincipalTagAccount-level ec2:EnableSerialConsoleAccess or declarative policyOS password

Scenario drill

Scenario wordingWhat it is really askingAnswer
”Operators connect with Session Manager, but the SOC cannot see what they ran. Sessions are started with ssh -i key ec2-user@i-....”Logging gap for SSH sessionsSwitch to standard shell sessions; enable S3/CloudWatch logging; deny the AWS-StartSSHSession document
”A session must end after 15 minutes of inactivity and never exceed 8 hours.”Idle vs maximum durationIdle timeout 15 (range 1 to 60); maximum session duration 480 (range 1 to 1,440)
“After enabling KMS encryption of session data, no one can start sessions.”Two-sided KMS permissionsUsers need kms:GenerateDataKey; instance roles need kms:Decrypt; agent must be 2.3.539.0 or later
”Instances in an isolated subnet show as not managed.”Agent cannot reach endpointsInterface endpoints for ssm, ssmmessages, ec2messages; agent 2.3.68.0 or later
”After disabling IMDS for hardening, Session Manager stopped working.”Agent credentials come from IMDSKeep IMDS on, enforce IMDSv2 instead
”Each operator must appear in OS logs under their own account; nobody may be root.”Run AsEnable Run As, tag principals with SSMSessionRunAs, create matching OS users; Run As refuses root
”Junior admins may only tail one log file.”Interactive command documentCustom Session document with InteractiveCommands session type; grant ssm:StartSession on that document only
”A user terminated a colleague’s session.”Session ownershipScope ssm:TerminateSession to session/${aws:userid}-* or the aws:ssmmessages:session-id tag
”Console-based EC2 Instance Connect fails; CLI works.”Prefix-list ruleAllow 22 inbound from com.amazonaws.<region>.ec2-instance-connect
”Users with SendSSHPublicKey can reach every instance.”Missing resource scopeRestrict by instance ARN or aws:ResourceTag, and pin ec2:osuser
”Pushed key works for 60 seconds then stops.”Expected behaviourEIC keys live in metadata for 60 seconds by design; re-push for each connection
”RDP to private Windows instances without a bastion or public IPs.”EICE supports 3389Instance Connect Endpoint with remotePort 3389
”Policy sets maxTunnelDuration to 900 but connections are refused.”Required CLI flagPass --max-tunnel-duration 900 (or less) when the policy value is below 3,600
”Client IP preservation enabled; instances in a peered VPC stopped accepting connections.”Preservation constraintsSame-VPC only, IPv4 only, not through transit gateway; or reference the endpoint SG instead of IP ranges
”Need a second endpoint in another AZ of the same VPC.”QuotaOne endpoint per VPC; delete and recreate, or accept cross-AZ transfer charges
”Instance unreachable after a sshd_config typo; must recover without snapshotting.”Serial consoleEnable account access, grant SendSerialConsoleSSHPublicKey, use the password-based user set earlier
”Prevent any account in the organization from enabling the serial console.”Central controlDeclarative policy for the serial console setting, or SCP denying ec2:EnableSerialConsoleAccess

Common mistakes

  • Assuming Session Manager logs everything. It logs standard shell sessions only. SSH and port-forwarding sessions pass through the tunnel unrecorded. Many candidates lose a point here.
  • Confusing EC2 Instance Connect with EC2 Instance Connect Endpoint. The first pushes a 60-second key and needs a public address plus an open port; the second is a TCP proxy that needs neither. Only the endpoint supports RDP.
  • Opening port 22 for Session Manager. It is never required. If a scenario’s “fix” adds an inbound rule for Session Manager, it is wrong.
  • Forgetting the instance side of permissions. Session logging to S3 or CloudWatch and KMS session encryption need permissions on the instance role, not only on the user.
  • Treating Run As as a fallback. When Run As is on and the OS user is missing, the session fails; it does not revert to ssm-user.
  • Expecting the IAM session to end the tunnel. EICE tunnels last until maxTunnelDuration, regardless of credential expiry.
  • Reaching for the serial console as an access method. It bypasses security groups and NACLs by design and must stay a break-glass tool.
  • Disabling IMDS instead of enforcing IMDSv2. SSM Agent, and therefore Session Manager, depends on the instance role delivered through metadata.

Practice until the discriminator jumps out

Security Specialty questions in this area are never titled “Session Manager question”. They describe an auditor, a compliance deadline, a stopped instance or a developer’s laptop, and bury the discriminating phrase (“transcript”, “no public IP”, “RDP”, “60 seconds”, “inactivity”, “will not boot”) in the middle of a paragraph. Getting fast at spotting that phrase takes repetition against realistically worded scenarios. Sailor.sh’s AWS Certified Security - Specialty Mock Exam Bundle includes eight full-length mock exams whose infrastructure-security and incident-response scenarios are written in that indirect style, with explanations that walk through why Session Manager, an Instance Connect Endpoint, a hardened bastion or the serial console is the best fit for the stated requirement. The compute-access content carried straight from SCS-C02 into SCS-C03, so the drills remain on-blueprint. Pair the mocks with the Security Specialty practice questions, the 30-day study plan and the IAM deep dive for the policy-evaluation logic these condition keys depend on.

Frequently Asked Questions

Does Session Manager require port 22 or 3389 to be open?

No. The SSM Agent initiates an outbound HTTPS connection to the Systems Manager endpoints, and the session rides that channel. You can remove all inbound rules from the security group and still start sessions. The instance also does not need a public IP as long as it can reach the ssm, ssmmessages and ec2messages endpoints, through NAT or interface VPC endpoints.

What is the difference between EC2 Instance Connect and EC2 Instance Connect Endpoint?

EC2 Instance Connect pushes a one-time SSH public key into instance metadata for 60 seconds, after which normal SSH takes place; it needs port 22 reachable from the client and a public address or private connectivity. EC2 Instance Connect Endpoint is an identity-aware TCP proxy that AWS provisions as a network interface in your subnet; it tunnels SSH or RDP to private instances with no public IP and no internet gateway, authorized by ec2-instance-connect:OpenTunnel. The two are often used together: the endpoint provides the path, the one-time key provides the login.

Why are my SSH-over-Session-Manager sessions missing from the S3 logs?

Because Session Manager only acts as a tunnel for SSH and port-forwarding sessions. The SSH traffic is encrypted inside the TLS channel, so the service cannot see or record it. Standard shell sessions (the Standard_Stream session type) are the ones that produce transcripts. If a transcript is a requirement, use standard sessions and consider denying the AWS-StartSSHSession document.

How do I stop Session Manager users from being root?

Either overwrite /etc/sudoers.d/ssm-agent-users so that ssm-user no longer has NOPASSWD:ALL, or enable Run As and tag each IAM user or role with SSMSessionRunAs set to a non-root OS user that exists on the node. Run As does not support root and does not fall back to ssm-user when the named user is missing.

Can an EC2 Instance Connect Endpoint reach instances in another VPC?

The endpoint reaches any subnet in its own VPC whose route table allows traffic from the endpoint’s subnet. With client IP preservation turned off, you can route through peering or a transit gateway, but client IP preservation requires the instance to be in the same VPC and does not work through a transit gateway. There is a quota of one endpoint per VPC and per subnet, and each endpoint supports 20 concurrent connections.

Is the EC2 Serial Console a replacement for Session Manager?

No. The serial console is an out-of-band troubleshooting path that ignores security groups and network ACLs. It is disabled by default at the account level, must be granted per user through ec2-instance-connect:SendSerialConsoleSSHPublicKey, and requires a password-based OS user on Linux. Use it when an instance cannot be reached any other way, and govern it centrally with a declarative policy or an SCP.

Which of these should I expect on the SCS-C03 exam?

Skill 3.2.5 names Session Manager and EC2 Instance Connect explicitly, and the in-scope list calls out EC2 Instance Connect under Amazon EC2. Expect scenario questions that make you choose between those two, the Instance Connect Endpoint and a bastion, plus troubleshooting questions on VPC endpoints, KMS permissions, logging gaps and IAM condition keys.

Conclusion

Administrative access is a solved problem on AWS, but only if you can match the mechanism to the requirement. Session Manager removes ports, keys and bastions and gives you transcripts, timeouts, Run As and KMS encryption, with the one caveat that SSH and port-forwarding sessions are not logged. EC2 Instance Connect keeps SSH but turns the key into a 60-second, IAM-authorized token. EC2 Instance Connect Endpoint turns the bastion into a managed, IAM-governed TCP proxy for SSH and RDP with precise remotePort, privateIpAddress and maxTunnelDuration controls. A bastion host remains for the rare case that forces raw SSH, and the serial console waits for the day the network is broken. Learn where each one authenticates, what each one needs from the network, and what each one writes to the log, and Skill 3.2.5 becomes some of the most predictable points on the exam.

Limited Time Offer: Get 80% off all Mock Exam Bundles | Sale ends in 7 days. Start learning today.

Claim Now