I’ve been an advocate for AWS SSO for a while, but the official tooling used to log in and work with various accounts within your organization has been somewhat lacking, to put it mildly. That’s why I was so pleased to stumble across granted recently. Before I get into what it is and how it works, allow me to identify what my rather peculiar use case looks like.

My Ridiculous Needs

First, I have an AWS Control Tower managed organization for the Duckbill Group, replete with its AWS SSO access management. We have a bunch of accounts inside of that organization that we can assume roles within, depending upon who we are and what we’re up to. So far, so good.

Second, I have a second AWS Organization comprising a single account called “Shitposting.” I’m not making that up. AWS account aliases are globally unique and for some odd reason nobody at The Register bothered to snap that one up, so I did. That’s a completely separate AWS SSO installation to which I have to authenticate.

Third, I have a variety of roles that I assume in client accounts. These never tend to last very long as our engagements at The Duckbill Group are by design short-term, but any given client has anywhere from one to thousands of AWS accounts that we’ll do bill analysis within. It’s… fun. We’re increasingly rolling out automated tooling for a lot of it, but occasionally there’s still no substitute for working directly with the resources inside of the account.

Fourth, while I use a Mac at home, whenever I travel I have a habit of only bringing an iPad with me, so whatever I use for account access has to also work within a headless EC2 instance.

Fifth, I have a bunch of command line utilities that have no real conception of AWS account profiles and the like, but will pay attention to environment variables like AWS credential sets.

Sixth, as much as I like to tout the benefits of doing everything via either the CLI or a variety of API calls, that is of course a lie. Lying is a foundational tenet of ClickOps, after all. Therefore I need to be able to log into a number of different account AWS consoles, ideally without having to go through an obnoxious process of having to manage a whole mess of IAM usernames and passwords.

Seventh, because it’s a vast world and it takes all kinds, I do have a couple of “legacy” accounts that only support IAM credential sets.

That basically covers it, as well as explains why I’m so sad all the time.

What Came Before

Once upon a time in previous jobs I kept long-lived IAM credentials on disk because I was a dangerous fool. I now know that this was wrong, and have taken steps to not do that anymore. It could have been worse; those credentials might have been for the AWS root user. Please never do this.

For a while I’ve been using 99 Designs’ excellent aws-vault; it stores IAM credentials in a local encrypted password store (macOS keychain, on Linux it uses the pass utility) so you don’t have long lived credentials sitting around on disk. It’s been good, but granted is better.

I’ve experimented with aws-sso-cli which, while excellent, ergonomically didn’t quite suit me. I’ve also of course used the official AWS CLI to log in via SSO, but… well, let’s just say that while it’s gotten better lately, it’s pretty clear that someone on that service team at AWS gets bonused based upon how many characters their customers type when working with the tool.

And now, I use granted instead.

Let’s Talk About Granted

I originally discovered granted a month or so before authoring this post. The delay was largely spent with me lobbing GitHub issues at their repository and obnoxious leading questions at their developers in their community Slack. There were a few strange issues, a few unsupported use cases from my lengthy list above, and above all I wanted to get comfortable enough with it so as not to have to retract this post in three weeks after something better comes along.

On a Mac, brew install largely gets you what you need, after adding a tap. On Linux, “wget a binary from their site and shove it into place” is the state of the art because I don’t like Linux packaging either. Nobody does. It’ll be fine, keep reading.

It includes two commands, granted and assume. The former controls settings for the utility itself. It’s worth pointing out that it of course respects the AWS configuration file in the user’s home directory, so populating that with the roles I care about was a bit of a task. Ben Kehoe’s aws-sso-util was helpful, though it did require a fair bit of tweaking to align with how I think about profile naming. Take a look into its AWS config file generation capability; it’s great for generating a config file that a human being can get value out of.

Granted lets you configure what browser you’re using; assuming you’re not running a headless Linux instance, you’re going to want to use Firefox for this. Spare me your “I use Chrome/Brave/whatever for this, Corey” protests. I’m not saying this because I’m a zealot, I’m saying this because Firefox’s multi-container capability has been wrapped by the granted Firefox plugin. Keep reading!

Once you’ve gotten it set up the way you want, type assume followed by either the enter key, or the name of a profile. If the former, you’ll be able to select from all of the profiles in your AWS config, sorted by a frecency (yes that’s really a word, not a typo) algorithm so that your most commonly used options appear near the top. Whack enter, and you’ll either be kicked out to a browser to authenticate via SSO, or be given a URL to stdout if that’s how you’ve configured granted. Go sign in with your SSO credentials.

When the login is successful, granted stores the token in its configured credential store; it’s usually got a 12 hour validity window; none of the IAM ‘log in every hour’ nonsense here. It also populates the usual environment variables in your terminal as you’d expect. Wait; it gets better.

If you invoke assume with the -c flag, instead of setting environment variables it will launch your default browser. Here’s why you want it to be Firefox: it will add the name of the profile to your URL bar in a unique color, representing the container it’s in. You can thus have a dozen or more different AWS accounts logged into the web console simultaneously. For those of us who live and die by ClickOps, this is transformative.

I’d advise users to also detect and display the value of AWS_PROFILE in your various shell prompts lest you operate on an account you didn’t intend to, and the zsh tab completion isn’t quite working for profiles the way I want it to yet as of the time of this writing. That said, the developers behind the tool are friendly and accessible, the code is surprisingly readable for someone who’s never touched golang in anger, and the documentation continues to get better bit by bit.

Granted is to date the best means I’ve found to navigate a disturbing number of AWS accounts; if you know of a better one I’d dearly love to know what you’ve found.