Golang Implementation of AWS STS Auth Using Kerberos + ADFS

We leverage kerb-sts to authenticate developers to use the Amazon AWS API/CLI. kerb-sts is cross-platform and uses kerberos tickets generated as part of MS AD Domain authentication that Devs use to login to their workstations anyway. This use of kerberos makes it easy to track the identity of users across the environment.

Last week I ran into a rare instance where kerb-sts stopped functioning. 'Something' had changed in our environment which I could not easily determine and that left me in a bind. While I was able to figure out and solve the problem I realized that I needed to improve my depth of understanding around kerberos/ADFS and AWS STS, so I wrote a tool that attempts to perform this authentication in Golang.

If you want to cut to the chase and see the code, head on over to gkerb-sts to take a look


Process Overview

For kerberos -> AWS STS authentication to work the following steps need to take place (from a Linux system):

  • User has to authenticate with MS Active directory (using kinit)
  • Read the cached kerberos credentials (/tmp/krb5cc_<UID>)
  • Read the system kerberos configuration (/etc/krb5.conf)
  • Create an SPNEGO client from the kerberos creds and configuration
  • Authenticate against the identity provider (url similar to: https://adfs.domain.tld/adfs/ls/IdpInitiatedSignOn.aspx?loginToRp=urn:amazon:webservices)
    • IMPORTANT: Set the User-Agent in the request to Mozilla/5.0 (compatible, MSIE 11, Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko. Without this I found that kerberos auth would not work against an ADFS provider
  • Extract the encoded SAML token from the response (by scraping the HTML)
  • Base64 Decode the SAML token
  • Extract the list of authorized AWS Roles from the SAML Assertion/Attributes
  • Use the AWS SDK to generate temporary tokens for each AWS Role the user is authorized for
  • Write out a properly-formatted AWS credentials file (usually found at ~/.aws/credentials)

Kerberos, SAML and Golang

The most difficult parts of this process (dealing with Kerberos and SAML) would have been MUCH more difficult were it not for the solid library support made available by the gokrb5 and gosaml2 libraries. Thank you to the maintainers and contributors of those fine projects!

Example Project + Caveats

You can find the working golang code here: gkerb-sts. Most of the effort in this project went into figuring out how the process flow was supposed to work so the example is pretty raw. Be sure to read the comments and code and set values appropriate to your environment if you want to test it out.