This is a tool to authenticate to Amazon Web Services using the ADFS SAML provider and create temporary tokens for use with AWS API clients.
The code is packaged as a Python module; if you have a working Python
installation of a recent enough vintage, you should be able to install it
directly from PyPI (http://pypi.python.org) by running pip install samlkeygen
.
If you regularly use Docker and would rather run the tool without installing
anything, you can run a prebuilt Docker image directly from Docker Hub
(http://dockerhub.com) with docker run turnerlabs/samlkeygen
.
Both approaches require some environment variables and/or command-line parameters in order to function properly; see below for details. Of course, you can also always clone the git repository (https://github.com/turnerlabs/samlkeygen) and use the source directly. Pull requests with improvements are always welcome!
On some versions of MacOS, the stock Python install doesn't include pip
. and
even if you install it (e.g. with easy_install
), installing samlkeygen
may
require upgrading some standard modules that file system security restrictions
will not permit. On such systems you will need to either take the Docker approach
or install a separate instance of Python (2.7+ or 3.x, the module works either way);
for the latter solution, consider using Homebrew (http://brew.sh) and/or pyenv
(https://github.com/pyenv/pyenv)
When installed as a module, samlkeygen
installs three front-end scripts
to make common use cases take less typing: awsprof
, awsprofs
, and samld
. There
are bash alias definitions below to create similar commands when using the Docker
version of the tool; the github repo includes a source
able bash script containing
those definitions.
The primary configuration parameters required for the authentication operation are the URL of your ADFS service endpoint and the credentials to log into that endpoint: your Active Directory domain, username, and password. You can provide all of these via command-line parameters or environment variables, though for security we recommend that you let the tool prompt you for your password (which will not be echoed).
Option | Environment Variable | Description |
---|---|---|
--url | ADFS_URL | Complete URL to ADFS SAML endpoint for AWS |
--domain | ADFS_DOMAIN | Active Directory/ADFS domain name |
--username | USER | Your Active Directory username (sAMAccountName) |
--password | PASSWORD | Your Active Directory password (again, we recommend you leave this unset and allow the program to prompt you for it) |
Depending on your environment, you may also have to be on your corporate LAN or VPN in order to authenticate. Once you have obtained keys for a profile, though, those should work from anywhere until they expire.
samlkeygen
has two basic functions: the primary one is authentication, in which
it connects to the ADFS endpoint, authenticates, and gets authorization tokens for
the user's defined SAML roles. The secondary function is to simplify the selection
of a credentials profile file for use by a command.
SAML-based credentials are only good for an hour (a hard AWS-imposed limit). To
make this limit less inconvenient, samlkeygen authenticate
provides a mode of
operation called auto-update
which requests your password once, then runs
continually and automatically requests and saves new credentials every hour
just before the old ones expire. The supplied entry points include samld
,
which can usually be run without arguments if the environment variables are set
properly, or with just --username sAMAccountName
if that isn't the
same as your local $USER
on your workstation. Example:
$ samld --username gpburdell
...
Writing credentials for profile aws-shared-services:aws-shared-services-admin
Writing credentials for profile aws-shared-services:aws-shared-services-dns
Writing credentials for profile aws-ent-prod:aws-ent-prod-admin
Writing credentials for profile cdubs:aws-cdubs-admin
58 minutes till credential refresh
The full usage for samlkeygen authenticate
may be found below.
The authentication tokens will be written out to your credentials file with a
separate profile for each SAML role, named $ACCOUNT_ALIAS:$ROLE_NAME
. You can
get a list of your profiles by running samlkeygen list-profiles
, which
takes an optional parameter to restrict the output to those profiles matching
a substring (really a regular expression). There's an awsprofs
alias/entry point
for this functionality:
$ awsprofs shared-services
aws-shared-services:aws-shared-services-admin
aws-shared-services:aws-shared-services-dns-cnn
These are normal AWS profiles and can be used like any other, by supplying the
--profile
option to whatever AWS CLI command you are running,
or setting the AWS_PROFILE
environment variable (or AWS_DEFAULT_PROFILE
for
some older tools). However, since the autogenerated names are somewhat long,
the script also has a subcommand that lets you select a profile via substring
or regular expression match: select-profile
works just like list-profiles
,
but requires that the pattern match exactly one profile. The supplied
aliases/entry points include one called awsprof
(singular) for this use case:
$ awsprof shared-services
samlkeygen.py: Pattern is not unique. It matches these profiles:
aws-shared-services:aws-shared-services-admin
aws-shared-services:aws-shared-services-dns-cnn
If the pattern does match one profile, that profile's full name is output by itself; the intent is to use the command in command-substitution:
$ aws --profile $(awsprof shared-services-admin) iam list-account-aliases
{
"AccountAliases": [
"aws-shared-services"
]
}
Finally, if you are running the local Python version, you can ask the script to
run a command for you under a given profile. The pip-installed entry poitns
include one called awsrun
for this function; there's no corresponding Docker
alias because the Docker container would have to include the AWS command-line
tool you wanted to run this way.
That lets me replace the above example with this:
$ awsrun shared-services-admin aws iam list-account-aliases
{
"AccountAliases": [
"aws-shared-services"
]
}
alias samld='docker run -it --rm -v "${AWS_DIR:-$HOME/.aws}:/aws" -e "USER=$USER" -e "ADFS_DOMAIN=$ADFS_DOMAIN" -e "ADFS_URL=$ADFS_URL" turnerlabs/samlkeygen authenticate --all-accounts --auto-update'
alias awsprofs='docker run --rm -v ~/.aws:/aws turnerlabs/samlkeygen list-profiles'
alias awsprof='docker run --rm -v ~/.aws:/aws turnerlabs/samlkeygen select-profile'
$AWS_DIR = "$env:UserProfile\.aws" -replace "\\","//"
function Run-SamlKeygenAuto {
docker run -it --rm -v ${AWS_DIR}:/aws -e "USER=$env:UserName" `
-e "ADFS_DOMAIN=$ADFS_DOMAIN" -e "ADFS_URL=$ADFS_URL" `
docker run --rm -v ~/.aws:/aws turnerlabs/samlkeygen select-profile
}
New-Alias awsprof Run-SamlKeygen
usage: samlkeygen [-h]
{authenticate,list-profiles,select-profile,run-command,version}
...
positional arguments:
{authenticate,list-profiles,select-profile,run-command,version}
authenticate Authenticate via SAML and write out temporary security
tokens to the credentials file
list-profiles List available AWS profiles in the credentials file
select-profile Select a unique profile name
run-command Run a command with a given profile
version
optional arguments:
-h, --help show this help message and exit
usage: samlkeygen authenticate [-h] [--url URL] [--region REGION] [--batch]
[--all-accounts] [--account ACCOUNT]
[--profile PROFILE] [--domain DOMAIN]
[--role ROLE] [--username USERNAME]
[--password PASSWORD] [--filename FILENAME]
[--auto-update] [--verbose]
Authenticate via SAML and write out temporary security tokens to the credentials file
optional arguments:
-h, --help show this help message and exit
--url URL URL to ADFS provider (default: '')
--region REGION AWS region to use (default: 'us-east-1')
--batch Disable all interactive prompts (default: False)
--all-accounts Retrieve tokens for all accounts and roles (default:
False)
--account ACCOUNT Name or ID of AWS account for which to generate token
(default: -)
--profile PROFILE Name to give profile in credentials file (default
account:role) (default: -)
--domain DOMAIN Windows domain to authenticate to (default: '')
--role ROLE Name or ARN of role for which to generate token
(default: all for accounts) (default: -)
--username USERNAME Name of user to authenticate as (default: 'mjreed')
--password PASSWORD Password for user (default: -)
--filename FILENAME Name of AWS credentials file (default:
'/Users/mjreed/.aws/credentials')
--auto-update Continue running and update token(s) every hour
(default: False)
--verbose Display trace output (default: False)
usage: samlkeygen list-profiles [-h] [--filename FILENAME] [pattern]
List available AWS profiles in the credentials file
positional arguments:
pattern Restrict list to profiles matching pattern (default:
'.*')
optional arguments:
-h, --help show this help message and exit
--filename FILENAME Name of AWS credentials file (default:
'/Users/mjreed/.aws/credentials')
usage: samlkeygen select-profile [-h] [--filename FILENAME] pattern
Select a unique profile name
positional arguments:
pattern Run command with profile matching pattern
optional arguments:
-h, --help show this help message and exit
--filename FILENAME Name of AWS credentials file (default:
'/Users/mjreed/.aws/credentials')