onelogin / onelogin-python-aws-assume-role

MIT License
58 stars 52 forks source link

onelogin-python-aws-assume-role

Assume an AWS Role and get temporary credentials using Onelogin.

Users will be able to choose from among multiple AWS roles in multiple AWS accounts when they sign in using OneLogin in order to assume an AWS Role and obtain temporary AWS access credentials.

This is really useful for customers that run complex environments with multiple AWS accounts, roles and many different people that need periodic access as it saves manually generating and managing AWS credentials.

This repository contains a python script at src/aws_assume_role/aws_assume_role.py that you can execute using onelogin-aws-assume-role in order to retrieve the AWS credentials.

OneLogin's Smart MFA cannot be enforced with OneLogin's AWS CLI utility

AWS and OneLogin prerequisites

The "Configuring SAML for Amazon Web Services (AWS) with Multiple Accounts and Roles" guide explains how to:

Installation

Hosting

Github

The project is hosted at github. You can download it from:

Pypi

The toolkit is hosted in pypi, you can find the python-saml package at https://pypi.python.org/pypi/onelogin-aws-assume-role

Dependencies

It works with python2 and python3.

Getting started

Virtualenv

The use of a virtualenv is highly recommended.

Virtualenv helps isolating the python environment used to run the toolkit. You can find more details and an installation guide in the official documentation.

Once you have your virtualenv ready and loaded, then you can install the toolkit on it in development mode executing this:

python setup.py develop

Using this method of deployment the toolkit files will be linked instead of copied, so if you make changes on them you won't need to reinstall the toolkit.

If you want install it in a normal mode, execute:

python setup.py install

Settings

The python script uses a settings file, where OneLogin SDK properties are placed.

Is a json file named onelogin.sdk.json as follows:

{
  "client_id": "",
  "client_secret": "",
  "region": "",
  "ip": ""
}

Where:

For security reasons, IP only can be provided in onelogin.sdk.json. On a shared machine where multiple users has access, That file should only be readable by the root of the machine that also controls the client_id / client_secret, and not by an end user, to prevent him manipulate the IP value.

Place the file in the ~/.onelogin directory or in the same path where the python script is invoked or provide the path with the -c option.

There is an optional file onelogin.aws.json, that can be used if you plan to execute the script with some fixed values and avoid providing it on the command line each time.

{
  "app_id": "123456",
  "subdomain": "myolsubdomain",
  "username": "user.name",
  "profile": "profile-1",
  "duration": 3600,
  "aws_region": "us-west-2",
  "aws_account_id": "",
  "aws_role_name": "",
  "profiles": {
    "profile-1": {
      "aws_account_id": "",
      "aws_role_name": "",
      "aws_region": "",
      "app_id": ""
    },
    "profile-2": {
      "aws_account_id": ""
    }
  }
}

Where:

Note: The values provided on the command line will take precedence over the values defined on this file and, values defined at the global scope in the file, will take precedence over values defined at the profiles level. IN addition, each attribute is treating individually, so be aware that this may lead to somewhat strange behaviour when overriding a subset of parameters, when others are defined at a lower level and not overridden. For example, if you had a onelogin.aws.json config file as follows:

{
  ...
  "aws_region": "eu-east-1",
  "profiles": {
    "my-account": {
      "aws_account_id": "11111111",
      "aws_role_name": "Administrator"
    }
  }
}

And, you you subsequently ran the application with the command line arguments --profile my-account --aws-account-id 22222222 then the application would ultimately attempt to log in with the role Administrator on account 22222222, with region set to eu-east-1 and, if successful, save the credentials to profile my-account.

In addition, there is another optional file that can be created to give more human readable names to the account list, named accounts.yaml, which should be placed in the same path where the python script is invoked:

accounts:
  "987654321012": Prod account
  "123456789012": Dev Account

This isn't needed for the script to function but it provides a better user experience.

Docker installation method

How the process works

