okta / okta-aws-cli

A CLI for having Okta as the IdP for AWS CLI operations
https://github.com/okta/okta-aws-cli
Other
128 stars 34 forks source link

Cache access token for improved user experience #74

Closed cvchavez2 closed 1 year ago

cvchavez2 commented 1 year ago

Each time a user runs a CLI command they are required to verify a device code via the browser. This translates to a very poor experience when a user is assigned to multiple AWS accounts/multiple roles, due to the user having to verify a new device code each time they need to move accounts or roles. 

Desired Behavior:

Cache/store the OIDC access token from the native application and reuse it each time a user needs to switch between AWS accounts/roles. Potentially this could be achieved via:

  1. After an access token has been issued, from the first okta-aws-cli command, cache/store the access token.
  2. Each subsequent command, check to see if a token is available to use.
    • Verify the access token is still valid via the exp date on the JWT.
    • if token is valid, continue without prompting user to verify user code in the browser.
  3. If the token is invalid, prompt user to verify user code to retrieve a new device token via the browser. 

Also, I noticed that the expiration time of an access token is set to 300s even though in my access policy I have specified a longer lifetime. Not sure where the 300 is coming from.

access-token

monde commented 1 year ago

This sounds good to me, I'll have to look if I can improve the user experience with regards to this.

monde commented 1 year ago

@jefftaylor-okta I was talking about this with DZ in Slack. Currently, the access token (the device grant) is not a one time token. We could use it multiple times to generate new web sso tokens. (Making it one time use might be a thing VM has an opinion about). So, if I'm going to keep an Okta access token resident where should I store that?

In Env Var mode as an Env Var like OKTA_ACCESS_TOKEN and OKTA_ACCESS_TOKEN_EXPIRY. In AWS creds INI file format, something like

[okta]
x_okta_access_token = abc
x_okta_access_token_expiry = 123

Maybe drop it in a temporary file? I know how to do this in *nix, not sure of Windows has equivalent temporary files.

Then, on subsequent runs of okta-aws-cli I can check if there is a current Access Token instead of bumping the operator out to the browser for a new device grant. This seems like an awesome v1.0.0 feature.

monde commented 1 year ago

@cvchavez2 I see you are working on caching the access token https://github.com/okta/okta-jwt-verifier-golang/issues/86#issuecomment-1472238190

I confirmed with the PM of the feature team that owns that endpoint that the access token can be used multiple times (that it is not single use). @jefftaylor-okta is the PM for okta-aws-cli . We are still deciding how we'd want to implement this feature.

Keep in mind with okta-aws-cli we are focusing on industry best practices and making a tool that enhances the capabilities of Okta Identity Engine and the OIN AWS Federation App. We not writing a tool to replace other community projects.

Just pointing out that persisting a token to disk, even if it has an expiry, is not considered a best practice.

cvchavez2 commented 1 year ago

@monde Im looking forward to see how you guys implement that feature as I agree with the fact that persisting a token to disk is not good practice. We are also exploring an alternative. Will provide an update later :)

monde commented 1 year ago

I forgot to mention good idea @cvchavez2 on using the JWT verifier to verify before re-use of the access token. If we have to update the verifier to better support okta-aws-cli we can make time for that. Sad panda keeps coming to mind any time I think $HOME/.oktaawsclirc, $HOME/.okta/okta-aws-cli-rc, etc., might be laughing at our intentions of not implementing it.

cvchavez2 commented 1 year ago

Hey @monde, you guys put the tools out there, we just got to use them.

I just cant think of a way how the jwtverifier can verify an access token that it is coming from an org auth server if there are any public keys available to verify it with. I know you have seen this. It will be pretty cool if there is a way to do it though.

What do you think about verifying the ID token instead of the Access token since this is currently possible? If the ID token is not valid, more than likely the Access token is not going to be valid since both expire in 1 hour. If that is the case, prompt the user to verify device code again in order to get a fresh set of tokens.

If it is valid then proceed without prompting user to verify device code.

Either way you cant get far if you dont check the access token and it turns is not valid since it will be put to test in listFedApps function.

cvchavez2 commented 1 year ago

Btw, now that I remember there is a bug in the listFedApps resp, err := s.config.HTTPClient.Do(req) if resp.StatusCode == http.StatusForbidden { return nil, err } If a 403 comes back, err will be null. Therefore, upstream code will think that there is no problem and in line 183 a misleading error will be thrown. It will be nice to also check for 401s since that is what comes back when an access token is not valid :)