Skip to content

Instantly share code, notes, and snippets.

@jimathyp
Last active February 2, 2023 21:19
Show Gist options
  • Save jimathyp/181528d9193fba00005330991c6de79e to your computer and use it in GitHub Desktop.
Save jimathyp/181528d9193fba00005330991c6de79e to your computer and use it in GitHub Desktop.
aws-vault usage

aws-vault

WIP

Intro

https://github.com/99designs/aws-vault

aws-vault is a command line tool used to:

  • run a process using AWS credentials
  • provide a login link to use to login into the AWS console (via browser). It can also open the browser directly.

Links on usage


Installation

v6.3.1

URL=https://github.com/99designs/aws-vault/releases/download/v6.3.1/aws-vault-linux-amd64
curl -O -L $URL
chmod +x aws-vault-linux-amd64
sudo mv aws-vault-linux-amd64 /usr/local/bin/aws-vault
  • The curl option -L means follow redirects. -O means to save to a local filename the same as the remote file

Check that aws-vault is available (aws-vault) as it should be on the PATH (which aws-vault and echo $PATH)


Setup

  • login to base account as user

  • create access key, note access key and secret access key

  • run

      #mkdir ~/.awsvault/
      echo "export AWS_VAULT_FILE_PASSPHRASE=yourpass" > ~/.awsvault/awsvault
      chmod 400 ~/.aws/awsvault
      # aws-vault add <profile_name> --backend=file
    

in .bash_profile add:

source ~/.awsvault/awsvault

then run

source ~/.bash_profile

To add a login; add credentials for the base user (but cannot login using aws-vault as this user directly. These creds are used by roles we add later)

aws-vault add <name> --backend=file

enter access and secret access when asked and set a passphrase for the local cred file

NB: not sure backend=file is necessary, since we export AWS_VAULT_BACKEND=file later


Environment variables

When running in aws-vault exec <profile_name> these environment variables are added to the shell:

AWS_REGION
AWS_DEFAULT_REGION
AWS_VAULT
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_SESSION_TOKEN
AWS_SECURITY_TOKEN
AWS_CREDENTIAL_FILE
AWS_DEFAULT_PROFILE
AWS_PROFILE
AWS_SDK_LOAD_CONFIG
AWS_SESSION_EXPIRATION

Errors

aws-vault: error: Specified keyring backend not available

Add to ~/.bash_profile

export AWS_VAULT_BACKEND=file

aws-vault: error: exec: Error execing process: cannot allocate memory

$ aws-vault exec <profile_name> -- aws s3 ls 
aws-vault: error: exec: Error execing process: cannot allocate memory

Had a memory leak in another process.

aws-vault: error: login: Failed to get credentials

aws-vault: error: login: Failed to get credentials for <awsvault_profile>: AccessDenied: User:
arn:aws:iam::<aws_account>:user/<aws_user_name> is not authorized to perform: sts:GetFederationToken
on resource: arn:aws:sts::<aws_account>:federated-user/<aws_username> with an explicit deny

"Other AWS STS API operations that return temporary credentials do not support MFA. ... For GetFederationToken, MFA is not necessarily associated with a specific user."

GetFederationToken api call which is used for profiles without role_arn does not support MFA

Fix:

  • Login with user with iam:CreateRole permission
  • Create policy
  • "Assume-XRole"
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Condition": {
                    "Bool": {
                        "aws:MultiFactorAuthPresent": "true"
                    }
                },
                "Action": "sts:AssumeRole",
                "Resource": [
                    "arn:aws:iam::<account>:role/<rolename>"            ],
                "Effect": "Allow",
                "Sid": "AssumeRole"
            }
        ]
    }
  • Create Role 'AssumeAdmin'

    • IAM, create role
    • another aws account (use same account)
    • require MFA
    • attach policy created above
  • Create role 'Admin'

    • another aws account (this one)
    • require MFA
    • Add role Adminaccess
  • Create Group

    • Add user to group
    • add permissions: assumerole
  • aws-vault: now to add that role. Don't use 'aws-vault add ' as this adds to the aws-vault cred store and you need an access key for that (we have a user - which we have an access key, and we want to use that user to assume a role which has no access key)

  • edit the standard aws config file ~/.aws/config

  • see https://github.com/99designs/aws-vault#roles-and-mfa

    [profile foo-admin]
    source_profile = jonsmith
    role_arn = arn:aws:iam::22222222222:role/Administrator
    mfa_serial = arn:aws:iam::111111111111:mfa/jonsmith

