In our last blog post, we read about Cloudsplaining - AWS IAM Security Assessment Tool from Salesforce OSS. I have mentioned that Cloudsplaining is a reactive tool whereas Policy Sentry is a preventive tool to write secured least privileged IAM Policies in AWS. In this blog post, we are going to deep-dive into Policy Sentry.
Policy Sentry
Handcrafting IAM policies is cumbersome, especially from a security perspective. Enter Policy Sentry - a Python utility to generate the least privilege IAM policy for AWS.
It is an open source initiative from Salesforce. Using Policy Sentry, it is easy to automate the creation of IAM policies with little knowledge on security.
Getting Started
The only prerequisite to installing Policy Sentry is to have the latest version of Python with pip3.
Enter the below command which will install Policy Sentry in Windows.
pip3 install --user policy_sentry
For MacOS, use:
brew tap salesforce/policy_sentry https://github.com/salesforce/policy_sentry
brew install policy_sentry
To validate the installation, enter:
policy_sentry --version
For bash, auto complete:
eval "$(_POLICY_SENTRY_COMPLETE=source policy_sentry)"
For zsh, auto complete:
eval "$(_POLICY_SENTRY_COMPLETE=source_zsh policy_sentry)"
Hello S3 Policy
Let us begin creating a new IAM policy to read the S3 buckets using Policy Sentry. The first step is to generate a template.
There are two types of templates available in Policy Sentry:
- actions
- CRUD
Enter the below command to create a template using crud type.
policy_sentry create-template --template-type crud --output-file readonlyS3.yaml
Open the readonlyS3.yaml
in your favorite editor and add the ARN as shown below.
Create a S3 bucket e.g. policy-sentry-demo-bucket
and add some dummy files for testing purpose.
mode: crud
name: 'readonlyS3'
# Specify resource ARNs
read:
- 'arn:aws:s3:::policy-sentry-demo-bucket'
list:
- 'arn:aws:s3:::policy-sentry-demo-bucket'
# If this policy needs to include an AssumeRole action
sts:
assume-role:
- 'arn:aws:iam::1234567890:role/policy_sentry_demo_role'
The next step is to generate an IAM policy using this template. Issue the below command to generate the IAM policy.
policy_sentry write-policy --input-file readonlyS3.yaml > readonlyS3_policy.json
If you print the contents of readonlyS3_policy.json
, it will display as shown below.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "S3ReadBucket",
"Effect": "Allow",
"Action": [
"s3:GetAccelerateConfiguration",
"s3:GetAnalyticsConfiguration",
"s3:GetBucketAcl",
"s3:GetBucketCORS",
"s3:GetBucketLocation",
"s3:GetBucketLogging",
"s3:GetBucketNotification",
"s3:GetBucketObjectLockConfiguration",
"s3:GetBucketOwnershipControls",
"s3:GetBucketPolicy",
"s3:GetBucketPolicyStatus",
"s3:GetBucketPublicAccessBlock",
"s3:GetBucketRequestPayment",
"s3:GetBucketTagging",
"s3:GetBucketVersioning",
"s3:GetBucketWebsite",
"s3:GetEncryptionConfiguration",
"s3:GetIntelligentTieringConfiguration",
"s3:GetInventoryConfiguration",
"s3:GetLifecycleConfiguration",
"s3:GetMetricsConfiguration",
"s3:GetReplicationConfiguration"
],
"Resource": [
"arn:aws:s3:::policy-sentry-demo-bucket"
]
},
{
"Sid": "S3ListBucket",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:ListBucketMultipartUploads",
"s3:ListBucketVersions"
],
"Resource": [
"arn:aws:s3:::policy-sentry-demo-bucket"
]
},
{
"Sid": "AssumeRole",
"Effect": "Allow",
"Action": [
"sts:AssumeRole"
],
"Resource": [
"arn:aws:iam::1234567890:role/policy_sentry_demo_role"
]
}
]
}
The next step is to generate a policy. Assuming you have the AWS CLI configured with valid privileges.
aws iam create-policy --policy-name policysentry_demo_s3 --policy-document file://readonlyS3_policy.json
Copy the ARN from the output. The next step is to create an IAM role.
To create an IAM Role, we need a trust document. The below command will create a trust.json
.
cat << 'EOF' > trust.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::1234567890:root"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
After creating trust.json
, enter the below command which will create a role.
aws iam create-role --role-name policy_sentry_demo_role --assume-role-policy-document file://trust.json
Copy the role ARN which we will need it for testing.
The next step is to attach the created policy policysentry_demo_s3
using the below command.
aws iam attach-role-policy --role-name policy_sentry_demo_role --policy-arn arn:aws:iam::1234567890:policy/policysentry_demo_s3
Congratulations! You just created least privileged IAM policy using Policy Sentry. Let us put this into action.
Testing the IAM Policy
Enter the below command to get the temp credentials:
aws sts assume-role --role-arn arn:aws:iam::1234567890:role/policy_sentry_demo_role --role-session-name policy_sentry_demo
Copy the access key, secret access, and the token and create the below environment variables in *nx OS, in case of Windows, use set
command.
export AWS_ACCESS_KEY_ID=ASIAS6WEREROPETNGKNLOIEF
export AWS_SECRET_ACCESS_KEY=Isdff3rtdfg344fdgh31123ghjyjkiuolGQzxTN7znDwTEdfgdfgX4
export AWS_SESSION_TOKEN=IQoJb3JpZ2luX2VjENL//////////wEaCXVzLWVhc3QtMiJHMEUCIQD6AFLxIVfsoX7OH0Ta5xb6snPAAJWDFvLFu2BodaoCEgIgCugSJ0Th19QZPhK7FFIRqyGzCXGoq2GKLJNrjgR9AePbAURrLalHEoDnhv/sHWXPE3/Z0piRFH/IK73nk8vNA=
Now, issue the aws s3 list command, you will get the below error.
But if you list the exact bucket name, it will work as shown below.
If you are not able to list the bucket or getting any other error, this video will be helpful.
Helpful Commands
Below are the commands that will be helpful to learn. It is a shameless copy from the repo.
# Create templates first!!! This way you can just paste the values you need rather than remembering the YAML format
# CRUD mode
policy_sentry create-template --output-file tmp.yml --template-type crud
# Actions mode
policy_sentry create-template --output-file tmp.yml --template-type actions
# Write policy based on resource-specific access levels
policy_sentry write-policy --input-file examples/yml/crud.yml
# Write policy based on a list of actions
policy_sentry write-policy --input-file examples/yml/actions.yml
###############
# Actions Table
###############
# NOTE: Use --fmt yaml or --fmt json to change the output format. Defaults to json for querying
# Get a list of actions that do not support resource constraints
policy_sentry query action-table --service s3 --resource-type "*" --fmt yaml
# Get a list of actions at the "Write" level in S3 that do not support resource constraints
policy_sentry query action-table --service s3 --access-level write --resource-type "*" --fmt yaml
# Get a list of all IAM actions across ALL services that have "Permissions management" access
policy_sentry query action-table --service all --access-level permissions-management
# Get a list of all IAM Actions available to the RAM service
policy_sentry query action-table --service ram
# Get details about the `ram:TagResource` IAM Action
policy_sentry query action-table --service ram --name tagresource
# Get a list of all IAM actions under the RAM service that have the Permissions management access level.
policy_sentry query action-table --service ram --access-level permissions-management
# Get a list of all IAM actions under the SES service that support the `ses:FeedbackAddress` condition key.
policy_sentry query action-table --service ses --condition ses:FeedbackAddress
###########
# ARN Table
###########
# Get a list of all RAW ARN formats available through the SSM service.
policy_sentry query arn-table --service ssm
# Get the raw ARN format for the `cloud9` ARN with the short name `environment`
policy_sentry query arn-table --service cloud9 --name environment
# Get key/value pairs of all RAW ARN formats plus their short names
policy_sentry query arn-table --service cloud9 --list-arn-types
######################
# Condition Keys Table
######################
# Get a list of all condition keys available to the Cloud9 service
policy_sentry query condition-table --service cloud9
# Get details on the condition key titled `cloud9:Permissions`
policy_sentry query condition-table --service cloud9 --name cloud9:Permissions
# Initialize the policy_sentry config folder and create the IAM database tables.
policy_sentry initialize
# Fetch the most recent version of the AWS documentation so you can experiment with new services.
policy_sentry initialize --fetch
# Override the Access Levels by specifying your own Access Levels (example:, correcting Permissions management levels)
policy_sentry initialize --access-level-overrides-file ~/.policy_sentry/overrides-resource-policies.yml
policy_sentry initialize --access-level-overrides-file ~/.policy_sentry/access-level-overrides.yml
Other Features
If you are a fan of Terraform, please check this repo. If you are into Docker, use docker build -t kmcquade/policy_sentry .
to get started.
Policy Sentry comes with a querying feature where you can query the IAM database (action, ARN, and condition table), refer to the above commands.
To fetch the latest IAM database info, start with (optional steps):
policy_sentry initialize
policy_sentry initialize --fetch
command will fetch all the latest AWS services if you want to play around.
Final Thoughts
Policy Sentry is a great utility to automate and manage IAM entities. It helps to mitigate security mishaps as it allows us to grant fine-grained access. The Policy Sentry library helps if you want to develop your custom scripts. If you face any issues or request a new feature, please check the GitHub repo.
Top comments (0)