Quick AWS Console Login

There are two ways to interact with AWS. The first is the AWS Console which requires a username and password plus according to best practices Multi-Factor Authentication (MFA). MFA is great because usernames and passwords that are easy for humans to remember are often easy for machines to crack. The second is API based access either from the AWS CLI or applications using access key and secret access key, stored in the home directory in the .aws/credentials file. I often use the AWS Console as a simple verification that an application works as expected and I have enabled MFA in my accounts. Starting the AWS Console first involves bringing up a browser, going to the URL, typing in my username and password. I then dig out my phone, stare at it while FaceId scans me, open the Duo app, and select the account to display the code. I switch back to the computer and type the code into the browser. Phew! Wouldn’t it be nice if you could get a quick AWS console login using the access key and secret access key and bypassing MFA?

NOTE: MFA can also be used in two ways within AWS. First, the AWS Console can be protected by MFA. Second, IAM policies can require MFA. The approach shown below doesn’t bypass MFA if it is required by an IAM policy, it will only bypass MFA for AWS Console access.

Quick AWS Console Login

AWS provide a mechanism that allows Enterprises to build their own authentication mechanism which allows console logins. Leveraging this mechanism allows automatic login to the AWS console login without enforcing the MFA requirements.

I’ve been learning Golang (or just Go) and decided to write the program in Go. The first few lines setup the program with all the packages it needs (line 3), and declares some constants (on line 18):

Next, we declare a struct to store the results of parsing the JSON response from one of the AWS web services. See way down on line 122.

We then (on line 26) declare the main entry point for the program, declare some variables we’ll use later (line 28), declare our command line parameters (using the “flag” package) and then parse them (on line 35):

In order to build a session name, we read the the username of the current logged in user (on line 37), and generate an error if there are any problems:

Establishing Credentials

We then attempt to establish a session with AWS. First we look to see if the user has used “-p” or “–profile” to configure a specific profile to use. AWS to allow users to switch between multiple accounts and regions using different profiles. If not specified, we create a default session (line 44), otherwise the specified profile is used to create the session (line 46-48).

Next we use the Security Token Service (STS) to generate a Federation Token with a specific duration, the AWS IAM policy intersection, and the session name (on line 54). We set the session duration to 1 hour. Next set the session name to the name of the current user. We also set the policy intersection to the “anything goes” policy (line 20). This means that the created session will have all the same access as the access key and secret access key. Check for errors then assign the new access key, secret access key and session token to the variables declared above.

What if there was an error? This can be caused when an AssumeRole style of profile is used. We check for this on line 61 and under these circumstances, the following sequence of operations occurs.

First, we fetch the caller identity. Due to the use of AssumeRole, the ARN representing the caller’s identity is “assumed-role” and contains a random session Id. The code at line 77 checks for “assumed-role” and if it finds it, it replaces it with just “role” (line 78) and then removes the trailing backslash (“/”) and random session Id.

Next, we do an assumeRole on that modified role ARN (line 88). What is actually happening here is that we’re assuming the same role. The account Id of the role remains constant and then name of the role remains constant. When we assumeRole on effectively the same role though, we can retrieve the access key, secret access key and session token required for the next phase.

These are then stored in the variables declared earlier (lines 93 – 95).

Building the URLs

So now (on line 99) we have the necessary credentials. GetFederationToken worked when using a traditional profile with access key and secret access keys. Re-assumeRole worked when an assumeRole profile with a source profile and a role to assume. The code is common from this point onwards.

We next build a URL to generate (get) a sign-in token, and issue an HTTP GET request:

We check for an error (line 113) and panic if one occurred. In Go that usually means the program exits, although there are ways to recover.

Assuming the request for a sign-in token succeeded, we then read the response into a byte array (called contents). Then we attempt to parse it with a JSON parser into the “s” variable (line 123). Another check for an error. Finally (line 128) a URL is printed that allows for quick AWS Console login which bypasses MFA requirements for the console.

On the Mac, you can run the Go program from Terminal. Hold Command while double-clicking on the URL to open it in the default browser.


Downloads for Mac, Windows, Linux.


Add Comment

Required fields are marked *. Your email address will not be published.