Step 1. Provide OneLogin data.

Note: If you're bored typing your username (--onelogin-username), App ID (--onelogin-app-id), subdomain (--onelogin-subdomain) or AWS region (--aws-region) every time, you can specify these parameters as command-line arguments and the tool won't ask for them any more.

You can specify OTP Code (--otp) and the cli will use this otp only for the first interaction requiring a manual OTP Code

Note: Specifying your password directly with --onelogin-password is bad practice, you should use that flag together with password managers, eg. with the OSX Keychain: --onelogin-password $(security find-generic-password -a $USER -s onelogin -w), so your password won't be saved in you command line history. Please note that your password will be visible in your process list, if you use this flag (as the expanded command line arguments are part of the name of the process).

With that data, a SAMLResponse is retrieved. And possible AWS Role are retrieved.

Step 2. Select AWS Role to be assumed.

Step 3. AWS Credentials retrieved.

A temporal AWS AccessKey and secretKey are retrieved in addition to a sessionToken. Those data can be used to generate an AWS BasicSessionCredentials to be used in any AWS API SDK.

Quick Start using the python script

Prepare the environment

After checking out the repository, let's use a virtual environment

cd <repository>
virtualenv venv

Activate then the environment

> source venv/bin/activate

Then run

> python setup.py install

or

> python setup.py develop

to install dependencies.

Usage

Assuming you have your AWS Multi Account app set up correctly and you’re using valid OneLogin API credentials stored on the onelogin.sdk.json placed at the root of the repository, using this tool is as simple as following the prompts.

> onelogin-aws-assume-role

Or alternately save them to your AWS credentials file to enable faster access from any terminal.

> onelogin-aws-assume-role --profile profilename

By default, the credentials only last for 1 hour, but you can edit that restriction on AWS and set a max of 12h session duration.

Then set the -z or duration with the desired credentials session duration. The possible value to be used is limited by the AWS Role. Read more at https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session

You can also make it regenerate and update the credentials file by using the --loop option to specify the number of iterations, and --time to specify the minutes between iterations. If you specified a duration, be sure the value you set for the duration session of the credential is bigger than the value you set for the time, so your credentials will be renewed before expiration.

You can provide an specific path where locate the settings file by providing the -c or --config-file-path option.

You can also make it interactive, with the -x or --interactive option, and at the end of the iteration, you will be asked if want to generate new credentials for a new user or a new role.

The selection of the AWS account and Role can be also be done with the --aws-account-id and --aws-role-name parameters. If both parameters are set then both will be matched against the list of available accounts and roles. If only --aws-account-id is specified and you only have one available role in that account, then that role will be chosen by default. If you have more than one role in the given account then you will need to select the appropriate one as per normal.

If you plan to execute the script several times over different Accounts/Roles of the user and you want to cache the SAMLResponse, set the --cache-saml option

By default in order to select Account/Role, the list will be ordered by account ids. Enable the --role_order option to list by role name instead.

For more info execute:

> onelogin-aws-assume-role --help

Test your credentials with AWS CLI

AWS provide a CLI tool that makes remote access and management of resources super easy. If you don’t have it already then read more about it and install it from here.

For convenience you can simply copy and paste the temporary AWS access credentials generated above to set them as environment variables. This enables you to instantly use AWS CLI commands as the environment variables will take precedence over any credentials you may have in your ~/.aws directory.

Assuming that:

You should find success with the following AWS CLI command.

aws ec2 describe-instances

Development

After checking out the repo, run pip setup install or python setup.py develop to install dependencies.

To release a new version, update the version number in src/onelogin/api/version.py and commit it, then you will be able to update it to pypi. with python setup.py sdist upload and python setup.py bdist_wheel upload. Create also a release tag on github.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/onelogin/onelogin-python-aws-assume-role. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

License

The gem is available as open source under the terms of the MIT License.

Code of Conduct

Everyone interacting in the OneLogin Assume AWS Role project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.