Customers are looking for a way to limit the types of commands that can be run on their Amazon Elastic Compute Cloud (Amazon EC2) instances when using AWS Systems Manager Session Manager interactive sessions. Allowed commands vary by group, meaning you need to allow different sets of commands based on the group of users. For example, a group of support engineers might require read-only access to some log files or tools while a group of infrastructure engineers might require access to perform package updates in the operating system. In this post, I will demonstrate how two groups of users can have access to execute different sets of commands through the AWS Systems Manager Session Manager.

Solution overview

Session Manager makes it possible to start sessions on your instances and issue interactive commands. Session Manager uses a runbook-style set of SSM documents to define these commands. You can use AWS-provided SSM documents or create your own. For example, you can use the AWS-provided AWS-StartInteractiveCommand document to allow users to issue any command on their instances. The document does this by taking in the command as a parameter and then executing it as provided on the instance. To control which commands can be executed, create a custom SSM document and couple it with the allowedPattern document parameter to define a regular expression that validates the command parameter against a predefined regular expression pattern. If the command does not match the allowed pattern, the execution fails to start. Through the use of IAM policies, you can control who can execute each of the documents.

Step 1: Create two SSM documents

Start by creating two documents. The first document allows read-only access to investigate logs on your instances.

  1. In the AWS Systems Manager console, choose Documents.
  2. Choose Create Command or Session.
  3. Use the following to create the document.
    1. For Name, enter SSM-StartReadOnlyInteractiveCommand.
    2. For Document Type, choose Session document.
    3. For Content, copy and paste the following:
schemaVersion: '1.0'
description: Document to run single interactive command on an instance
sessionType: InteractiveCommands
parameters: command: type: String description: The command to run on the instance. Allows ls, cat, less, tail -f on .log files allowedPattern: ^(ls(\s[\s\w\/-]+)?)|((cat |less |tail -f )([\s\w\/-]+\.log))$
properties: windows: commands: '{{command}}' runAsElevated: false linux: commands: '{{command}}' runAsElevated: false

 

Next, create a second document that allows users to interactively update packages on your instances. Follow steps 1-3 to create a document, but use the following values:

  • For Name, enter SSM-StartUpdatePackagesInteractiveCommand.
  • For Document Type, choose Session document.
  • For Content, copy and paste the following:

 

schemaVersion: '1.0'
description: Document to run single interactive command on an instance
sessionType: InteractiveCommands
parameters: command: type: String description: The command to run on the instance allowedPattern: ^(sudo yum (update|upgrade))|(sudo yum install [\w\d-]+)|(sudo yum downgrade [\w\d-]+)$
properties: windows: commands: '{{command}}' runAsElevated: false linux: commands: '{{command}}' runAsElevated: false

 

These two documents now provide specific commands that can be run on your instances. Each document has a single parameter named command and an allowedPattern regular expression that will only allow a specific set of commands to be specified.

Step 2: Create IAM policies and apply them to your users

Now, create an IAM policy that specifies who can use these documents and prevents those users from executing any other documents, including the default session document. You will create two policies in IAM that can be used to restrict principals to executing only the specified documents.

The first policy allows users to only execute the SSM-StartReadOnlyInteractiveCommand document for all instances in your account.

  1. In the AWS Identity and Access Management console, choose Policies.
  2. Choose Create policy.
  3. In the JSON tab, copy and paste the following policy. Update the ARN account IDs, partitions, and Regions accordingly.
    { "Version":"2012-10-17", "Statement":[ { "Sid":"AllowStartReadOnlyInteractiveCommandAllInstances", "Effect":"Allow", "Action":"ssm:StartSession", "Resource":[ "arn:aws:ssm:*:111122223333:document/SSM-StartReadOnlyInteractiveCommand", "arn:aws:ec2:*:111122223333:instance/*" ], "Condition":{ "BoolIfExists":{ "ssm:SessionDocumentAccessCheck":"true" } } } ]
    }
    
  4. Choose Review policy.
  5. Enter a name and then create the policy.

 

Next, create a second policy that allows users to execute only the SSM-StartUpdatePackagesInteractiveCommand document for all instances in your account. Follow the preceding steps to create the policy, but copy and paste the following policy in the JSON tab. Again, update the ARN account IDs, partitions, and Regions accordingly.

{ "Version":"2012-10-17", "Statement":[ { "Sid":" AllowStartUpdatePackagesInteractiveCommandAllInstances", "Effect":"Allow", "Action":"ssm:StartSession", "Resource":[ "arn:aws:ssm:*:111122223333:document/SSM-StartUpdatePackagesInteractiveCommand", "arn:aws:ec2:*:111122223333:instance/*" ], "Condition":{ "BoolIfExists":{ "ssm:SessionDocumentAccessCheck":"true" } } } ]
}

You can refine these policies further to specific sets of instances. The ssm:SessionDocumentAccessCheck field is specified to ensure the user has explicit access to a session document.

Step 3: Execute the commands from the AWS CLI

After applying the policies to your users, they can now start interactive sessions through AWS Systems Manager Session Manager. Executing the commands from the AWS CLI will target a specific instance, require the document name, and your command will be provided as a parameter to the document.

The following two commands demonstrate how these two new documents can be executed from the AWS CLI. To run these commands, be sure you have installed the Session Manager plugin for the AWS CLI.

aws ssm start-session --target <instance-id-here> --document-name SSM-StartUpdatePackagesInteractiveCommand --parameters command="sudo yum upgrade" aws ssm start-session --target <instance-id-here> --document-name SSM-StartReadOnlyInteractiveCommand --parameters command="ls -al app/logs"

Conclusion

In this post, I’ve shown how you can create AWS Systems Manager documents that can only execute the allowed interactive commands to your instances. You can use this pattern to define differing levels of access to commands in your DevOps practices to better ensure the principle of least privilege.

About the Author

Adam Spicer headshot

Adam Spicer is a Senior Migration Delivery Consultant for AWS Professional Services. He works with enterprise customers to design and build their cloud infrastructure and automation to accelerate their migration to AWS. He is an avid FSU Seminole fan who loves to be on outdoor adventures with his family.