Cloud-custodian: aws.iam-role - filter based on trust policy

Created on 30 Sep 2020  路  4Comments  路  Source: cloud-custodian/cloud-custodian

Is your feature request related to a problem? Please describe.
I'm currently using a c7n policy that will auto attach an IAM managed policy to every newly created role. I'd like to do attach it to only IAM roles that have a trusted policy for ec2.amazonaws.com. Since I cannot do that afaict, I have tagged my non-EC2 iam roles with notEC2 or similar.

Describe the solution you'd like
I'd like a new filter that would search through the trusted policy so we can see if an IAM role has a trust relationship with a specific AWS service.

Describe alternatives you've considered
Using the tag based approach mentioned above.

Additional context

policies:
- name: iam-attach-default-policy
  resource: iam-role
  description: |
    Attach default IAM policy triggered on the cloudtrail event name CreateRole
  mode:
    type: cloudtrail
    events:
      - source: iam.amazonaws.com
        event: CreateRole
        ids: "requestParameters.roleName"
    role: cloud-custodian
    tags:
      application: cloud-custodian
      team: sre
      env: production
    execution-options:
      output_dir: s3://bucket/cloud-custodian/output
  filters:
    - type: no-specific-managed-policy
      value: base
    - not:
      - type: value
        key: Path
        op: regex
        value: ".*aws-service-role.*"
    - "tag:notEC2": absent
  actions:
    - type: set-policy
      state: attached
      arn: arn:aws:iam::{account_id}:policy/base
kinenhancement

Most helpful comment

we have a specific filter for cross-account on it, internally that does some normalization, although i wonder if the has-statement pr would also be useful here, albeit exposed as trust-statement filter.

All 4 comments

the trust document is an attribute of a role

Hmmmm I didn't realize. Thank you!

aws iam get-role --role-name task

Case # 1 - Single statement and Service is a string

{
    "Role": {
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Sid": "",
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "ec2.amazonaws.com"
                    },
                    "Action": "sts:AssumeRole"
                }
            ]
        }
    }
}

Case # 2 - Multi statement and Service is a string

{
    "Role": {
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Sid": "",
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "ec2.amazonaws.com"
                    },
                    "Action": "sts:AssumeRole"
                },
                {
                    "Sid": "",
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "lambda.amazonaws.com"
                    },
                    "Action": "sts:AssumeRole"
                },
            ]
        }
    }
}

Case # 3 - Single statement and Service is an array

{
    "Role": {
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Sid": "",
                    "Effect": "Allow",
                    "Principal": {
                        "Service": [
                          "ec2.amazonaws.com",
                          "lambda.amazonaws.com"
                        ]
                    },
                    "Action": "sts:AssumeRole"
                }
            ]
        }
    }
}

so I could filter using

  filters:
    - type: value
      key: "AssumeRolePolicyDocument.Statement[].Principal.Service"
      # key: "AssumeRolePolicyDocument.Statement[].Principal.Service[]"
      op: contains
      value:
        - "ec2.amazonaws.com"

Sometimes the Service is a string and sometimes it's an array. Is it possible to filter with both ?

@kapilt if it's not very easy, then perhaps we need a specific filter for this for iam-role. What do you think ?

we have a specific filter for cross-account on it, internally that does some normalization, although i wonder if the has-statement pr would also be useful here, albeit exposed as trust-statement filter.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

justinhauer picture justinhauer  路  4Comments

kwcrook picture kwcrook  路  4Comments

mechastorm picture mechastorm  路  5Comments

twitherspoon picture twitherspoon  路  4Comments

engineertree5 picture engineertree5  路  3Comments