github.com/versent/saml2aws@v2.17.0+incompatible/README.md (about)

     1  # saml2aws [![Build Status](https://travis-ci.org/Versent/saml2aws.svg?branch=master)](https://travis-ci.org/Versent/saml2aws) [![Build status - Windows](https://ci.appveyor.com/api/projects/status/ptpi18kci16o4i82/branch/master?svg=true)](https://ci.appveyor.com/project/davidobrien1985/saml2aws/branch/master)
     2  
     3  CLI tool which enables you to login and retrieve [AWS](https://aws.amazon.com/) temporary credentials using 
     4  with [ADFS](https://msdn.microsoft.com/en-us/library/bb897402.aspx) or [PingFederate](https://www.pingidentity.com/en/products/pingfederate.html) Identity Providers.
     5  
     6  This is based on python code from [
     7  How to Implement a General Solution for Federated API/CLI Access Using SAML 2.0](https://blogs.aws.amazon.com/security/post/TxU0AVUS9J00FP/How-to-Implement-a-General-Solution-for-Federated-API-CLI-Access-Using-SAML-2-0).
     8  
     9  The process goes something like this:
    10  
    11  * Setup an account alias, either using the default or given a name
    12  * Prompt user for credentials
    13  * Log in to Identity Provider using form based authentication
    14  * Build a SAML assertion containing AWS roles
    15  * Exchange the role and SAML assertion with [AWS STS service](https://docs.aws.amazon.com/STS/latest/APIReference/Welcome.html) to get a temporary set of credentials
    16  * Save these credentials to an aws profile named "saml"
    17  
    18  ## Table of Contents
    19  
    20  - [Table of Contents](#table-of-contents)
    21  - [Requirements](#requirements)
    22  - [Caveats](#caveats)
    23  - [Install](#install)
    24      - [OSX](#osx)
    25      - [Windows](#windows)
    26  - [Dependency Setup](#dependency-setup)
    27  - [Usage](#usage)
    28      - [`saml2aws script`](#saml2aws-script)
    29      - [Configuring IDP Accounts](#configuring-idp-accounts)
    30  - [Example](#example)
    31  - [Advanced Configuration](#advanced-configuration)
    32      - [Dev Account Setup](#dev-account-setup)
    33      - [Test Account Setup](#test-account-setup)
    34  - [Building](#building)
    35  - [Environment vars](#environment-vars)
    36  - [Provider Specific Documentation](#provider-specific-documentation)
    37  
    38  ## Requirements
    39  
    40  * One of the supported Identity Providers
    41    * ADFS (2.x or 3.x)
    42    * PingFederate + PingId
    43    * [Okta](pkg/provider/okta/README.md)
    44    * KeyCloak + (TOTP)
    45    * [Google Apps](pkg/provider/googleapps/README.md)
    46    * [Shibboleth](pkg/provider/shibboleth/README.md)
    47    * [F5APM](pkg/provider/f5apm/README.md)
    48    * [PSU](pkg/provider/psu/README.md)
    49  * AWS SAML Provider configured
    50  
    51  ## Caveats
    52  
    53  Aside from Okta, most of the providers in this project are using screen scraping to log users into SAML, this isn't ideal and hopefully vendors make this easier in the future. In addition to this there are some things you need to know:
    54  
    55  1. AWS defaults to session tokens being issued with a duration of up to 3600 seconds (1 hour), this can now be configured as per [Enable Federated API Access to your AWS Resources for up to 12 hours Using IAM Roles](https://aws.amazon.com/blogs/security/enable-federated-api-access-to-your-aws-resources-for-up-to-12-hours-using-iam-roles/) and `--session-duration` flag.
    56  2. Every SAML provider is different, the login process, MFA support is pluggable and therefore some work may be needed to integrate with your identity server
    57  
    58  ## Install
    59  
    60  ### OSX
    61  
    62  If you're on OSX you can install saml2aws using homebrew!
    63  
    64  ```
    65  brew tap versent/homebrew-taps
    66  brew install saml2aws
    67  ```
    68  
    69  ### Windows
    70  
    71  If you're on Windows you can install saml2aws using chocolatey!
    72  
    73  ```
    74  choco install saml2aws
    75  saml2aws --version
    76  ```
    77  
    78  ## Dependency Setup
    79  
    80  Install the AWS CLI [see](https://docs.aws.amazon.com/cli/latest/userguide/installing.html), in our case we are using [homebrew](http://brew.sh/) on OSX.
    81  
    82  ```
    83  brew install awscli
    84  ```
    85  
    86  ## Usage
    87  
    88  ```
    89  usage: saml2aws [<flags>] <command> [<args> ...]
    90  
    91  A command line tool to help with SAML access to the AWS token service.
    92  
    93  Flags:
    94        --help                   Show context-sensitive help (also try --help-long
    95                                 and --help-man).
    96        --version                Show application version.
    97        --verbose                Enable verbose logging
    98    -i, --provider=PROVIDER      This flag is obsolete. See:
    99                                 https://github.com/Versent/saml2aws#configuring-idp-accounts
   100    -a, --idp-account="default"  The name of the configured IDP account. (env:
   101                                 SAML2AWS_IDP_ACCOUNT)
   102        --idp-provider=IDP-PROVIDER
   103                                 The configured IDP provider. (env:
   104                                 SAML2AWS_IDP_PROVIDER)
   105        --mfa=MFA                The name of the mfa. (env: SAML2AWS_MFA)
   106    -s, --skip-verify            Skip verification of server certificate.
   107        --url=URL                The URL of the SAML IDP server used to login.
   108                                 (env: SAML2AWS_URL)
   109        --username=USERNAME      The username used to login. (env:
   110                                 SAML2AWS_USERNAME)
   111        --password=PASSWORD      The password used to login. (env:
   112                                 SAML2AWS_PASSWORD)
   113        --mfa-token=MFA-TOKEN    The current MFA token (supported in Keycloak,
   114                                 ADFS). (env: SAML2AWS_MFA_TOKEN)
   115        --role=ROLE              The ARN of the role to assume. (env:
   116                                 SAML2AWS_ROLE)
   117        --aws-urn=AWS-URN        The URN used by SAML when you login. (env:
   118                                 SAML2AWS_AWS_URN)
   119        --duo-mfa-option         The MFA option you want to use to authenticate (env: SAML_DUO_MFA_OPTION)
   120        --skip-prompt            Skip prompting for parameters during login.
   121        --exec-profile           Execute the given command utilizing a specific profile from your ~/.aws/config file
   122        --session-duration=SESSION-DURATION
   123                                 The duration of your AWS Session. (env:
   124                                 SAML2AWS_SESSION_DURATION)
   125  
   126  Commands:
   127    help [<command>...]
   128      Show help.
   129  
   130    configure [<flags>]
   131      Configure a new IDP account.
   132  
   133    login [<flags>]
   134      Login to a SAML 2.0 IDP and convert the SAML assertion to an STS token.
   135  
   136    exec [<flags>] [<command>...]
   137      Exec the supplied command with env vars from STS token.
   138  
   139    list-roles
   140      List available role ARNs.
   141  
   142    script [<flags>]
   143      Emit a script that will export environment variables.
   144  ```
   145  
   146  
   147  ### `saml2aws script`
   148  
   149  If the `script` sub-command is called, `saml2aws` will output the following temporary security credentials:
   150  ```
   151  export AWS_ACCESS_KEY_ID="ASIAI....UOCA"
   152  export AWS_SECRET_ACCESS_KEY="DuH...G1d"
   153  export AWS_SESSION_TOKEN="AQ...1BQ=="
   154  export AWS_SECURITY_TOKEN="AQ...1BQ=="
   155  SAML2AWS_PROFILE=saml
   156  ```
   157  
   158  Powershell, and fish shells are supported as well.
   159  
   160  If you use `eval $(saml2aws script)` frequently, you may want to create a alias for it:
   161  
   162  zsh:
   163  ```
   164  alias s2a="function(){eval $( $(command saml2aws) script --shell=bash --profile=$@);}"
   165  ```
   166  
   167  bash:
   168  ```
   169  function s2a { eval $( $(which saml2aws) script --shell=bash --profile=$@); }
   170  ```
   171  
   172  ### `saml2aws exec`
   173  
   174  If the `exec` sub-command is called, `saml2aws` will execute the command given as an argument:
   175  By default saml2aws will execute the command with temp credentials generated via `saml2aws login`.
   176  
   177  The `--exec-profile` flag allows for a command to execute using an aws profile which may have chained "assume role" actions. (via 'source_profile' in ~/.aws/config) *See section "blah" for scenario where this is useful as well as example below.
   178  
   179  ```
   180  options:
   181  --exec-profile           Execute the given command utilizing a specific profile from your ~/.aws/config file
   182  ```
   183  
   184  ### Configuring IDP Accounts
   185  
   186  This is the *new* way of adding IDP provider accounts, it enables you to have named accounts with whatever settings you like and supports having one *default* account which is used if you omit the account flag. This replaces the --provider flag and old configuration file in 1.x.
   187  
   188  To add a default IdP account to saml2aws just run the following command and follow the prompts.
   189  
   190  ```
   191  $ saml2aws configure
   192  ? Please choose a provider: Ping
   193  ? AWS Profile myaccount
   194  
   195  ? URL https://example.com
   196  ? Username me@example.com
   197  
   198  ? Password
   199  No password supplied
   200  
   201  account {
   202    URL: https://example.com
   203    Username: me@example.com
   204    Provider: Ping
   205    MFA: Auto
   206    SkipVerify: false
   207    AmazonWebservicesURN: urn:amazon:webservices
   208    SessionDuration: 3600
   209    Profile: myaccount
   210  }
   211  
   212  Configuration saved for IDP account: default
   213  ```
   214  
   215  Then to login using this account.
   216  
   217  ```
   218  saml2aws login
   219  ```
   220  
   221  You can also add named accounts, below is an example where I am setting up an account under the `wolfeidau` alias, again just follow the prompts.
   222  
   223  ```
   224  saml2aws configure -a wolfeidau
   225  ```
   226  
   227  You can also configure the account alias without prompts.
   228  
   229  ```
   230  saml2aws configure -a wolfeidau --idp-provider KeyCloak --username mark@wolfe.id.au \
   231    --url https://keycloak.wolfe.id.au/auth/realms/master/protocol/saml/clients/amazon-aws --skip-prompt
   232  ```
   233  
   234  Then your ready to use saml2aws.
   235  
   236  ## Example
   237  
   238  Log into a service (without MFA).
   239  
   240  ```
   241  $ saml2aws login
   242  Using IDP Account default to access Ping https://id.example.com
   243  To use saved password just hit enter.
   244  Username [mark.wolfe@example.com]:
   245  Password: ************
   246  
   247  Authenticating as mark.wolfe@example.com ...
   248  Selected role: arn:aws:iam::123123123123:role/AWS-Admin-CloudOPSNonProd
   249  Requesting AWS credentials using SAML assertion
   250  Saving credentials
   251  Logged in as: arn:aws:sts::123123123123:assumed-role/AWS-Admin-CloudOPSNonProd/wolfeidau@example.com
   252  
   253  Your new access key pair has been stored in the AWS configuration
   254  Note that it will expire at 2016-09-19 15:59:49 +1000 AEST
   255  To use this credential, call the AWS CLI with the --profile option (e.g. aws --profile saml ec2 describe-instances).
   256  ```
   257  
   258  Log into a service (with MFA).
   259  
   260  ```
   261  $ saml2aws login
   262  Using IDP Account default to access Ping https://id.example.com
   263  To use saved password just hit enter.
   264  Username [mark.wolfe@example.com]:
   265  Password: ************
   266  
   267  Authenticating as mark.wolfe@example.com ...
   268  Enter passcode: 123456
   269  
   270  Selected role: arn:aws:iam::123123123123:role/AWS-Admin-CloudOPSNonProd
   271  Requesting AWS credentials using SAML assertion
   272  Saving credentials
   273  Logged in as: arn:aws:sts::123123123123:assumed-role/AWS-Admin-CloudOPSNonProd/wolfeidau@example.com
   274  
   275  Your new access key pair has been stored in the AWS configuration
   276  Note that it will expire at 2016-09-19 15:59:49 +1000 AEST
   277  To use this credential, call the AWS CLI with the --profile option (e.g. aws --profile saml ec2 describe-instances --region us-east-1).
   278  ```
   279  
   280  ## Advanced Configuration
   281  
   282  Configuring multiple accounts with custom role and profile in `~/.aws/config` with goal being isolation between infra code when deploying to these environments. This setup assumes you're using separate roles and probably AWS accounts for `dev` and `test` and is designed to help operations staff avoid accidentally deploying to the wrong AWS account in complex environments. Note that this method configures SAML authentication to each AWS account directly (in this case different AWS accounts). In the example below, separate authentication values are configured for AWS accounts 'profile=customer-dev/awsAccount=was 121234567890' and 'profile=customer-test/awsAccount=121234567891'
   283  
   284  ### Dev Account Setup
   285  
   286  To setup the dev account run the following and enter URL, username and password, and assign a standard role to be automatically selected on login.
   287  
   288  ```
   289  saml2aws configure -a customer-dev --role=arn:aws:iam::121234567890:role/customer-admin-role -p customer-dev
   290  ```
   291  
   292  This will result in the following configuration in `~/.saml2aws`.
   293  
   294  ```
   295  [customer-dev]
   296  url                     = https://id.customer.cloud
   297  username                = mark@wolfe.id.au
   298  provider                = Ping
   299  mfa                     = Auto
   300  skip_verify             = false
   301  timeout                 = 0
   302  aws_urn                 = urn:amazon:webservices
   303  aws_session_duration    = 28800
   304  aws_profile             = customer-dev
   305  role_arn                = arn:aws:iam::121234567890:role/customer-admin-role
   306  ```
   307  
   308  To use this you will need to export `AWS_DEFAULT_PROFILE=customer-dev` environment variable to target `dev`.
   309  
   310  ### Test Account Setup
   311  
   312  To setup the test account run the following and enter URL, username and password.
   313  
   314  ```
   315  saml2aws configure -a customer-test --role=arn:aws:iam::121234567891:role/customer-admin-role -p customer-test
   316  ```
   317  
   318  This results in the following configuration in `~/.saml2aws`.
   319  
   320  ```
   321  [customer-test]
   322  url                     = https://id.customer.cloud
   323  username                = mark@wolfe.id.au
   324  provider                = Ping
   325  mfa                     = Auto
   326  skip_verify             = false
   327  timeout                 = 0
   328  aws_urn                 = urn:amazon:webservices
   329  aws_session_duration    = 28800
   330  aws_profile             = customer-test
   331  role_arn                = arn:aws:iam::121234567891:role/customer-admin-role
   332  ```
   333  
   334  To use this you will need to export `AWS_DEFAULT_PROFILE=customer-test` environment variable to target `test`.
   335  
   336  ## Advanced Configuration (Multiple AWS account access but SAML authenticate against a single 'SSO' AWS account)
   337  
   338  Example:
   339  (Authenticate to my 'SSO' AWS account. With this setup, there is no need to authenticate again. We can now rely on IAM to assume role cross account)
   340  
   341  ~/.aws/credentials: #(these are generated by `saml2aws login`. Sets up SAML authentication into my AWS 'SSO' account)
   342  ```
   343  [saml]
   344  aws_access_key_id        = AAAAAAAAAAAAAAAAB
   345  aws_secret_access_key    = duqhdZPRjEdZPRjE=dZPRjEhKjfB
   346  aws_session_token        = #REMOVED#
   347  aws_security_token       = #REMOVED#
   348  x_principal_arn          = arn:aws:sts::000000000123:assumed-role/myInitialAccount
   349  x_security_token_expires = 2019-08-19T15:00:56-06:00
   350  ```
   351  
   352  (Use AWS profiles to assume an aws role cross-account)
   353  (Note that the "source_profile" is set to SAML which is my SSO AWS account since it is already authenticated)
   354  
   355  ~/.aws/config:
   356  ```
   357  [profile roleIn2ndAwsAccount]
   358  source_profile=saml
   359  role_arn=arn:aws:iam::123456789012:role/OtherRoleInAnyFederatedAccount # Note the different account number here
   360  role_session_name=myAccountName
   361  ```
   362  
   363  Running saml2aws without --exec-profile flag:
   364  ```
   365  saml2aws exec aws sts get-caller-identity
   366  {
   367      "UserId": "AROAYAROAYAROAYOO:myInitialAccount",
   368      "Account": "000000000123",
   369      "Arn": "arn:aws:sts::000000000123:assumed-role/myInitialAccount"  # This shows my 'SSO' account (SAML profile)
   370  }
   371  
   372  ```
   373  
   374  Running saml2aws with --exec-profile flag:
   375  ```
   376  saml2aws exec --exec-profile roleIn2ndAwsAccount aws sts get-caller-identity
   377  {
   378      "UserId": "YOOYOOYOOYOOYOOA:/myAccountName",
   379      "Account": "123456789012",
   380      "Arn": "arn:aws:sts::123456789012:assumed-role/myAccountName"  # When using '--exec-profile' I can assume-role into a                                                                        # different AWS account without re-authenticating. 
   381                                                                     # Note that it does not re-authenitcate since we are 
   382                                                                     # alredy authenticated via the SSO account
   383  }
   384  ```
   385  
   386  As an example
   387  
   388  ```
   389  saml2aws login
   390  
   391  aws s3 ls --profile saml
   392  
   393  An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied
   394  # This is denied in this example because there are no S3 buckets in the 'SSO' AWS account
   395  
   396  saml2aws exec --exec-profile roleIn2ndAwsAccount aws s3 ls  # Runs given CMD with environment configured from --exec-profile role
   397  
   398  # If we check env variables we see that our environment is configured with temporary credentials for our 'assumed role'
   399  env | grep AWS
   400  AWS_SESSION_TTL=12h
   401  AWS_FEDERATION_TOKEN_TTL=12h
   402  AWS_ASSUME_ROLE_TTL=1h
   403  AWS_ACCESS_KEY_ID=AAAAAAAASORTENED
   404  AWS_SECRET_ACCESS_KEY=secretShortened+6jJ5SMqsM5CkYi3Gw7
   405  AWS_SESSION_TOKEN=ShortenedTokenXXX=
   406  AWS_SECURITY_TOKEN=ShortenedSecurityTokenXXX=
   407  
   408  # If we desire to execute multiple commands utilizing our assumed profile, we can obtain a new shell with Env variables configured for access
   409  
   410  saml2aws exec --exec-profile roleIn2ndAwsAccount $SHELL  # Get a new shell with AWS env vars configured for 'assumed role' account access
   411  
   412  # We are now able to execute AWS cli commands with our assume role permissions
   413  
   414  # Note that we do not need a --profile flag because our environment variables were set up for this access when we obtained a new shell with the --exec-profile flag
   415  
   416  aws s3 ls  
   417  2019-07-30 01:32:59 264998d7606497040-sampleBucket
   418  
   419  aws iam list-groups
   420  {
   421      "Groups": [
   422          {
   423              "Path": "/",
   424              "GroupName": "MyGroup",
   425              "GroupId": "AGAGTENTENTENGOCQFK",
   426              "Arn": "arn:aws:iam::123456789012:group/MyGroup",
   427              "CreateDate": "2019-05-13T16:12:19Z"
   428              ]
   429          }
   430  }
   431  
   432  ## Building
   433  
   434  To build this software on osx clone to the repo to `$GOPATH/src/github.com/versent/saml2aws` and ensure you have `$GOPATH/bin` in your `$PATH`.
   435  
   436  ```
   437  make deps
   438  ```
   439  
   440  Install the binary to `$GOPATH/bin`.
   441  
   442  ```
   443  make install
   444  ```
   445  
   446  Then to test the software just run.
   447  
   448  ```
   449  make test
   450  ```
   451  
   452  ## Environment vars
   453  
   454  The exec sub command will export the following environment variables.
   455  
   456  * AWS_ACCESS_KEY_ID
   457  * AWS_SECRET_ACCESS_KEY
   458  * AWS_SESSION_TOKEN
   459  * AWS_SECURITY_TOKEN
   460  * EC2_SECURITY_TOKEN
   461  * AWS_PROFILE
   462  * AWS_DEFAULT_PROFILE
   463  
   464  Note: That profile environment variables enable you to use `exec` with a script or command which requires an explicit profile.
   465  
   466  ## Provider Specific Documentation
   467  
   468  * [Azure Active Directory](./doc/provider/aad)
   469  * [JumpCloud](./doc/provider/jumpcloud)
   470  
   471  # Dependencies
   472  
   473  This tool would not be possible without some great opensource libraries.
   474  
   475  * [goquery](https://github.com/PuerkitoBio/goquery) html querying
   476  * [etree](https://github.com/beevik/etree) xpath selector
   477  * [kingpin](https://github.com/alecthomas/kingpin) command line flags
   478  * [aws-sdk-go](https://github.com/aws/aws-sdk-go) AWS Go SDK
   479  * [go-ini](https://github.com/go-ini/ini) INI file parser
   480  * [go-ntlmssp](https://github.com/Azure/go-ntlmssp) NTLM/Negotiate authentication
   481  
   482  # Releasing
   483  
   484  Install `github-release`.
   485  
   486  ```
   487  go get github.com/buildkite/github-release
   488  ```
   489  
   490  To release run.
   491  
   492  ```
   493  make release
   494  ```
   495  
   496  # Debugging Issues with IDPs
   497  
   498  There are two levels of debugging, first emits debug information and the URL / Method / Status line of requests.
   499  
   500  ```
   501  saml2aws login --verbose
   502  ```
   503  
   504  The second emits the content of requests and responses, this includes authentication related information so don't copy and paste it into chat or tickets!
   505  
   506  ```
   507  DUMP_CONTENT=true saml2aws login --verbose
   508  ```
   509  
   510  # License
   511  
   512  This code is Copyright (c) 2018 [Versent](http://versent.com.au) and released under the MIT license. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE.md file for more details.
   513