letme

command module
v0.2.0-rc4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 17, 2024 License: MIT Imports: 3 Imported by: 0

README

Known issues:

  • --credentials-process with mfa enabled fails if mfa code is not provided through argument --inline-mfa TODO:
  • (letme-tests) fix credentials-process requesting credentials even if time specified in session_duration hasnt been completed
  • fix letme list not displaying more than 25 clients
  • letme list now must read from json database file
  • remove client from .letme-db file when letme remove client is issued
  • remove code referencing old cache mechanism e.g. type CacheFields struct
  • deleted various external libraries which will make letme smaller in total size
  • remove old cache functions and methods (letme init)

letme Go Report Card GitHub go.mod Go version of a Go module GoDoc reference example

A reliable, secure and fast way to switch between AWS accounts from the CLI.

Requirements

  • Go (recommended 1.22 or later).
  • AWS CLI (recommended v2).

Objectives

Letme was born from the groundup with the following goals and design principles:

  • Reduce the hassle of interacting with AWS services on multiple accounts.
  • Leverage the interaction with AWS Assume Role API.
  • Do not tinker with end-user machine:
    • Using the keychain.
    • Updating environment variables.
    • Executing other programs.
    • etc.
  • No more: "From my local computer works."
  • Be compatible with all desktop OS.

What it is and what it's not

The following statement explains what this tool is:

A simple tool which writes/updates AWS credentials under your AWS files.

This software is NOT intended for:

  • Securing your AWS files, letme just reads and writes to them.
  • You are responsable to prevent unauthorized access to those files.
  • Securing your AWS infrastructure (requiring MFA in your trust relationships, using a role with fine-grained permissions, etc.)

Setting up letme

If your organization has already configured the infrastructure required by letme, you just want to install letme. And start using it as soon as you configure the required parameters.

Nevertheless, if want to set up letme for your organization you must spin up the required infrastructure for letme, once done, you can distribute your configuration file amongst your peers.

Installing letme

Review the requirements and install letme with:

go install github.com/lockedinspace/letme@latest

Go will automatically install it in your $GOPATH/bin directory which should be in your $PATH.

Installing letme from source

If you wish to install from source, clone the repository and build the executable with go build. Afterwards, you must place the binary into your $PATH.
This repository uses a go mod file, so don't git clone inside your $GOPATH.

Using the configuration file

letme needs a configuration file to read values from, it holds details regarding your AWS configurations.

[general]
aws_source_profile = "default"
aws_source_profile_region = "eu-west-1"
dynamodb_table = "mytable"
mfa_arn = "arn:aws:iam::123456789012:mfa/user001"
session_name = "user001-with-letme"

Run letme config-file to generate your config-file.

Where:

Key Description Default value Required  Type 
aws_source_profile The AWS CLI profile name which maps to the source account. This profile must held the DynamoDB table. [1] default No string
aws_source_profile_region The region name in the source account where the DynamoDB table is located [2] - Yes string
dynamodb_table The DynamoDB table name where the AWS accounts are stored 3 - Yes string
mfa_arn Virtual MFA device arn used to authenticate against AWS [4] - No (depending on your AWS trust relationship policy) string
session_name The session name when performing assumeRole requests [5] ${account_name}-letme-session No string

- represents an empty/null value.

Setting up the AWS infrastructure required by letme

If you want to start using letme for your organization, you must deploy one DynamoDB table under your main AWS account (aws_source_profile) which will be the one hosting the whole central database for your organization. The DynamoDB table name will be the one used in your configuration file under the dynamodb_table key.

When adding a new AWS account, you need to create an item inside the DynamoDB table with the following structure: AWS account structure. Once you create that item, if you perform a letme list or letme init && letme list you will be able to list that new account.

Take a look at the following simplified diagram and understand why a DynamoDB table is required in order to provide a central and reliable source of trust.

(letme workflow)

Here's a more detailed workflow of the work being done behind the scenes:

When the user tries to obtain access to example1's account, letme will read the parameters specified in the config file and try to authenticate against AWS (step 1 from diagram). If the specified keys aws_source_profile , aws_source_profile_region and dynamodb_table map to an existing DynamoDB table, letme will try to get the information stored into the item which its "name" satisfies example1.

If the DynamoDB table contains an item entry for example1 with the following json structure, letme will grab the first role from the role list. If the destination account needs to be chained through multiple roles, specify them in order (the latest role to be assumed should be on the lastest position of the json role list) more information

Once letme can retrieve the role, it will request some AWS STS temporary credentials using the AWS Go SDK. Note that the request will always come from the account which holds the profile aws_source_profile.

If the IAM role has a multi factor authentication condition:

"Condition": {
    "BoolIfExists": { 
      "aws:MultiFactorAuthPresent" : "true" 
  }
}

You will need to set the mfa_arn to your mfa device for the profile specified under aws_source_profile, afterwards, letme will ask you to provide the mfa token. If the token is valid, you will get the new credentials written or overwritten (if they already exist from a previous letme obtain call) (image step 2) and you will be able to call resources (image step 3) from that AWS account (image step 4).

If you wish to cache some queries, you must run letme init which will create a file containing all of the accounts from your DynamoDB table. This will speed up response times and save you some extra billing at the end of the month. The downside is that you will be working with a copy, so if anyone updates the DynamoDB, you will need to rerun letme init in order to update your local file against the remote DynamoDB table. It is recommended to run letme init before obtaining credentials.

Multi-account role chaining (added in v0.1.5)

You can also assume a role through a series of IAM roles (also known as IAM role chaining). Note the diagram below to clarify. The initiator role (Role 1 in diagram), should only be accesed based on a true multi factor authentication condition (see above).

Role2 and Role3 IAM role's trust relationships should use arn of the previous role as princial. E.g: Role2 trust relationship.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:sts::ACCOUNT1:assumed-role/role/role1"
            },
            "Action": [
                "sts:AssumeRole",
                "sts:TagSession"
            ]
        }
    ]
}

This approach grants another layer of security, using a bastion aws account to track and centralize assume role requests [5]. When you create a multi-account role chaining on your DynamoDB table, you should specify the roles in order:

Using the letme account structure, the roles should be placed

{
 "id": 123456789,
 "name": "example1",
 "description": "This is a skeleton for an aws account named example1 which will be assumed through an IAM Role (or a chained IAM role list).",
 "region": [
  "eu-west-1",
  "eu-central-1"
 ],
 "role": [
  "arn:aws:iam::ACCOUNT1:role/role1",
  "arn:aws:iam::ACCOUNT2:role/role2",
  "arn:aws:iam::ACCOUNT3:role/role3"
 ]
}

Roles should have sufficient IAM permissions to perform sts:AssumeRole on the next IAM role. E.g. role1 permission policies:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PermissionToAssumeRole2",
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::ACCOUNT2:role/role2"
        }
    ]
}

The following is an example output when assuming through multiple roles

~ $ letme obtain Account3
Using default session name: mySession
More than one role detected. Total hops: 3
[1/3] 
Enter MFA one time pass code: 123456
[2/3] 
[3/3] 
letme: use the argument '--profile Account3' to interact with the account.

Some important notes regarding this approach:

Currently, letme only supports using MFA authentication for the first role.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
pkg
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL