Skip to main content

Generate locked-down AWS IAM Policies

Project description

Policy Sentry

Build Status Documentation Status Join the chat at https://gitter.im/salesforce/policy_sentry

IAM Least Privilege Policy Generator, auditor, and analysis database.

Wiki

For walkthroughs and full documentation, please visit the project on ReadTheDocs.

Overview

Writing security-conscious IAM Policies by hand can be very tedious and inefficient. Many Infrastructure as Code developers have experienced something like this:

  • Determined to make your best effort to give users and roles the least amount of privilege you need to perform your duties, you spend way too much time combing through the AWS IAM Documentation on Actions, Resources, and Condition Keys for AWS Services.
  • Your team lead encourages you to build security into your IAM Policies for product quality, but eventually you get frustrated due to project deadlines.
  • You don't have an embedded security person on your team who can write those IAM policies for you, and there's no automated tool that will automagically sense the AWS API calls that you perform and then write them for you in a least-privilege manner.
  • After fantasizing about that level of automation, you realize that writing least privilege IAM Policies, seemingly out of charity, will jeopardize your ability to finish your code in time to meet project deadlines.
  • You use Managed Policies (because hey, why not) or you eyeball the names of the API calls and use wildcards instead so you can move on with your life.

Such a process is not ideal for security or for Infrastructure as Code developers. We need to make it easier to write IAM Policies securely and abstract the complexity of writing least-privilege IAM policies. That's why I made this tool.

Authoring Secure IAM Policies

Policy Sentry's flagship feature is that it can create IAM policies based on resource ARNs and access levels. Our CRUD functionality takes the opinionated approach that IAC developers shouldn't have to understand the complexities of AWS IAM - we should abstract the complexity for them. In fact, developers should just be able to say...

  • "I need Read/Write/List access to arn:aws:s3:::example-org-sbx-vmimport"
  • "I need Permissions Management access to arn:aws:secretsmanager:us-east-1:123456789012:secret:mysecret"
  • "I need Tagging access to arn:aws:ssm:us-east-1:123456789012:parameter/test"

...and our automation should create policies that correspond to those access levels.

How do we accomplish this? Well, Policy Sentry leverages the AWS documentation on Actions, Resources, and Condition Keys documentation to look up the actions, access levels, and resource types, and generates policies according to the ARNs and access levels. Consider the table snippet below:

Actions Access Level Resource Types
ssm:GetParameter Read parameter
ssm:DescribeParameters List parameter
ssm:PutParameter Write parameter
secretsmanager:PutResourcePolicy Permissions management secret
secretsmanager:TagResource Tagging secret

Policy Sentry aggregates all of that documentation into a single database and uses that database to generate policies according to actions, resources, and access levels. To generate a policy according to resources and access levels, start by creating a template with this command so you can just fill out the ARNs:

policy_sentry create-template --name myRole --output-file crud.yml --template-type crud

It will generate a file like this:

policy_with_crud_levels:
- name: myRole
  description: ''
  arn: ''
  # Insert ARNs under each access level below
  # If you do not need to use certain access levels, delete them.
  read:
    - ''
  write:
    - ''
  list:
    - ''
  tag:
    - ''
  permissions-management:
    - ''
  # If the policy needs to use IAM actions that cannot be restricted to ARNs,
  # like ssm:DescribeParameters, specify those actions here.
  wildcard:
    - ''

Then just fill it out:

policy_with_crud_levels:
- name: myRole
  description: 'Justification for privileges'
  arn: 'arn:aws:iam::123456789102:role/myRole'
  read:
    - 'arn:aws:ssm:us-east-1:123456789012:parameter/myparameter'
  write:
    - 'arn:aws:ssm:us-east-1:123456789012:parameter/myparameter'
  list:
    - 'arn:aws:ssm:us-east-1:123456789012:parameter/myparameter'
  tag:
    - 'arn:aws:secretsmanager:us-east-1:123456789012:secret:mysecret'
  permissions-management:
    - 'arn:aws:secretsmanager:us-east-1:123456789012:secret:mysecret'

Then run this command:

policy_sentry write-policy --crud --input-file crud.yml

It will generate these results:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "SsmReadParameter",
            "Effect": "Allow",
            "Action": [
                "ssm:getparameter",
                "ssm:getparameterhistory",
                "ssm:getparameters",
                "ssm:getparametersbypath",
                "ssm:listtagsforresource"
            ],
            "Resource": [
                "arn:aws:ssm:us-east-1:123456789012:parameter/myparameter"
            ]
        },
        {
            "Sid": "SsmWriteParameter",
            "Effect": "Allow",
            "Action": [
                "ssm:deleteparameter",
                "ssm:deleteparameters",
                "ssm:putparameter",
                "ssm:labelparameterversion"
            ],
            "Resource": [
                "arn:aws:ssm:us-east-1:123456789012:parameter/myparameter"
            ]
        },
        {
            "Sid": "SecretsmanagerPermissionsmanagementSecret",
            "Effect": "Allow",
            "Action": [
                "secretsmanager:deleteresourcepolicy",
                "secretsmanager:putresourcepolicy"
            ],
            "Resource": [
                "arn:aws:secretsmanager:us-east-1:123456789012:secret:mysecret"
            ]
        },
        {
            "Sid": "SecretsmanagerTaggingSecret",
            "Effect": "Allow",
            "Action": [
                "secretsmanager:tagresource",
                "secretsmanager:untagresource"
            ],
            "Resource": [
                "arn:aws:secretsmanager:us-east-1:123456789012:secret:mysecret"
            ]
        }
    ]
}

