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

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
¶
There is no documentation for this package.