aws-vault: error: login: Failed to get credentials for...

aws-vault: error: login: Failed to get credentials for <role>: AccessDenied: User:
arn:aws:iam::<account>:user/<user> is not authorized to perform: sts:AssumeRole on resource:
    arn:aws:iam::<account>:role/<role from config>
  • Add MFA serial
  • make sure group has the assume admin policy attached

STS Token expired


Example .aws/config

 [profile user-account]

 [profile otheraccount-somerole]
 source_profile = user_account
 role_arn = some_arn
 mfa_serial = user_mfa_arn

The config file is the same as used for the aws-cli - see https://docs.aws.amazon.com/cli/latest/topic/config-vars.html

When using aws-vault to login using a role, the name in the top right console will be "/@..."

where role name comes from the role_arn=arn:aws:iam::<account>:role/<role-name> line.

To make it clearer which account/what role you are using I add the following the to the ~/.aws/config

    role_session_name=some_name

Discussion

aws-vault - federation. Main point of federation is centralization of identity and privileges. Only one identity that counts as you. Can federate to other identities, but cannot federate using those identities elsewhere.

Can switch to the service account, but the service account cannot switch to anything else

Returns a set of temporary security credentials (consisting of an access key ID, a secret access key, and a security token) for a federated user.


config file

Add region

    [default]
    region = us-east-1

the config file is not specific to aws-vault. It is also used by the aws-cli.

Other options include

    output=text
    output=json
    include_profile=some_other

Can use the .aws/credential (or config) file to tell application how to get aws credentials for a profile

    [admin]
    credential_process = aws-vault exec admin --no-session --json
    
    # or
    credential_process = ~/bin/call-aws-vault.sh my_new_profile

