Managing access to EC2 instances is a critical part of maintaining security and compliance in the cloud.
The challenge lies in implementing true least-privilege access—ensuring that users can only access the resources they need, and only for a limited, defined period of time. This principle, often referred to as Just-in-Time (JIT) Access, minimizes risk by reducing unnecessary or prolonged permissions.
To address this, AWS offers Systems Manager Just-in-Time Node Access (JITNA)—a secure, approval-based solution that enables temporary access to nodes across AWS, on-premises, and even multi-cloud environments.
In this blog, we’ll walk through how to utilise JITNA to strengthen your access management strategy and achieve compliance with confidence.
Key Benefits
- Eliminates persistent access, granting privileges only when actively required.
- Enhances access logging, providing a comprehensive audit trail from approval to the actual session recording.
Prerequisites
- AWS Identity Center or IAM: Must be configured with users/groups.
- AWS Systems Manager: Should be centrally enabled with Default Host Management Configuration (DHMC) to automate instance IAM profile setup for the SSM.
- JITNA Enabled: JITNA must be set up in the unified Systems Manager console.
JITNA Enabling Process
JITNA automatically performs the following actions:
- IAM Role Creation: Creates an IAM role in each target account, providing Systems Manager with the necessary permissions to establish just-in-time node access resources.
- State Manager Association (Service-Linked Role): Establishes a State Manager association in each target account, creating a service-linked role that enables Systems Manager to configure just-in-time node access on your behalf.
- State Manager Association (Temporary Credentials): Generates a State Manager association in each target account, which creates an IAM role used by Systems Manager for generating temporary security credential tokens.
- State Manager Association (Delegated Administrator Account): Creates a State Manager association in the delegated administrator account and Home Region for your organization. This establishes an IAM role for sharing deny-access policies with member accounts.
Post-Enablement Session Preferences
Once JITNA is enabled, you can configure additional session preferences. These preferences can be modified in the console for any session, even after its initial approval.
Key configurable preferences include:
- Maximum session duration
- Idle session timeout
- « Run as » user for Linux instances
- KMS encryption
- Logging to S3/CloudWatch
- RDP session recording
Supported policy types
JITNA supports three distinct policy types to manage access requests:
- Auto-Deny (organization-wide): This policy type is designed to automatically deny access requests. It can only contain forbid instructions, e.g. any resource tagged as « Prod »
Example:
forbid ( principal, action == AWS::SSM::Action::"getTokenForInstanceAccess", resource ) when { resource.hasTag("Environement") && resource.getTag("Environement") == "Prod" };
Written in CEDAR language https://github.com/cedar-policy
- Auto-Approve (one per account and region, but can be have multiple permit instructions): This policy automatically approves requests from any principal belonging to the « DevOps » Group
Example:
permit ( principal, action == AWS::SSM::Action::"getTokenForInstanceAccess", resource) when { principal in AWS::IdentityStore::Group::"DevOps" };
Note: Once an auto-approved request is granted, it cannot be canceled or revoked by an administrator or the requestor. Access is granted for fixed start and end times, with a one-hour timeout automatically applied from the time of approval.
- Manual-Approval (account and region specific, with a limit of 50): This policy is used when neither auto-approval nor auto-deny rules apply. Requests are sent to designated decision-makers for manual review and approval. This policy can be applied to all or specific nodes.
Overlapping Policies:
When policies overlap, their interaction determines the outcome:
- If two manual approval policies overlap, the request will be DENIED.
- If an auto-approval policy is present and overlaps with a manual-approval workflow, the request will be APPROVED.
Permission set for Users/Groups
A minimal permission set is required for users/groups to utilize JITNA, allowing them to create a response and connect to an instance, but explicitly excluding ssm:SessionStart. This exclusion prevents users from bypassing JITNA by directly connecting to an SSM session without approval.
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "ssm:StartAccessRequest", "ssm:GetAccessToken" ], "Resource": "*", "Effect": "Allow", "Sid": "AllowJITNAOperations" }, { "Action": [ "ssm:CreateOpsItem", "ssm:GetOpsItem" ], "Resource": "arn:aws:ssm:*:*:opsitem/*", "Effect": "Allow", "Sid": "AllowOpsItemCreationAndRetrieval" }, { "Action": [ "ssm:DescribeOpsItems", "ssm:GetOpsSummary", "ssm:ListOpsItemEvents", "ssm:DescribeSessions" ], "Resource": "*", "Effect": "Allow", "Sid": "AllowListAccessRequests" }, { "Condition": { "StringEquals": { "ssm:DocumentType": "ManualApprovalPolicy" } }, "Action": "ssm:StartAutomationExecution", "Resource": "arn:aws:ssm:*:*:document/*", "Effect": "Allow", "Sid": "RequestManualApprovals" }, { "Action": "ssm:StartAutomationExecution", "Resource": "arn:aws:ssm:*:*:automation-execution/*", "Effect": "Allow", "Sid": "StartManualApprovalsAutomationExecution" }, { "Condition": { "StringEquals": { "aws:RequestTag/SystemsManagerJustInTimeNodeAccessManaged": "true" }, "ForAllValues:StringEquals": { "aws:TagKeys": [ "SystemsManagerJustInTimeNodeAccessManaged" ] } }, "Action": [ "ssm:AddTagsToResource" ], "Resource": [ "arn:aws:ssm:*:*:automation-execution/*" ], "Effect": "Allow", "Sid": "AllowManualApprovalAutomationExecutionTagging" }, { "Condition": { "StringEquals": { "aws:ResourceTag/SystemsManagerJustInTimeNodeAccessManaged": "true" } }, "Action": "ssm:StopAutomationExecution", "Resource": "arn:aws:ssm:*:*:automation-execution/*", "Effect": "Allow", "Sid": "CancelAccessRequestManualApproval" }, { "Action": [ "ec2:DescribeInstances", "ec2:DescribeTags", "ec2:GetPasswordData" ], "Resource": "*", "Effect": "Allow", "Sid": "DescribeEC2Instances" }, { "Action": [ "ssm:DescribeInstanceInformation", "ssm:ListTagsForResource" ], "Resource": "*", "Effect": "Allow", "Sid": "AllowListSSMManagedNodesAndTags" }, { "Action": [ "ssm-quicksetup:ListConfigurationManagers", "ssm-quicksetup:GetConfigurationManager", "ssm-quicksetup:ListConfigurations", "ssm-quicksetup:ListQuickSetupTypes", "ssm-quicksetup:GetConfiguration" ], "Resource": "*", "Effect": "Allow", "Sid": "QuickSetupConfigurationManagers" }, { "Action": [ "ssm:DescribeSessions", "ssm:GetConnectionStatus" ], "Resource": "*", "Effect": "Allow", "Sid": "AllowSessionManagerOperations" }, { "Action": [ "ssm-guiconnect:ListConnections", "ssm:GetConnectionStatus", "ssm-guiconnect:StartConnection" ], "Resource": "*", "Effect": "Allow", "Sid": "AllowRDPOperations" }, { "Action": [ "cloudformation:ListStacks", "cloudformation:DescribeStacks", "organizations:DescribeOrganization", "organizations:ListDelegatedAdministrators" ], "Resource": "*", "Effect": "Allow", "Sid": "QuickSetupDeployments" }, { "Condition": { "StringEquals": { "ssm:DocumentType": [ "ManualApprovalPolicy", "AutoApprovalPolicy" ] } }, "Action": [ "ssm:GetDocument", "ssm:DescribeDocument" ], "Resource": [ "arn:aws:ssm:us-east-1:010625735676:document/*" ], "Effect": "Allow", "Sid": "AllowSsmJitnaPoliciesReadOnly" }, { "Action": [ "ssm:ListDocuments", "ssm:ListDocumentVersions" ], "Resource": "*", "Effect": "Allow", "Sid": "AllowSsmJitnaPoliciesListOperations" }, { "Action": [ "ssm:ListNodesSummary", "ssm:ListNodes", "ssm:DescribeInstanceProperties" ], "Resource": "*", "Effect": "Allow", "Sid": "ExploreNodes" }, { "Action": [ "sso:DescribeRegisteredRegions", "sso:ListDirectoryAssociations", "identitystore:GetUserId", "identitystore:DescribeUser", "identitystore:DescribeGroup" ], "Resource": "*", "Effect": "Allow", "Sid": "IdentityStorePermissions" } ] }
Access Request and Approval Process
JITNA provides a mechanism for controlling access to AWS resources. Requests for access can be initiated via the AWS Console or CLI, and are always necessary.
The privilege access management flow diagram:
Centralized Configuration:
JITNA can be centrally enabled for specific organizational units and regions through AWS Systems Manager. However, policies cannot be inherited from the delegated administrator.
Approval Policies:
Both auto-approval and manual approval policies work locally only within the AWS accounts and Regions where they are established. Manual approval policies can define the quantity and levels of manual approvals required to access specified nodes.
Approval and Rejection Process:
Upon approval of a request, the session can be initiated and tracked. The approver retains the ability to revoke approval at any time. Further clarification is needed on whether the session automatically terminates upon revocation.
User Experience
For the access to the fresh node, Node operator approaches EC2 instance and click connect on its Session Manager, instead of terminal they will receive a form to request access:

