saml2aws
saml2aws copied to clipboard
exec/script ignores credentials as arguments
saml2aws exec --username=.. --password=.. --mfa=TOTP --mfa-token=... --idp-provider=Okta --url=https://... --role=arn:aws:iam.. aws s3 ls
error aws credentials have expired
saml2aws script --username=.. --password=.. --mfa=TOTP --mfa-token=.. --idp-provider=Okta --url=https://... --role=arn:aws:iam::...
error aws credentials have expired
The console
and login
commands work fine, but script
and exec
do not. Am I missing something? I note that the console command still gives an 'expired credentials triggering login' message, so presumably its defaulting to stored credentials and then trying the given credentials from the arguments?
saml2aws console --link --username=.. --password=.. --mfa=TOTP --mfa-token=.. --idp-provider=Okta --url=.. --role=arn:aws:iam::.. --skip-prompt
expired credentials triggering login
Using IDP Account default to access Okta https://..
Authenticating as m.. ...
Selected role: arn:aws:iam::..
Requesting AWS credentials using SAML assertion
Logged in as: arn:aws:sts::..
Your new access key pair has been stored in the AWS configuration
Note that it will expire at 2021-07-17 19:20:09 +0100 BST
Maybe the problem is returning here https://github.com/Versent/saml2aws/blob/cd493549dfd492e4bb16cd5f8d3b0dfae410dc9b/cmd/saml2aws/commands/exec.go#L49-L51
instead of trying to login with the provided creds as per here https://github.com/Versent/saml2aws/blob/cd493549dfd492e4bb16cd5f8d3b0dfae410dc9b/cmd/saml2aws/commands/console.go#L86-L88
Looks like an empty config file is created https://github.com/Versent/saml2aws/blob/cd493549dfd492e4bb16cd5f8d3b0dfae410dc9b/pkg/awsconfig/awsconfig.go#L146
Which is loaded with a default expiry time of 0, which then is counted as expired.
Shouldnt all this logic just be skipped if we provide credentials on the command line?
The discrepancies in behaviour is potentially caused by all the duplicated (but slightly different) code between these commands - it deviates when console
calls loadOrLogin
instead of sharedCreds.Load
which works with the username/password from the command line:
https://github.com/Versent/saml2aws/blob/cd493549dfd492e4bb16cd5f8d3b0dfae410dc9b/cmd/saml2aws/commands/exec.go#L26-L77
https://github.com/Versent/saml2aws/blob/cd493549dfd492e4bb16cd5f8d3b0dfae410dc9b/cmd/saml2aws/commands/console.go#L27-L67
Maybe all this should be extracted out and shared rather than copy/pasted everywhere?
saml2aws login \
--credential-process \
--username=$USERNAME \
--password="$PASSWORD" \
--role "$ROLE" \
--profile "$PROFILE" \
--credentials-file="$CRED" \
--disable-keychain \
--skip-prompt
saml2aws login --credential-process --username=*** --password=*** --role arn:aws:iam::***:role/OktaAdminAccess --profile oktapreview --credentials-file=/var/folders/sk/***/T//saml2aws.oktapreview --disable-keychain --skip-prompt
? Enter verification code ^C
is asking MFA token as well
The naive workaround is to use silent login followed by exec.
#!/bin/bash
set -euo pipefail
saml2aws_credentials_file="$HOME/.aws/saml2aws-credentials"
# Workaround for "credentials have expired" https://github.com/Versent/saml2aws/issues/695#issuecomment-881932210
saml2aws login -a controlplane --quiet --skip-prompt --credentials-file="$saml2aws_credentials_file"
saml2aws exec --exec-profile "$1" -a controlplane --skip-prompt --credentials-file="$saml2aws_credentials_file" aws "${@:2}"
I.e.
./awsx groundcover-managed-dev1 sts get-caller-identity
Better apporach (IMHO) is to use saml2aws credential_process
support (https://github.com/Versent/saml2aws/issues/120), which does renew the auth session upon expiration for aws cli commands.
~/.aws/config
[profile controlplane]
credential_process = /opt/homebrew/bin/saml2aws login -a controlplane --credential-process --skip-prompt --credentials-file /Users/maximveksler/.aws/saml2aws-credentials
[profile groundcover-managed-dev1]
source_profile = controlplane
role_arn = arn:aws:iam::XXXXXXXXXXXXX:role/OrganizationAccountAccessRole
awsx
#!/bin/bash
set -euo pipefail
aws "${@:2}" --profile "$1"
Test
# Authenticated session
maximveksler@Maxims-MBP bin % ./awsx groundcover-managed-dev1 sts get-caller-identity
{
"UserId": "AROAZIMJOEDRK7GH6BPUO:botocore-session-1680564423",
"Account": "XXXXXXXXXXXXX",
"Arn": "arn:aws:sts::XXXXXXXXXXXXX:assumed-role/OrganizationAccountAccessRole/botocore-session-1680564423"
}
# No credentials session
maximveksler@Maxims-MBP bin % rm ~/.aws/saml2aws-credentials
maximveksler@Maxims-MBP bin % ./awsx groundcover-managed-dev1 sts get-caller-identity
{
"UserId": "AROAZIMJOEDRK7GH6BPUO:botocore-session-1680564423",
"Account": "XXXXXXXXXXXXX",
"Arn": "arn:aws:sts::XXXXXXXXXXXXX:assumed-role/OrganizationAccountAccessRole/botocore-session-1680564423"
}
# Expired credentials session
maximveksler@Maxims-MBP bin % sed -i '' '/x_security_token_expires/d' ~/.aws/saml2aws-credentials
maximveksler@Maxims-MBP bin % ./awsx groundcover-managed-dev1 sts get-caller-identity
{
"UserId": "AROAZIMJOEDRK7GH6BPUO:botocore-session-1680564423",
"Account": "XXXXXXXXXXXXX",
"Arn": "arn:aws:sts::XXXXXXXXXXXXX:assumed-role/OrganizationAccountAccessRole/botocore-session-1680564423"
}