or create add SSM parameter and create script call-aws-vault.sh (https://hands-on.cloud/how-to-securly-manage-connections-to-multiple-aws-accounts/)

    mkdir -p $HOME/bin
    cat > $HOME/bin/call-aws-vault.sh <<- EOF
    #!/usr/bin/env bash

    export PROFILE=$1
    export AWS_VAULT_FILE_PASSPHRASE=$(aws ssm get-parameters --profile default --names '/laptop/aws-vault/password' --with-decryption --query 'Parameters[0].Value' --output text)

    aws-vault exec -j $PROFILE
    EOF

    chmod +x $HOME/bin/call-aws-vault.sh

Can mean we can run a command without aws-vault prepended, eg:

    aws --profile admin s3 ls

credential_source

credential_source can be Environment, Ec2InstanceMetadata, EcsContainer (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-role.html)

Specifying a role session name for easier auditing

https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-role.html#cli-configure-role-session-name

session_name

    [profile namedsessionrole]
    role_arn = arn:aws:iam::234567890123:role/SomeRole
    source_profile = default
    role_session_name = Session_Maria_Garcia

This results in the role session having the following ARN.

    arn:aws:iam::234567890123:assumed-role/SomeRole/Session_Maria_Garcia

Before, in top right of console you would have:

    role_name/1623032412770877500

Discussion on role usage

End result, don't need a ~/.aws/credentials file (all in aws-vault)

Check if you can assume role

aws sts get-caller-identify
aws sts get-caller-identity --profile another_account_role

config file

https://docs.aws.amazon.com/cli/latest/topic/config-vars.html

aws-vault uses the ~/.aws/config file. aaws-vault v6 also recognizes a include_profile option (v5 = parent_profile) (not recognized by the aws-cli) where the included profile is used as a code fragment (rather than as a parent profile as for source_profile).

Using this, this is how you can have common mfa_serial for each profile (otherwise when using source_profile, mfa_serial must be listed in each profile).

aws cli

Issues

Region in config file not being recognized.

When running code commit create repo. Not sure on this one. It works for listing bucket in a region. Fixed. Region must be under [default] profile not only [source_profile]

Session durations

aws-vault uses Amazon's STS service to generate temporary credentials via the GetSessionToken or AssumeRole API calls. These expire in a short period of time, so the risk of leaking credentials is reduced.


https://aws.amazon.com/console/faq-console/#session_expire

Q: When does my session expire?

For security purposes, a login session will expire 12 hours after you sign in to the AWS Management Console with your AWS or IAM account credentials. To resume your work after the session expires, choose Click login to continue and log in again. The duration of federated sessions varies depending on the federation API (GetFederationToken or AssumeRole) and the administrator’s preference. Please go to our Security Blog to learn more about building a secure delegation solution to grant temporary access to your AWS account.


https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html

AssumeRole* API operation - SessionDuration from 900-43200 seconds (15 min - 12h)

GetFederationToken API - DurationSeconds from 900-129600 sec (36 h)

Difference between the lifetime of the federation endpoint URL (15 min) and the duration of the temporary credential session associated with the URL. ie. you have 15 min to login, once you do, you have the duration you specified (starting from when it was created).


https://aws.amazon.com/blogs/security/understanding-the-api-options-for-securely-delegating-access-to-your-aws-account/

Comes down to where you want to maintain the policies associated with your federated users:

  • in organization: use GetFederationToken.
  • in AWS: use AssumeRole.

https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html Temporary security credentials in IAM

Regions. STS is a global service, but you can choose to use regional endpoints to reduce latency. But the credentials work globally.

use cases:

Open link

Using WSL with Windows Terminal, Ctrl Click on the link aws-vault login link will open a browser window.

'wslview' is a fake WSL browser that will open windows's default browser

Can just change default browser in windows settings

A BROWSER envrionment variable can be used to open browser of your choice (export BROWSER=..., add to bash_profile etc)

AWS Vault SSO

aws-vault

** merged several gists - to be edited **

https://github.com/99designs/aws-vault


Installation

v6.2.0 v6.3.1

URL=https://github.com/99designs/aws-vault/releases/download/v6.3.1/aws-vault-linux-amd64
curl -O -L $URL
chmod +x aws-vault-linux-amd64
sudo mv aws-vault-linux-amd64 /usr/local/bin/aws-vault

follow redirects

aws-vault should thne be on the PATH (echo $PATH)


Setup

  • login to identify account as user

  • create access key, note access key and secret access key

  • run

      #mkdir ~/.awsvault/
      echo "export AWS_VAULT_FILE_PASSPHRASE=yourpass" > ~/.awsvault/awsvault
      chmod 400 ~/.aws/awsvault
      # aws-vault add <profile_name> --backend=file
    

in .bash_profile add:

source ~/.awsvault/awsvault

then run

source ~/.bash_profile

To add a login; add credentials for the base user (but cannot login using aws-vault as this user directly. These creds are used by roles we add later)

aws-vault add <name> --backend=file

enter access and secret access when asked and set a passphrase for the local cred file

nb not sure backend=file is necessary, since we export AWS_VAULT_BACKEND=file later

https://github.com/99designs/aws-vault


Environment variables

AWS_REGION
AWS_DEFAULT_REGION
AWS_VAULT
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_SESSION_TOKEN
AWS_SECURITY_TOKEN
AWS_CREDENTIAL_FILE
AWS_DEFAULT_PROFILE
AWS_PROFILE
AWS_SDK_LOAD_CONFIG
AWS_SESSION_EXPIRATION

Errors

aws-vault: error: Specified keyring backend not available, try --help

Add to ~/.bash_profile

export AWS_VAULT_BACKEND=file

aws-vault: error: exec: Error execing process: cannot allocate memory

$ aws-vault exec profile-name -- aws s3 ls 
aws-vault: error: exec: Error execing process: cannot allocate memory

had a memory leak in another process

aws-vault: error: login: Failed to get credentials

aws-vault: error: login: Failed to get credentials for <awsvault_profile>: AccessDenied: User: arn:aws:iam::<aws_account>:user/<aws_user_name> is not authorized to perform: sts:GetFederationToken on resource: arn:aws:sts::<aws_account>:federated-user/<aws_username> with an explicit deny

"Other AWS STS API operations that return temporary credentials do not support MFA. ... For GetFederationToken, MFA is not necessarily associated with a specific user."

GetFederationToken api call which is used for profiles without role_arn does not support MFA

    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Condition": {
                    "Bool": {
                        "aws:MultiFactorAuthPresent": "true"
                    }
                },
                "Action": "sts:AssumeRole",
                "Resource": [
                    "arn:aws:iam::<account>:role/<rolename>"            ],
                "Effect": "Allow",
                "Sid": "AssumeRole"
            }
        ]
    }
  • Create Role 'AssumeAdmin'

    • IAM, create role
    • another aws account (use same account)
    • require MFA
    • attach policy created above
  • Create role 'Admin'

    • another aws account (this one)
    • require MFA
    • Add role Adminaccess
  • Create Group

    • Add user to group
    • add permissions: assumerole
  • aws-vault: now to add that role. Don't use 'aws-vault add ' as this adds to the aws-vault cred store and you need an access key for that (we have a user - which we have an access key, and we want to use that user to assume a role which has no access key)

  • edit the standard aws config file ~/.aws/config

  • see https://github.com/99designs/aws-vault#roles-and-mfa

    [profile foo-admin]
    source_profile = jonsmith
    role_arn = arn:aws:iam::22222222222:role/Administrator
    mfa_serial = arn:aws:iam::111111111111:mfa/jonsmith