Submitting the form will give the request as Access request that will be visible for requestor and approver, since we don’t have auto-approval flow, the manual approval is required in this case interacting the user from JITNA Approvers group in IAM Identity Center

This is defined by the policy.

Approver has own UI with all requests submitted where he is approver:
Approvers have a dedicated UI that displays all submitted requests for which they are designated as an approver.
The new submitted request can be rejected or approved:

Once approved, notifications can be sent to a Slack channel or MS Teams for the relevant account/region, and via email. These notifications are configurable within AWS Systems Manager settings and JITNA’s local configuration. Additionally, Amazon EventBridge can be used to add automations based on status updates.

An approval remains active until its specified end time, unless the approver revokes it. Revoking an approval prevents new sessions from starting but does not terminate any sessions already in progress:
Now the requestor can initiate an SSM session to access the node within this time window:
All sessions are tracked for each request:

Billing
Enabling JITNA will result in charges for all nodes managed by AWS Systems Manager within the account. A free trial is available. It’s important to note that individual nodes cannot be excluded from this scope.
Advantages
- Native AWS Integration: seamlessly integrated with AWS Systems Manager
- Enhanced Security Features out of the box: session loggging, KMS encryption
- Centralized Compliance: provides a centralized deny function for compliance purposes
- Flexible Approvals: supports both automatic and manual approval processes
- Session Tacking: each accessing session is logged, RDP recording
- Customizable sessions: approved requests can have their own customized settings
Disadvantages
- No Access Time Specification: Requests do not allow for defining a specific access time
- Limited Organizational Approval Flows: The system only supports deny flows, lacking broader organizational approval capabilities (automatic or manual)
- Account and Region Confinement: Usage is restricted to individual accounts and regions, preventing cross-account functionality
- Poor Organizational Visibility for Approvals: Approvals are tied to specific accounts, making it difficult to notify the correct approver when multiple teams manage nodes across different accounts
- Requirement for Additional Automation: Verifications, such as checking a requester’s shift schedule via webhooks, requires additional automation
- Lack of Native IaC Support: Current approval policies do not natively support CloudFormation or Terraform resources
Conclusion
JITNA provides native AWS integration for securing node access, along with important security features like session logging and RDP recording. However, it has major limitations including poor approval visibility, lack of centralization, and no Infrastructure as Code support. This means that while JITNA is easy to start, it is not flexible or scalable enough for large, complex, or multi-account environments.