Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v2] credentials supplied by aws sso login do not conform to AWS standards #4982

Closed
dayer4b opened this issue Feb 19, 2020 · 33 comments
Closed
Labels
feature-request A feature should be added or improved. sso v2

Comments

@dayer4b
Copy link

dayer4b commented Feb 19, 2020

AWS documents that credentials generated by aws configure are stored in the standard path ~/.aws/credentials:

The AWS CLI stores the credentials that you specify with aws configure in a local file named credentials, in a folder named .aws in your home directory.

https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html

This path is not utilized by credentials stored by aws configure sso or aws sso login.

Other tools (like Terraform and Boto3) that rely on this standard do not function because they do not see the credentials stored in the ~/.aws/cli/cache/ JSON files.

Shared credential file (~/.aws/credentials)

https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html

@dayer4b
Copy link
Author

dayer4b commented Feb 19, 2020

For my own purposes, I am working around this issue by extracting the data from the JSON object and dumping it into the ~/.aws/credentials file as such:

#!/bin/bash

JSON_BASEPATH="${HOME}/.aws/cli/cache"
AWS_CREDENTIALS_PATH="${HOME}/.aws/credentials"

if [ -f ${AWS_CREDENTIALS_PATH} ]; then
        echo "backing up existing credentials"
	cp -rf ${AWS_CREDENTIALS_PATH} "${AWS_CREDENTIALS_PATH}-"$(date +"%s")
fi

# find the latest CLI JSON file

json_file=$(ls -tr "${JSON_BASEPATH}" | tail -n1)

# use jq to dump stuff in the right place

aws_access_key_id=$(cat ${JSON_BASEPATH}/${json_file} | jq -r '.Credentials.AccessKeyId')
aws_secret_access_key=$(cat ${JSON_BASEPATH}/${json_file} | jq -r '.Credentials.SecretAccessKey')
aws_session_token=$(cat ${JSON_BASEPATH}/${json_file} | jq -r '.Credentials.SessionToken')


echo "[default]" > ${AWS_CREDENTIALS_PATH}

echo "aws_access_key_id = ${aws_access_key_id}" >> ${AWS_CREDENTIALS_PATH}
echo "aws_secret_access_key = ${aws_secret_access_key}" >> ${AWS_CREDENTIALS_PATH}
echo "aws_session_token = ${aws_session_token}" >> ${AWS_CREDENTIALS_PATH}

I hope this helps others until a fix is ready!

@KaibaLopez KaibaLopez self-assigned this Feb 21, 2020
@KaibaLopez
Copy link
Contributor

Hi @dayer4b ,
To make sure I understand the problem here,
you've ran the configure sso command and logged in and are able to use the various services with the generated temporary credentials right?

aws sso login --profile my-sso-profile
aws s3 ls --profile my-sso-profile

this kind of call works for you, but when running through another sdk, it is not recognizing the credentials. Am I understanding correctly?

@KaibaLopez KaibaLopez added response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. closing-soon This issue will automatically close in 4 days unless further comments are made. and removed response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. labels Feb 22, 2020
@heikkis
Copy link

heikkis commented Mar 5, 2020

@KaibaLopez that is the current best solutions I think we agree. Those STS creds are valid only for an hour so you have to generate those quite often.

This is not a good solutions. SSO does not always create new cache json files so you actually need to clear cache folder beforehand to be sure that the newest file is created by AWS cli.

@KaibaLopez
Copy link
Contributor

I think I'm missing something here, but this is not really a problem on the CLI, unless it is not working for you for cli actions either it'd be a problem with how you're getting credentials on the other sdks. You're right that you shouldn't need to move them manually, but each sdk has it's own way of retrieving credentials when it comes to sso logins, make sure that you're doing it correctly, it might need extra configuration.

Also, not sure if this was part of the problem but sso is meant to be temporary so not sure I can offer you a solution there.
Again let me know if I missed something here or you don't agree with my response, I do feel like I'm not getting the full picture...

@KaibaLopez KaibaLopez added response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. and removed closing-soon This issue will automatically close in 4 days unless further comments are made. labels Mar 5, 2020
@heikkis
Copy link

heikkis commented Mar 6, 2020

I think you are correct in away. I think that it would be nice that cli would provide supported way for SSO STS creds like you can get those from the portal. Now this "hook" is way too complex and error brone.

Support could be very similar to STS lookup with MFA code.

@rossmckelvie
Copy link