aws-vault: error: login: Failed to get credentials for...

aws-vault: error: login: Failed to get credentials for <role>: AccessDenied: User: arn:aws:iam::<account>:user/<user> is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::<account>:role/<role from config>
  • Add MFA serial
  • make sure group has the assume admin policy attached

Example .aws/config

 [profile user-account]

 [profile otheraccount-somerole]
 source_profile = user_account
 role_arn = some_arn
 mfa_serial = user_mfa_arn

Links


Discussion

aws-vault - federation. Main point of federation is centralization of identiy and privileges. Only one identity that counts as you. Can federate to other identities, but cannot federate using those identities elsewhere.

Can switch to the service account, but the service account cannot swithc to anything else

Returns a set of temporary security credentials (consisting of an access key ID, a secret access key, and a security token) for a federated user.

config file

Add region

    [default]
    region = us-east-1

the config file is not specific to aws-vault. It is also used by the aws-cli.

Other options include

    output=text
    output=json
    include_profile=some_other

Can use the .aws/credential (or config) file to tell application how to get aws credentials for a profile

    [admin]
    credential_process = aws-vault exec admin --no-session --json
    
    # or
    credential_process = ~/bin/call-aws-vault.sh my_new_profile

or create add SSM parameter and create script call-aws-vault.sh [2]

    mkdir -p $HOME/bin
    cat > $HOME/bin/call-aws-vault.sh <<- EOF
    #!/usr/bin/env bash

    export PROFILE=$1
    export AWS_VAULT_FILE_PASSPHRASE=$(aws ssm get-parameters --profile default --names '/laptop/aws-vault/password' --with-decryption --query 'Parameters[0].Value' --output text)

    aws-vault exec -j $PROFILE
    EOF

    chmod +x $HOME/bin/call-aws-vault.sh

Can mean can run a command without aws-vault prepended, eg:

    aws --profile admin s3 ls

Discussion on role usage

End result, don't need a ~/.aws/credentials file (all in aws-vault)

Check if you can assume role

aws sts get-caller-identify
aws sts get-caller-identity --profile another_account_role

config file

https://docs.aws.amazon.com/cli/latest/topic/config-vars.html

aws-vault uses the ~/.aws/config file. aaws-vault v6 also recognizes a include_profile option (v5 = parent_profile) (not recognized by the aws-cli) where the included profile is used as a code fragment (rather than as a parent profile as for source_profile).

