DEV Community 👩‍💻👨‍💻

Cover image for Policy Sentry - IAM Least Privilege Policy Generator
NaveenKumar Namachivayam ⚡ for AWS Community Builders

Posted on • Originally published at qainsights.com

Policy Sentry - IAM Least Privilege Policy Generator

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:

  1. actions
  2. 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.

ListBuckets error
ListBuckets error

But if you list the exact bucket name, it will work as shown below.

s3 access
s3 access

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
Policy Sentry Initialize

policy_sentry initialize --fetch command will fetch all the latest AWS services if you want to play around.

Policy Sentry Fetch
Policy Sentry Fetch

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)

🌚 Life is too short to browse without dark mode