cevoaustralia / aws-google-auth

Provides AWS STS credentials based on Google Apps SAML SSO auth (what a jumble!)
MIT License
538 stars 180 forks source link

Feature: Renewing STS credentials without prompting for password again. #26

Open FrederikNJS opened 6 years ago

FrederikNJS commented 6 years ago

I have been trying out this command-line tool to move our AWS Users over to SAML, including their CLI usage. Unfortunately you always need to sign-in again after 1 hour. Some of our users run processes which take more than an hour to complete and need AWS access throughout the process.

AWS allows SAML users to stay signed in for up to 12 hours. Amazon STS still only allows the generated keys to last for up to 1 hour.

I would love if this command-line tool would allow me to stay signed in, such that I don't have to re-enter my password every hour.

I have two ideas for how to achieve this:

  1. Introduce a command-line switch such as --auto, which keeps the script running, remembering the user password in memory, and automatically re-authenticating when the time is about to run out.
  2. Grab the cookie which contains the token, and write it to the ~/.aws/config file, and when running the command again, check if the token is still valid, and generate a new STS credential.

The two tactics might even be complementary, such that the --auto parameter makes the script wait until the credentials are about to expire, and then re-authenticates using the token in step 2.

I have not looked deeply into the options for solving this, but I might be able to create a Pull Request, I would just like to know what method would be preferred.

mide commented 6 years ago

I personally feel that keeping the user's password in memory could be a dangerous solution - If the user left for the day without closing the application, their computer would effectively always have an active STS token. I feel part of what makes STS special is that they are short lived (even if they're 12 hours).

I think --auto would be fine if it just cached the SAML assertion, and used it to renew the STS tokens. (This would be a mix of both your solutions). That way, at the end of 12 hours, the assertion would expire and it would force the user to re-enter their password. Edit: No, that wouldn't work if you have 2FA turned on.

I started working on a SAML assertion caching PR, but I've got a few others in flight (#34, #33, #29) that I want to get in before I get too far with this one.

nonspecialist commented 6 years ago

The SAML assertion caching is a preferred way of achieving this; the simplest thing to do would be to just save it to disk ... something like ~/.aws/assertions/<escaped-role-arn>.xml

Then, checking whether there's an existing assertion, loading it, verifying the expiry time and either re-using it to refresh the credentials or prompting the user to renew should be fairly straightforward.

mide commented 6 years ago

Yep; I've got a PR in the making. Just working out some minor issues and then tests.

mide commented 6 years ago

I think we should store the SAML assertion in the file ~/.aws/saml-assertion.xml, since one SAML assertion can be valid for multiple ARNs. Likewise, we don't want to store in a given profile, since the SAML assertion could be used in any profile.

mide commented 6 years ago

PR #47 takes a whack at this.

mide commented 6 years ago

FWIW, the --auto flag is just part of the workflow proposed in #47. When using aws-google-auth, it will try to use the SAML cache first, and if invalid will prompt the user for credentials. I figure most people will want to use SAML caching by default.

There is also a --no-cache flag to force a full credential prompt.

mide commented 6 years ago

I propose #47 addressed this issue.

max-rocket-internet commented 6 years ago

How exactly is this supposed to work?

aws-google-auth -u my-email@domain.com -S 99999999 -I XXXXX --ask-role --disable-u2f --duration 3600
Failed to import U2F libraries, U2F login unavailable. Other methods can still continue.
Google Password:
Open the Google App, and tap 'Yes' on the prompt to sign in ...
[  1] arn:aws:iam::9999999:role/sso/sso-xxxxx
[  2] arn:aws:iam::99999999:role/sso/sso-xxxxx
Type the number (1 - 2) of the role to assume: 1
Assuming arn:aws:iam::999999999:role/sso/sso-xxxxx
Credentials Expiration: 2018-01-31 17:07:49+01:00

But then I have no interesting files in ~/.aws:

$ ll ~/.aws/
total 16
-rw-------  1 max.williams  staff   509 Jan 31 16:12 config
-rw-------  1 max.williams  staff  1246 Jan 31 16:12 credentials
-rw-------  1 max.williams  staff     0 Jan 31 16:12 saml_cache.xml

Note that saml_cache.xml size is 0.

If this is working, we should be able to renew STS token without Google password and 2FA for 12 hours, is that correct?

mide commented 6 years ago

That's interesting. saml_cache.xml should have some contents. I wonder why that's not getting written. That's likely the issue.

Otherwise, you're mostly correct - if everything works, you'll be able to renew the STS token without being asked for Google Password / 2FA for five minutes; See https://github.com/cevoaustralia/aws-google-auth/pull/47#issuecomment-359457783.

FrederikNJS commented 6 years ago

@mide I'm seeing the same issues as @max-rocket-internet. I get authenticated, but when I run the script again, I get prompted for a password and 2FA. The saml_cache.xml file is empty.

I'm running version 0.0.19.

mide commented 6 years ago

Interesting; thanks for the info. I'll take a look when I get a chance.

FrederikNJS commented 6 years ago

So now that SAML caching works, and I have also successfully had 12 hour STS credentials generated, I don't really feel this issue is a problem anymore. I can now sign in with just my password once a day, which is perfectly fine.

I'm content with closing this issue unless anyone else has additional needs.