Using this, this is how you can have common mfa_serial for each profile (otherwise when using source_profile, mfa_serial must be listed in each profile).

aws cli

Issues

Region in config file not being recognized.

When running code commit create repo. Not sure on this one. It works for listing bucket in a region. Fixed. Region must be under [default] profile not only [source_profile]

Session durations

https://aws.amazon.com/console/faq-console/#session_expire

Q: When does my session expire?

For security purposes, a login session will expire 12 hours after you sign in to the AWS Management Console with your AWS or IAM account credentials. To resume your work after the session expires, choose Click login to continue and log in again. The duration of federated sessions varies depending on the federation API (GetFederationToken or AssumeRole) and the administrator’s preference. Please go to our Security Blog to learn more about building a secure delegation solution to grant temporary access to your AWS account.


https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html

AssumeRole* API operation - SessionDuration from 900-43200 seconds (15 min - 12h)

GetFederationToken API - DurationSeconds from 900-129600 sec (36 h)

Difference between the lifetime of the federation endpoint URL (15 min) and the duration of the temporary credential session associated with the URL. ie. you have 15 min to login, once you do, you have the duration you specified (starting from when it was created).


https://aws.amazon.com/blogs/security/understanding-the-api-options-for-securely-delegating-access-to-your-aws-account/

Comes down to where you want to maintain the policies associated with your federated users:

  • in organization: use GetFederationToken.
  • in AWS: use AssumeRole.

https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html Temporary security credentials in IAM

Regions. STS is a global service, but you can choose to use regional endpoints to reduce latency. But the credentials work globally.

use cases:

aws-vault on WSL troubles

aws-vault: error: login: Failed to get credentials for .... SignatureDoesNotMatch: Signature expired: 20210530T193155Z is now earlier than 20210530T193453Z (20210530T194953Z - 15 min.)
    status code: 403, request id: ......

If computer sleeps - WSL time can be out of sync with Windows OS time.

check time with

date

either restart WSL

# in ps or cmd
wsl --shutdown

or install ntp and run something like

sudo apt install ntpdate

sudo ntpdate -q -sb time.nist.gov
sudo ntpdate pool.ntp.org

# -q query only, don't set the clock
# -s s divert logging from sysout to syslog (use in cron scripts)
# -b force the time to be stepped using the settimeofday)_ syscall. this option should be used when called from a startup file at boot time


# or
sudo hwclock

# or use chrony, or ntpsec

# every 10 min sync crontab
sudo crontab -e, then add:
10 * * * * ntpdate time.windows.com

https://stackoverflow.com/questions/65086856/wsl2-clock-is-out-of-sync-with-windows

microsoft/WSL#4245 system date is not same with windows (WSL 2) #4245

microsoft/WSL#5324 WSL2 date incorrect after waking from sleep #5324

microsoft/WSL#5324 (comment) We've identified the root cause of this issue! This is caused by a Linux kernel bug, that has been fixed at https://kernel.org (patch 1 and patch 2). We're working on building a new kernel version that will include these changes, and will then be making that new kernel version available via Microsoft Update as per usual! I'll post any updates to this thread when I have them. :) https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/hv/hv_util.c?id=b46b4a8a57c377b72a98c7930a9f6969d2d4784e https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/hv/hv_util.c?id=90b125f4cd2697f949f5877df723a0b710693dd0

cat /proc/version
Linux version 5.4.72-microsoft-standard-WSL2

AWS Vault Setup

Environment variables

https://github.com/99designs/aws-vault/blob/master/USAGE.md#environment-variables

cat << EOF >> ~/.bash_profile.append
export AWS_VAULT_BACKEND=file

# optional
export AWS_VAULT_FILE_PASSPHRASE=
EOF

Adding roles

Add the 'base' user with access key id and secret access key

Then in config manually add the roles Add the source profile Add the role arn Add the MFA serial

Using another config file

https://github.com/99designs/aws-vault

https://github.com/99designs/aws-vault/blob/master/USAGE.md#environment-variables

AWS_CONFIG_FILE: The location of the AWS config file

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment