iann0036 / iamlive

Generate an IAM policy from AWS, Azure, or Google Cloud (GCP) calls using client-side monitoring (CSM) or embedded proxy
MIT License
3.1k stars 107 forks source link

Feature request: Populate `Resource` field #14

Open sveniu opened 3 years ago

sveniu commented 3 years ago

Would it be feasible to populate the Resource field with the appropriate value? An example would be the S3 bucket name and object key for the s3:GetObject action.

A useful side effect here is that it'd be necessary to split the policy into multiple statements, grouped by resource. (Since it is unlikely that resource specifiers are shared between services, you effectively also get grouping by service.)

Motivation: It is often desirable to design a least-privilege policy, where only the necessary resources are allowed. An example would be s3:GetObject, where the bucket and object would be part of the ARN in the Resource specifier. A user would be free to reduce the specificity of the resources after, by replacing suffixes with wildcards, etc.

iann0036 commented 3 years ago

Natively, no - the client-side monitoring events omitted from the AWS SDKs do not include the API calls parameter information and thus I won't be able to determine which resources are being affected.

I am working on some alternatives though. Could you let me know your use case? Would your use case allow for a change in application code to hook into the AWS SDK (effectively proxying the requests) for a temporary amount of time?

sveniu commented 3 years ago

My typical scenario would be creating policies in Terraform, that would be attached to IAM roles, and the roles would either be used by EC2 instance profiles or ECS Fargate task roles. These policies would typically be for granting ECR access (where the resource would be an image repository ARN), AWS Secrets Manager access (where the resource would be a secret name or path, often with wildcards), and often a mix of S3 and DynamoDB access, where buckets, object keys, and table names would be the typical resource specifiers.

In the past, designing such policies has usually been a circle of 1) guessing what's needed; 2) trying aws cli commands that kinda do the same thing; 3) observing cloudtrail logs to see which actions and resources were involved; 4) applying the policy; 5) trying the policy in real life; 6) getting some more or less (often less!) useful error message about permissions; 7) repeat from (1). On a side note, I think it's rather telling that most of AWS' own policy examples give really coarse, wide-open policies, rather than trying to be at least a little bit restrictive. Says something about the difficulty of IAM policy design, IMO.

So while I don't have an imminent use case, the feature request was mostly borne out of previous frustration.

iann0036 commented 3 years ago

Thanks for the context, it's very helpful!

used by EC2 instance profiles or ECS Fargate task roles

What's the underlying application type that would be actually calling the API endpoints (e.g. CLI, JS SDK, Python SDK)? If it's code, is it code that you typically would have access to? (DM me if that info is sensitive)

I think it's rather telling that most of AWS' own policy examples give really coarse, wide-open policies, rather than trying to be at least a little bit restrictive

I agree immensely, hence the work on this and related work currently in-flight.

iann0036 commented 3 years ago

Quick update; I'm now working on an alternative to allow population of the Resource field. Stay tuned.

Isan-Rivkin commented 3 years ago

@iann0036 Hi there, awesome tool! Just curious how this feature would look like? :) This is the missing thing that we need!

jeffmachado commented 3 years ago

Awsomeeeee Iann... Congrats.

Thats obvious, you're a real AW community hero!

Waiting for that feature tho.

iann0036 commented 3 years ago

Hi all,

This feature is now available with the new "proxy" mode. See the README for more info.

kernwig commented 3 years ago

Proxy mode fails with error self signed certificate in certificate chain

iann0036 commented 3 years ago

Hey @kernwig,

It sounds like either the --set-ini option wasn't provided, or a non-default profile was used, or the SDK wasn't aware of the CA bundle.

In all those cases, adding the below should solve your issue:

export AWS_CA_BUNDLE=~/.iamlive/ca.pem
ossie-git commented 3 years ago

I ran into an issue using Proxy Mode. I would run it as follows:

./iamlive --set-ini --mode proxy

and in my boto3 script, I had two boto3 calls. The first works fine and looks like this:

metadata = s3client.head_object(Bucket=BUCKET_NAME, Key=OBJECT_NAME)

but this next line:

s3client.download_file(BUCKET_NAME, OBJECT_NAME, FILE_NAME)

would throw the following error:

Traceback (most recent call last):
  File "go.py", line 53, in <module>
    main()
  File "go.py", line 47, in main
    check_and_download()
  File "go.py", line 36, in check_and_download
    s3client.download_file(BUCKET_NAME, OBJECT_NAME, FILE_NAME)
  File "/home/ubuntu/Development/Python/Projects/s3downloader/venv/lib/python3.6/site-packages/boto3/s3/inject.py", line 172, in download_file
    extra_args=ExtraArgs, callback=Callback)
  File "/home/ubuntu/Development/Python/Projects/s3downloader/venv/lib/python3.6/site-packages/boto3/s3/transfer.py", line 307, in download_file
    future.result()
  File "/home/ubuntu/Development/Python/Projects/s3downloader/venv/lib/python3.6/site-packages/s3transfer/futures.py", line 106, in result
    return self._coordinator.result()
  File "/home/ubuntu/Development/Python/Projects/s3downloader/venv/lib/python3.6/site-packages/s3transfer/futures.py", line 265, in result
    raise self._exception
  File "/home/ubuntu/Development/Python/Projects/s3downloader/venv/lib/python3.6/site-packages/s3transfer/tasks.py", line 255, in _main
    self._submit(transfer_future=transfer_future, **kwargs)
  File "/home/ubuntu/Development/Python/Projects/s3downloader/venv/lib/python3.6/site-packages/s3transfer/download.py", line 346, in _submit
    response['ContentLength'])
KeyError: 'ContentLength'

I've set all 3 of the following as mentioned in the documentation:

export HTTP_PROXY=http://127.0.0.1:10080
export HTTPS_PROXY=http://127.0.0.1:10080
export AWS_CA_BUNDLE=~/.iamlive/ca.pem

Once I remove them, the boto3 calls works as expected. Any ideas? Thanks.

iann0036 commented 3 years ago

Thanks @ossie-git,

I'm able to replicate your issue, and see that it occurs the moment the request comes through the proxy, indicating an issue with that library.

Looks like this may take some time to investigate, but I'll get back to you when I have something.

iann0036 commented 3 years ago

Hey @ossie-git,

I've made an adjustment to the codebase for the proxy to better handle HEAD requests, which should fix your issue. Upgrade to v0.25.0 to test your fix.

ossie-git commented 3 years ago

@iann0036 A quick test shows that it now works 👍 I'll try to do some more testing for other use cases. Thanks.

PS. The problem wasn't in the HEAD request but in the actual download

ossie-git commented 3 years ago

Not sure why, but this command:

$ aws elb describe-load-balancers

works but shows no output when running iamlive in proxy mode but works + shows the following when running it in non-proxy mode (iamlive --set-ini):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "elasticloadbalancing:DescribeLoadBalancers"
            ],
            "Resource": "*"
        }
    ]
}

So it looks like proxy mode is not detecting it for some reason

iann0036 commented 3 years ago

Thanks @ossie-git,

Thanks for letting me know! Turns out ELB is a special exception to the service naming process which wasn't picked up previously.

https://github.com/aws/aws-sdk-js/blob/54f8555bd94d33a1754a44a35286f1d9e31c28a3/lib/model/api.js#L46

I've hopefully fixed the ELB issue in v0.26.0.