I think the problem OP is describing is really a feature request for the aws terraform provider. I found a feature request over on the provider repo related to supporting SSO credentials: hashicorp/terraform-provider-aws#10851

@lorengordon
Copy link
Contributor

Doing this on a utility-by-utility or sdk-by-sdk basis will make for an absolutely horrid developer and user experience.

The SDKs all support the AWS Shared Config file in some way. The SSO auth/cred process should also integrate through the AWS Shared Config so all SDKs and all utilities are able to leverage it the same way.

@KaibaLopez
Copy link
Contributor

@lorengordon
Yes,and we are trying to unify the sdk's behaviors, but I think you misunderstood what I meant there, it's not as bad as that.
It's more on the default credentials provider chain, I'm not familiar with how terraform does theirs, but they should have a way to read the credentials from the same place as the cli, it just may not be the default, that's what I meant by extra steps, not that you'd need to modify the code but that you'd need a different method call.
All this being said, I'd recommend checking those sdk's documentation or opening an issue on their repos regarding this, it still sounds to me like there is no problem with the CLI's implementation.

@lorengordon
Copy link
Contributor

@KaibaLopez Ok, gotcha. I use terraform a lot and have also helped review/expand the credential handling to better work with the features of the AWS Shared Config. It will indeed leverage the SDK credential chain properly. The only known real issue currently is that IF you are using the AWS_PROFILE env and that profile uses certain features from the AWS Shared Config file, then you must export AWS_SDK_LOAD_CONFIG=1. That's kind of a thing in the aws-sdk-go for enabling resolution for the AWS Shared Config.

Far as I can tell, I don't think there is truly a terraform issue here.

@taingalls
Copy link

I would have to say I am experiencing the same "issue" as the OP.

I am using boto3 and it is expecting the AWS CLI V1 shared credentials file in INI format. https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html

As for a feature request I think it would be helpful to be able to choose if you also want the temporary credentials stored in a "legacy" format.

I am currently seeing if I can make a wrapper script similar to the OP that exports the access key, secret key, and session token.

@sgtoj
Copy link

sgtoj commented Apr 12, 2020

I have created and shared a script to simplify updating ~/.aws/credentials for AWS SSO users. It will update the AWS credentials file by adding/updating the specified profile credentials using the AWS CLI v2 cached SSO login.

@github-actions github-actions bot removed the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label May 6, 2020
@benkehoe
Copy link

benkehoe commented May 27, 2020

I pulled the SSO credential support from botocore v2 and the CLI into a credential_process helper, so by adding one line to your SSO-configured profile in .aws/config, it'll work with any SDK that supports credential_process (or any tool that uses one of those SDKs, like Terraform): aws-sso-credential-process.

@flyinprogrammer has written a similar thing in go that's a little less full-featured, but has the advantage of being a single executable: aws-sso-fetcher

@victorskl
Copy link

Well, come here for some quick ready made solution. Ended up writing one, yawsso -- which I extend @sgtoj work, without depending on anything except CLI v2 itself, to sync up CLI v2 SSO login session to v1 credentials file.

pip install yawsso
aws configure sso
aws sso login --profile=dev
yawsso -p dev

@dayer4b
Copy link
Author

dayer4b commented Jun 5, 2020

Sorry I didn't reply to these messages sooner, but I think most of the commenters here are understanding that pain that I have described. My concern with the proposed solution is that it effectively breaks the document contract that the AWS CLI has established and fostered for years.

This is particularly problematic with boto3 as this is literally managed by Amazon. I pointed to boto3 and terraform because these are very commonly used and one of them is managed by Amazon.

In the meantime, I have entirely given up any attempt at using aws configure from the command line, instead I have been manually copying credentials from the SSO web page and placing them somewhere that command line tools understand.

@victorskl I look forward to trying out your tool!

@FernandoMiguel
Copy link

Sorry I didn't reply to these messages sooner, but I think most of the commenters here are understanding that pain that I have described. My concern with the proposed solution is that it effectively breaks the document contract that the AWS CLI has established and fostered for years.

This is particularly problematic with boto3 as this is literally managed by Amazon. I pointed to boto3 and terraform because these are very commonly used and one of them is managed by Amazon.

In the meantime, I have entirely given up any attempt at using aws configure from the command line, instead I have been manually copying credentials from the SSO web page and placing them somewhere that command line tools understand.

@victorskl I look forward to trying out your tool!

I've moved (back) to aws-vault https://github.com/99designs/aws-vault/blob/master/USAGE.md#aws-single-sign-on-aws-sso
it covers all my needs, and is far more secure than aws cli leaving creds in clear text on disk

