cloudyr / aws.iam

AWS IAM Client Package

Home Page:https://cran.r-project.org/package=aws.iam

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support for Assume Role Provider

davidski opened this issue · comments

Not sure if this belongs here or under aws.signature.

Following up on this Twitter thread - https://twitter.com/dseverski/status/1233162504076976129, for consideration if someone is able to adopt the cloudyr aws suite. It would be wonderful to create support for the Assume Role Provider functionality present in boto3/botocore and documented at https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html. Specifically, I'm looking to find support to read and honor the source_profile, mfa_serial, and credential_process parameters. With these three, cloudyr/aws could be used to transparently assume a role where credentials are not stored on disk in plaintext, but instead are retrieved via secure storage with a program such as aws-vault, assuming a role with temporary credentials.

This is a complicated request, but is currently a missing feature in all of the R AWS packages and would be a tremendous add.

@davidski I'm not sure I understand the request. The way I understand it this is already supported in aws.iam - you just use set_credentials with the provider creds and the call assume_role. The link you mention has many things including assume role with web identity which we don't currently support but is trivial to add. I'd be happy to add what you request, but I need more information on what you need - referencing another implementation (like boto) doesn't help as we're not providing boto bindings.

Hi, Simon. Thanks for the dialog!

As far as I understand (and my testing seems to verify) the cloudyr suite doesn't support chained profiles with external credential processes, in contrast to boto, Go, and other AWS interfaces. In those versions, I can have an .aws/config with the following sample configuration:

[profile work]
region = us-east-2
mfa_serial = arn:aws:iam::ACCOUNT_ID:mfa/USER
credential_process = aws-vault exec --json work --prompt=osascript

[profile work-admin]
source_profile = work
role_arn = arn:aws:iam::ACCOUNT_ID:role/ROLENAME

With this configuration and a boto/Go AWS SDK-based tool, I can set my profile (usually via an explicit call, but also via an envvar) to work-admin and the SDK will find the work-admin profile from my config file and automatically assume the role specified via role_arn after first getting a set of credentials via the credential_process in the work profile. I don't have to have any AWS_* environment variables specified when using the above setup.

This is extremely helpful as I never have to set explicit accesskey, secretkey, and/or sessiontokens in my code, allowing secrets to be completely independent of my codebase. At the moment, I've not found any way out of the chicken-and-egg problem of having to pass an initial set of credentials to my R code. While there are various secrets management tools available for R, they'd all be something I'd have to setup just to manage AWS creds for R processes and would be one-offs while all of my other tooling "just works." 😉

Happy to go into more/different detail if that helps at all!

I think what you are describing is already supported. If I understand you correctly, this is what you are doing:

set_credentials(locate_credentials(profile="work"))
assume_role("arn:aws:iam::ACCOUNT_ID:role/ROLENAME", "session", use=TRUE)

Is that correct?

I wish, but it doesn't look like it. ☹️

I neglected to be specific that while I have an ~/.aws/config as I detailed above, I do not (nor do any of my colleagues) have any ~/.aws/credentials configured. If I perform locate_credentials(profile="work") on that profile without a credentials file, I get back

$key
[1] "work"

$secret
NULL

$session_token
NULL

$region
[1] "us-east-1"

Wrapping that in set_credentials(), I confirm that all of the various AWS_* environment variables remain unset in my local session. Even if that had worked -- which would be terrific -- it would still be not quite as good an experience as those pesky boto/Go versions I keep referring to, as that would still require a manual call to assume_role() (with the hard coded role ARN with that annoying account_id). I really want the R experience to be as good as the python/go experience where I can just call a profile by name, and have credentials retrieved from an external process, the proper role IDed & then assumed without user intervention.

Ah, ok, sorry, then you should file this with aws.signature since all the underlying support in aws.iam is there, but aws.signature supports only a subset of the configuration directives. Looking at it, it seems it dosn't even support credential_process (which actually wouldn't be hard).

That said, getting a bit off topic, I was actually thinking of factoring that functionality out of aws.signature since that package could just provide the (already quite complex) signature handling and have either a separate package for the credentials or fold it into aws.iam since we are already implementing things like the credentials stack. I had to even include a bad hack to make both packages work together as they don't even agree on basic data structures (7f1e4d1). Another benefit of that would be that we could change the behavior to make it more consistent with other AWS clients so legacy code could still use the aws.signature::locate_credentials() without breaking, but we could provide new API that would be used by the packages themselves. But that's just brainstorming for now.

Can do! Do you have access to the aws.signature repo and therefore the ability to move the issue or should I create an item from scratch over there?

I have opened cloudyr/aws.signature#53 for this and would like to help with this ASAP.

Ok, thanks, I'll close this and we can file things like support for credential_process, common credentials handling stack etc. separately.