similarweb / finala

Finala is an open-source resource cloud scanner that analyzes, discloses, presents and notifies about wasteful and unused resources.
https://finala.io
Other
732 stars 54 forks source link

Assumed role not used for pricing actions #160

Open vytautaskubilius opened 3 years ago

vytautaskubilius commented 3 years ago

What happened: When the Finala Docker container is configured to assume a cross-account IAM role, the role is only assumed for reading the resources (i.e. the ReadOnlyAccess policy), but not the pricing:* actions (i.e. the AWSPriceListServiceFullAccess policy).

What you expected to happen: The assumed role is used for all actions.

How to reproduce it (as minimally and precisely as possible):

  1. Have two AWS accounts (I'll call them local and remote, where local has Finala deployed, and remote is the account Finala scans).
  2. On the local account create an IAM role allow-assume-role that has just a single permission for the sts:AssumeRole action (with * as Resource to keep it simple).
  3. On the remote account create a cross-account IAM role finala-cross-account which trusts the local account, and attach the ReadOnlyAccess and AWSPriceListServiceFullAccess policies to it.
  4. Generate temporary credentials using the allow-assume-role role - aws sts assume-role --role-arn "arn:aws:iam::111111111111:role/allow-assume-role" --role-session-name "test-assume".
  5. Add the temporary credentials to docker-compose.yaml:
    collector:
      <truncated>
      environment:
        - AWS_ACCESS_KEY_ID=access_key_id_here
        - AWS_SECRET_ACCESS_KEY=secret_key_here
        - AWS_SESSION_TOKEN=session_token_here
  6. Add the finala-cross-account role to configuration/collector.yaml:
    providers:
    aws:
    accounts:
        <truncated>
        role: arn:aws:iam::222222222222:role/finala-cross-account
  7. Start Finala with docker-compose up.
  8. You will see in the logs that the collector starts as expected, and no errors are produced when analyzing the resources:
    collector_1      | time="2020-12-17T10:49:54Z" level=warning msg="setting logging level" fields.level=info
    collector_1      | time="2020-12-17T10:49:54Z" level=info msg="generate collector execution id" id=general_1608202194
    collector_1      | time="2020-12-17T10:49:54Z" level=info msg="auth: using aws role" region=
    collector_1      | time="2020-12-17T10:49:54Z" level=info msg="auth: using aws role" region=us-east-1
    collector_1      | time="2020-12-17T10:49:54Z" level=info msg="auth: using aws role" region=us-east-1
    collector_1      | time="2020-12-17T10:49:55Z" level=info msg="starting to analyze resource" region=us-east-1 resource=documentDB
    collector_1      | time="2020-12-17T10:49:57Z" level=info msg="starting to analyze resource" region=us-east-1 resource=ec2_volume
    collector_1      | time="2020-12-17T10:49:59Z" level=info msg="analyzing resource" region=us-east-1 resource=kinesis
    collector_1      | time="2020-12-17T10:50:01Z" level=info msg="Amount of streams" streams_count=0

    However, errors similar to the one below can be seen when it tries to perform any pricing action:

    collector_1      | time="2020-12-17T10:50:02Z" level=error msg="could not describe pricing product" error="AccessDeniedException: User: <redacted> is not authorized to perform: pricing:GetProducts\n\tstatus code: 400, request id: e3b83592-f6c8-4a71-a287-a72830d399a7" search_query="{\n  Filters: [{\n      Field: \"productFamily\",\n      Type: \"TERM_MATCH\",\n      Value: \"Kinesis Streams\"\n    },{\n      Field: \"group\",\n      Type: \"TERM_MATCH\",\n      Value: \"Provisioned shard hour\"\n    },{\n      Field: \"location\",\n      Type: \"TERM_MATCH\",\n      Value: \"US East (N. Virginia)\"\n    }],\n  ServiceCode: \"AmazonKinesis\"\n}"
    collector_1      | time="2020-12-17T10:50:02Z" level=error msg="Could not get shard price" error="AccessDeniedException: User: <redacted> is not authorized to perform: pricing:GetProducts\n\tstatus code: 400, request id: e3b83592-f6c8-4a71-a287-a72830d399a7"

    Anything else we need to know?: The errors can be avoided if the AWSPriceListServiceFullAccess policy is attached to the allow-assume-role role instead of the finala-cross-account role. I first discovered this issue when deploying Finala using the Helm chart into an EKS cluster that runs in one of our AWS accounts, and needs to scan a number of other ("remote") accounts.

Environment:

cregev commented 3 years ago

@vytautaskubilius thank you for adding this issue , @kaplanelad and I will take a look at this ... and let you know.