@rossmckelvie
Copy link

Note for aws-vault you need to get a v6 pre-release binary to use the SSO functionality. This is what has allowed us to roll out SSO to our org's backend developers

@ryansonshine
Copy link
Contributor

ryansonshine commented Jul 28, 2020

For anyone looking for a node version of this type of script I've published this one to npm https://github.com/ryansonshine/aws-sso-creds-helper

@kdaily kdaily added feature-request A feature should be added or improved. v2 sso labels Sep 23, 2020
@arvindkgs
Copy link

For folks still needing backward compatibility to ~/.aws/credentials file, I have created a script to automate the web flow of 'aws sso login', so you do not need to switch to the browser for SSO authentication, update the ~/.aws/credentials and inject env params AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN into current terminal.

https://github.com/arvindkgs/aws_sso_login

@benkehoe
Copy link

Please note that @arvindkgs's tool requires you to put your password in an environment variable or in your shell history, both of which are run against recommended practice. The process of using your browser to sign in is a security feature of AWS SSO login, not a bug. It also only appears to work with Okta, and I see no support for MFA.

@arvindkgs
Copy link

arvindkgs commented Feb 25, 2021

@benkehoe I built this for developers who don't want to shift focus from their cmd line. While this is a feature of SSO it is distracting for me. Yes, it is only for OKTA now. I added to environment because some tools require creds in the environment. I will add a switch to make this optional. I have explored other tools like https://github.com/Noovolari/leapp and https://github.com/linaro-its/aws2-wrap and found them lacking.

@dazhanghalo
Copy link

Any traction on this? I would love to be able to give my developers an sso user to authenticate against AWS while using the sdk rather than have to have them manually go and download the credentials from the login screen each time.

@zstyblik
Copy link

@dazhanghalo what's wrong with aws-vault?

@olenm
Copy link

olenm commented Aug 4, 2021

aws-vault is a band-aid to the real problem.
The json generated via aws-cli/botocore using a sha1 for its json-names (based on account-id,role/set-permission,start-url) is not great - I'm in favor of calling things for what they are - this currently feels like security by obfuscation and really buys us nothing but a headache. I am hoping this gets addressed soon, as well - the file names should really reflect the profile-name and be ini formatted making them both predictable and usable for other apps that already utilize the ini standard.

@kdaily
Copy link
Member

kdaily commented Aug 6, 2021

Hi all, I appreciate your continued conversation on this, and I'd like to clarify and update.

It seems like the biggest pain point underlying this issue is that all AWS SDKs did not support using the credential provider that is configured via aws configure sso. As of now, all AWS SDKs except C++ support the credentials from SSO login.

@dazhanghalo - what language are your developers using? Hopefully they are covered now by my above statement.

To clarify a bit of @dayer4b's concerns about the contract or standard set by the AWS SDK credential configuration:

The AWS CLI stores the credentials that you specify with aws configure in a local file named credentials, in a folder named .aws in your home directory.

This is still true - if you supply credentials to aws configure they are stored in the file (directly setting your access id, secret key, and token). However, aws configure sso does not store credentials, only configuration for the SSO portal that you will use. So the statement still holds, although I can agree that the distinction is nuanced. Is there clarification in the documentation that could make this more clear?

There are authentication methods besides SSO that also do not store them in the credentials file, and should not because of their transient nature. Assume role credentials are not written to the credential file, nor are those that are pulled from IMDS, or a custom credential provider. Writing them to the credential file would not work as the file is currently read once when a session is created (for example in Python), so if the credentials were refreshed after expiring they would be broken.

@olenm - I'm not sure I understand the issue here. There is no intention to use SHA1 as a security method, only as a way to ensure that the resulting name of the file is compatible with the storage (e.g., not having a filename that might be too long when combining things like you mentioned).