Notice how the policy above recognizes the ARNs that the user supplies, along with the requested access level. For instance, the SID “SecretsmanagerTaggingSecret” contains Tagging actions that are assigned to the secret resource type only.

This rapidly speeds up the time to develop IAM policies, and ensures that all policies created limit access to exactly what your role needs access to. This way, developers only have to determine the resources that they need to access, and we abstract the complexity of IAM policies away from their development processes.

Quickstart

  • policy_sentry is available via pip. To install, run:
pip install --user policy_sentry
  • Initialization
# 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
  • Policy Writing cheat sheet
# Initialize the policy_sentry config folder and create the IAM database tables.
policy_sentry initialize

# Create a template file for use in the write-policy command (crud mode)
policy_sentry create-template --name myRole --output-file tmp.yml --template-type crud

# Write policy based on resource-specific access levels
policy_sentry write-policy --crud --input-file examples/yml/crud.yml

# Write policy_sentry YML files based on resource-specific access levels on a directory basis
policy_sentry write-policy-dir --crud --input-dir examples/input-dir --output-dir examples/output-dir

# Create a template file for use in the write-policy command (actions mode)
policy_sentry create-template --name myRole --output-file tmp.yml --template-type actions

# Write policy based on a list of actions
policy_sentry write-policy --input-file examples/yml/actions.yml
  • IAM Database Query Cheat Sheet
###############
# Actions Table
###############
# 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
  • Policy Analysis Cheat Sheet
# Initialize the policy_sentry config folder and create the IAM database tables.
policy_sentry initialize

# Initialize the database, but instead of using the AWS HTML files in the Python package, download the very latest AWS HTML Docs and make sure that Policy Sentry uses them
policy_sentry initialize --fetch

# Analyze a single IAM policy FILE
policy_sentry analyze policy-file --policy examples/explicit-actions.json

# Download customer managed IAM policies from a live account under 'default' profile. By default, it looks for policies that are 1. in use and 2. customer managed
policy_sentry download-policies # this will download to ~/.policy_sentry/accountid/customer-managed/.json

# Download customer-managed IAM policies, including those that are not attached
policy_sentry download-policies --include-unattached # this will download to ~/.policy_sentry/accountid/customer-managed/.json

# 1. Use a tool like Gossamer (https://github.com/GESkunkworks/gossamer) to update your AWS credentials profile all at once
# 2. Recursively download all IAM policies from accounts in your credentials file
policy_sentry download-policies --recursive

# Audit all IAM policies downloaded locally and generate CSV and JSON reports.
policy_sentry analyze downloaded-policies

# Audit all IAM policies and also include a Markdown formatted report, then convert it to HTML
policy_sentry analyze downloaded-policies --include-markdown-report
pandoc -f markdown ~/.policy_sentry/analysis/overall.md -t html > overall.html

# Use a custom report configuration. This is typically used for excluding role names. Defaults to ~/.policy_sentry/report-config.yml
policy_sentry analyze downloaded-policies --report-config custom-config.yml

# Analyze a specific policy file
policy_sentry analyze policy-file --policy examples/analyze/explicit-actions.json

Commands

Usage

  • initialize: Create a SQLite database that contains all of the services available through the Actions, Resources, and Condition Keys documentation. See the documentation.

  • create-template: Creates the YML file templates for use in the write-policy command types.

  • write-policy: Leverage a YAML file to write policies for you

    • Option 1: Specify CRUD levels (Read, Write, List, Tagging, or Permissions management) and the ARN of the resource. It will write this for you. See the documentation
    • Option 2: Specify a list of actions. It will write the IAM Policy for you, but you will have to fill in the ARNs. See the documentation.
  • write-policy-dir: This can be helpful in the Terraform use case. For more information, see the documentation.

  • download-policies: Download IAM policies from your AWS account for analysis.

  • analyze: Analyze IAM policies downloaded locally, expands the wildcards (like s3:List*) if necessary, and generates a report based on policies that are flagged for these risk categories:

    • Privilege Escalation: This is based off of Rhino Security Labs research.

    • Resource Exposure: This contains all IAM Actions at the "Permissions Management" resource level. Essentially - if your policy can (1) write IAM Trust Policies, (2) write to the RAM service, or (3) write Resource-based Policies, then the action has the potential to result in resource exposure if an IAM principal with that policy was compromised.

    • Network Exposure: This highlights IAM actions that indicate an IAM principal possessing these actions could create resources that could be exposed to the public at the network level. For example, public RDS clusters, public EC2 instances. While possession of these privileges does not constitute a security vulnerability, it is important to know exactly who has these permissions.

    • Credentials Exposure: This includes IAM actions that grant some kind of credential, where if exposed, it could grant access to sensitive information. For example, ecr:GetAuthorizationToken creates a token that is valid for 12 hours, which you can use to authenticate to Elastic Container Registries and download Docker images that are private to the account.

  • query: Query the IAM database tables. This can help when filling out the Policy Sentry templates, or just querying the database for quick knowledge.

    • Option 1: Query the Actions Table (action-table)
    • Option 2: Query the ARNs Table (arn-table)
    • Option 3: Query the Conditions Table (condition-table)

Updating the AWS HTML files

This will update the HTML files stored in policy_sentry/shared/data/docs/list_*.partial.html:

pipenv shell
python3 ./utils/download_docs.py

References

Project details


Release history Release notifications | RSS feed

This version

0.6.4

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

policy_sentry-0.6.4.tar.gz (786.8 kB view hashes)

Uploaded Source

Built Distribution

policy_sentry-0.6.4-py3-none-any.whl (1.3 MB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page