Nike-Inc / gimme-aws-creds

A CLI that utilizes Okta IdP via SAML to acquire temporary AWS credentials
Apache License 2.0
925 stars 263 forks source link

Add optional cookiejar support to reduce password/MFA prompts #342

Open lyoung-confluent opened 2 years ago

lyoung-confluent commented 2 years ago

Description

Introduces an optional persistent cookiejar to store/re-use Okta session cookies between executions of gimme-aws-creds.

This will allow users who have multiple AWS tiles in the same Okta organization, or complex MFA polices in Okta to experience fewer MFA/password prompts.

Related Issue

I didn't find any closely related issues, let me know if you'd like me to open one and focus the discussion on adding this functionality there instead of within a PR.

Motivation and Context

Depending on the organization/application policy configured in Okta a user may only be required to authenticate every \<x> minutes/hours to access okta and/or a specific application tile.

Despite this policy, because gimme-aws-creds creates a new Okta session on each invocation (albeit with the same device token), the user will experience password/MFA prompts on each invocation of the CLI which does not match the behavior they would experience in a web browser accessing AWS.

Implementation Details

To implement the change a custom cookiejar class is added that extends from the existing RequestsCookieJar. This cookie jar uses the stdlib http.cookiejar.LWPCookieJar to serialize/deserialize the cookies (instead of the less secure pickle option).

To avoid potential parallel invocations of gimme-aws-creds overwriting the jar file and corrupting it any writes to the jar are staged in a temporary file in the same directory, then renamed in place (replacing the previous jar) which is an atomic operation within the same filesystem.

The jar is not very well optimized writing a file each time a cookie is created/deleted instead of batching changes but given the limited number of cookies/frequency of changes this seems like a reasonable trade-off for simplicity. Alternatively atexit could be used to flush the jar to disk when the CLI exits instead.

When auth_session is called and a cookie jar exists that contains a sid cookie, a call to /api/v1/users/me is made to check if the session is still valid. If it is, the function returns early otherwise it will fall-through to the previous implementation generating a new session.

I also cleaned up/unified some of the request logic as part of this change:

I will also note there are potential security implications of storing okta sessions on disk without encryption (ex: Chrome uses the system keychain to store an encryption key). However this has little value for a Python CLI since the entire python binary will be allowed access to the key, not a specific script. Additionally this is a similar risk to writing AWS credentials to disk which the tool already does. Given this is a non-default option I think this is a reasonable trade-off.

How Has This Been Tested?

Screenshots (if appropriate):

N/A

Types of changes

Checklist:

lyoung-confluent commented 2 years ago

@bwynsm Can you take a look at this? Do I need to open an Issue tied to the PR to get some 👀 on it?