One thing I hear from this is the need to still get out the current set of credentials that a profile would be using, regardless if they come from SSO, an assume role, or even are configured in the credential file itself. This open issue (#5261) proposes that specifically for SSO in response to the lack of support for SSO, but it seems to have further value to those who need the credentials in a predictable format for other uses

Many of you have written tools to do this (@benkehoe, @flyinprogrammer, @ryansonshine, @victorskl, and probably others). For users who already have the AWS CLI installed to perform the SSO login, it would be a win to also use the same tool to interrogate what credentials are in use and export them if needed. This looks like feature that the AWS CLI team can support and review for implementing.

@kdaily kdaily added the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Aug 6, 2021
@olenm
Copy link

olenm commented Aug 6, 2021

Thanks @kdaily !

Re the sha1 as a file-name - I am glad to hear it is not an attempt at a security measure; however I think that file name length as a consideration in terms of it potentially reflecting the profile-name should be reconsidered as it is already reaching some 40 characters. Anybody with so many profiles that utilize that many combinations on a single system is in trouble in another way if you ask me. Though personally even with long account+role name combinations in my own profile list, I can easily see 60+ chars - but really the problem comes if people are using paragraphs to identify profiles, if that is the case, I do feel sorry for when they have to use aws --profile myLongProfileNameThatIs200charactersLooooooooooong

The fact that people need to utilize other apps/wrappers/scripts to simply correlate a profile to a credential set is a problem (myself included).

Getting a printout of credentials from the CLI would be very helpful to a degree, but programs like Terraform which already utilize reading the ini file format and utilize profiles could easily benefit from a profile-named-ini - especially since the cache folder path does not change. Even still, I think there are some oddities in the behavior of the creation of the json - as in, it gets created not on login, but after the first call afterward (I personally call aws --profile bla sts get-caller-identity for the file to create, then generate the my ini) - and upon further use, notice that the json gets removed far before it expires, if multiple start-urls are logged into at once. So I can only ask for some predicable file locations based on profile-name alone, and that the files do not get removed pre-expiration.

@github-actions github-actions bot removed the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Aug 6, 2021
@arvindkgs
Copy link

arvindkgs commented Aug 26, 2021

Please note that @arvindkgs's tool requires you to put your password in an environment variable or in your shell history, both of which are run against recommended practice. The process of using your browser to sign in is a security feature of AWS SSO login, not a bug. It also only appears to work with Okta, and I see no support for MFA.

I have made modifications to my script that no longer needs credentials as environment variables and have been using it for 4 months now without issues.

  • I have abandoned trying to automate the web login using selenium, rather now you would need to run aws sso login before running the script.
  • The script sets credentials from ~/.aws/cli/cache into ~/.aws/credentials and also sets environment variables AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN in your shell

@robvanderleek
Copy link

robvanderleek commented Aug 29, 2021

FWIW, I created a small Python 3 wrapper (no external libraries required) around aws sso login that also updates .aws/credentials: https://gist.github.com/robvanderleek/7dd54a53ce72e835ac1f319ef2631c5e

@dayer4b
Copy link
Author

dayer4b commented Sep 4, 2021

@robvanderleek thanks so much! It is contributions like this that make me think that this feature is still broken. That there are commonly required and readily available solutions to fix the implementation suggests that the implementation is faulty, or perhaps doesn't go far enough in bridging towards backwards compatibility.

@m4dc4p
Copy link

m4dc4p commented Oct 5, 2021

Please, please fix this. Makes transitioning to aws sso extremely painful. That command needs to update ~/.aws/credentials.

@kdaily
Copy link
Member

kdaily commented Oct 8, 2021

Thanks again for the input. I'm going to close this issue, as we've outlined above the reasons why temporary credentials (including those from SSO) will not (and should not) be saved in the credentials file.

Nearly all AWS SDKs now automatically support this configuration, so other tools to get this functionality should no longer be required. Downstream tools (like Terraform) also support credential_process, as suggested by @benkehoe's comment. As a last resort, a credential exporter (#5261) can fill the remaining gaps in support.

@kdaily kdaily closed this as completed Oct 8, 2021
@github-actions
Copy link

github-actions bot commented Oct 8, 2021

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.

@m4dc4p
Copy link

m4dc4p commented Oct 8, 2021

Breaks my process. Thanks a lot.

@benkehoe
Copy link

benkehoe commented Oct 9, 2021

To echo @kdaily's comment, I've written an article on how the "AWS standard" for credentials is more comprehensive than just ~/.aws/credentials, and why credential_process is better than stuffing temporary credentials into ~/.aws/credentials or environment variables: https://medium.com/@ben11kehoe/never-put-aws-temporary-credentials-in-env-vars-or-credentials-files-theres-a-better-way-25ec45b4d73e

When using the configuration functionality of aws-sso-util (which can automatically create profiles for every account and role you have access to through AWS SSO), it automatically sets credential_process alongside the AWS SSO configuration to backfill for tools that don't yet support AWS SSO configuration. For tools that don't even support credential_process, there's aws-export-credentials as a last resort.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request A feature should be added or improved. sso v2
Projects
None yet
Development

No branches or pull requests