binbashar / leverage

Binbash Leverage CLI intended to orchestrate Leverage Reference Architecture for AWS (www.binbash.co/leverage)
https://pypi.org/project/leverage/
Apache License 2.0
17 stars 2 forks source link

Enhancement | Improve error reporting when assuming roles with MFA #161

Closed angelofenoglio closed 1 year ago

angelofenoglio commented 1 year ago

Describe the Bug

When a user tries to assume a role to which it has no permissions, the MFA handling script silently asks for a new OTP code instead of failing and informing of the reason.

Expected Behavior

An error message showing that the user has no permission to assume such role and exit.

Steps to Reproduce

Steps to reproduce the behavior:

  1. Go to a layer that requires assuming a role for which your user does not have permission. For example OAAR when your user can only assume DevOps.
  2. Run 'leverage tf plan`
  3. Wait for leverage to request OTP code
  4. Input code
  5. Leverage will ask for the code three times and write apparently garbage as credentials which lead to a failing execution of the command.

Screenshots

user@workstation:~/project/management/global/base-identities$ leverage -v tf plan
[16:01:30.929] DEBUG    Found config file /home/user/project/build.env                                                                                                   
[16:01:30.948] DEBUG    Container configuration:                                                                                                                                                    
                        {                                                                                                                                                                           
                          "image": "binbash/leverage-toolbox:1.2.7-0.1.1",                                                                                                                          
                          "command": "",                                                                                                                                                            
                          "stdin_open": true,                                                                                                                                                       
                          "environment": {                                                                                                                                                          
                            "COMMON_CONFIG_FILE": "/project/config/common.tfvars",                                                                                                                     
                            "ACCOUNT_CONFIG_FILE": "/project/management/config/account.tfvars",                                                                                                        
                            "BACKEND_CONFIG_FILE": "/project/management/config/backend.tfvars",                                                                                                        
                            "AWS_SHARED_CREDENTIALS_FILE": "/root/tmp/project/credentials",                                                                                                            
                            "AWS_CONFIG_FILE": "/root/tmp/project/config",                                                                                                                             
                            "SRC_AWS_SHARED_CREDENTIALS_FILE": "/root/tmp/project/credentials",                                                                                                        
                            "SRC_AWS_CONFIG_FILE": "/root/tmp/project/config",                                                                                                                         
                            "AWS_CACHE_DIR": "/root/tmp/project/cache",                                                                                                                                
                            "SSO_CACHE_DIR": "/root/tmp/project/sso/cache",                                                                                                                            
                            "SCRIPT_LOG_LEVEL": 3,                                                                                                                                                  
                            "MFA_SCRIPT_LOG_LEVEL": 3                                                                                                                                               
                          },                                                                                                                                                                        
                          "entrypoint": "/bin/terraform",                                                                                                                                           
                          "working_dir": "/project/management/global/base-identities",                                                                                                                 
                          "host_config": {                                                                                                                                                          
                            "NetworkMode": "default",                                                                                                                                               
                            "SecurityOpt": [                                                                                                                                                        
                              "label:disable"                                                                                                                                                       
                            ],                                                                                                                                                                      
                            "Mounts": [                                                                                                                                                             
                              {                                                                                                                                                                     
                                "Target": "/project",                                                                                                                                                  
                                "Source": "/home/user/project/devops-tf-infra",                                                                                                          
                                "Type": "bind",                                                                                                                                                     
                                "ReadOnly": false                                                                                                                                                   
                              },                                                                                                                                                                    
                              {                                                                                                                                                                     
                                "Target": "/root/tmp/project",                                                                                                                                         
                                "Source": "/home/user/.aws/project",                                                                                                                                 
                                "Type": "bind",                                                                                                                                                     
                                "ReadOnly": false                                                                                                                                                   
                              },                                                                                                                                                                    
                              {                                                                                                                                                                     
                                "Target": "/root/.ssh",                                                                                                                                             
                                "Source": "/home/user/.ssh",                                                                                                                                      
                                "Type": "bind",                                                                                                                                                     
                                "ReadOnly": false                                                                                                                                                   
                              },                                                                                                                                                                    
                              {                                                                                                                                                                     
                                "Target": "/etc/gitconfig",                                                                                                                                         
                                "Source": "/home/user/.gitconfig",                                                                                                                                
                                "Type": "bind",                                                                                                                                                     
                                "ReadOnly": false                                                                                                                                                   
                              }                                                                                                                                                                     
                            ]                                                                                                                                                                       
                          }                                                                                                                                                                         
                        }                                                                                                                                                                           
[16:01:30.976] DEBUG    Checking for layer /home/user/project/management/global/base-identities...                                                                       
[16:01:30.980] DEBUG    Checking layer /home/user/project/management/global/base-identities...                                                                           
[16:01:30.983] DEBUG    Running with entrypoint: /root/scripts/aws-mfa/aws-mfa-entrypoint.sh -- /bin/terraform                                                                                      
[16:01:30.985] DEBUG    Running command: plan -var-file=/project/config/common.tfvars -var-file=/project/management/config/account.tfvars -var-file=/project/management/config/backend.tfvars                
                        -var="region=us-east-1"                                                                                                                                                     
[19:01:31]   DEBUG      BACKEND_CONFIG_FILE=/project/management/config/backend.tfvars
[19:01:31]   DEBUG      SRC_AWS_CONFIG_FILE=/root/tmp/project/config
[19:01:31]   DEBUG      SRC_AWS_SHARED_CREDENTIALS_FILE=/root/tmp/project/credentials
[19:01:31]   DEBUG      TF_AWS_CONFIG_FILE=/root/.aws/project/config
[19:01:31]   DEBUG      TF_AWS_SHARED_CREDENTIALS_FILE=/root/.aws/project/credentials
[19:01:31]   DEBUG      AWS_REGION=us-east-1
[19:01:31]   DEBUG      AWS_OUTPUT=json
[19:01:31]   INFO       MFA: Found 1 profile/s
[19:01:31]   INFO       MFA: Attempting to get temporary credentials for profile project-management-admin
[19:01:32]   DEBUG      MFA_ROLE_ARN=arn:aws:iam::XXXXXXXXXXXX:role/OrganizationAccountAccessRole
[19:01:32]   DEBUG      MFA_SERIAL_NUMBER=arn:aws:iam::XXXXXXXXXXXX:mfa/user.name
[19:01:33]   DEBUG      MFA_PROFILE_NAME=project-security
[19:01:33]   DEBUG      MFA_TOTP_KEY=
[19:01:33]   DEBUG      TEMP_FILE=/root/tmp/project/cache/project-management-admin
MFA: Please type in your OTP: 745489
[19:01:55]   DEBUG      MFA_TOKEN_CODE=745489
[19:01:59]   DEBUG      MFA_ASSUME_ROLE_OUTPUT=
An error occurred (
[19:01:59]   DEBUG      OTP_FAILED=true
[19:01:59]   DEBUG      RETRIES_COUNT=1
MFA: Please type in your OTP: 018700
[19:02:10]   DEBUG      MFA_TOKEN_CODE=018700
[19:02:14]   DEBUG      MFA_ASSUME_ROLE_OUTPUT=
An error occurred (
[19:02:14]   DEBUG      OTP_FAILED=true
[19:02:14]   DEBUG      RETRIES_COUNT=2
MFA: Please type in your OTP: 000250
[19:02:38]   DEBUG      MFA_TOKEN_CODE=000250
[19:02:41]   DEBUG      MFA_ASSUME_ROLE_OUTPUT=
An error occurred (
[19:02:41]   DEBUG      OTP_FAILED=true
[19:02:41]   DEBUG      RETRIES_COUNT=3
cat: can't open '/root/tmp/project/cache/project-management-admin': No such file or directory
cat: can't open '/root/tmp/project/cache/project-management-admin': No such file or directory
cat: can't open '/root/tmp/project/cache/project-management-admin': No such file or directory
[19:02:41]   DEBUG      AWS_ACCESS_KEY_ID=**************
[19:02:41]   DEBUG      AWS_SECRET_ACCESS_KEY=**************
[19:02:41]   DEBUG      AWS_SESSION_TOKEN=**************

usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:

  aws help
  aws <command> help
  aws <command> <subcommand> help

aws: error: the following arguments are required: value

usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:

  aws help
  aws <command> help
  aws <command> <subcommand> help

aws: error: the following arguments are required: value

usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:

  aws help
  aws <command> help
  aws <command> <subcommand> help

aws: error: the following arguments are required: value

[19:02:44]   INFO       MFA: Credentials written succesfully!
╷
│ Error: error configuring S3 Backend: no valid credential sources for S3 Backend found.
│ 
│ Please see https://www.terraform.io/docs/language/settings/backends/s3.html
│ for more information about providing credentials.
│ 
│ Error: NoCredentialProviders: no valid providers in chain. Deprecated.
│       For verbose messaging see aws.Config.CredentialsChainVerboseErrors
│ 
│ 
│ 
╵

Environment

angelofenoglio commented 1 year ago

I've also noticed that in case there were once-valid cached credentials for the role, it will attempt to use those:

user@workstation:~/project/management/global/base-identities$ leverage -v tf plan
[15:59:44.205] DEBUG    Found config file /home/user/project/build.env                                                                                                   
[15:59:44.226] DEBUG    Container configuration:                                                                                                                                                    
                        {                                                                                                                                                                           
                          "image": "binbash/leverage-toolbox:1.2.7-0.1.1",                                                                                                                          
                          "command": "",                                                                                                                                                            
                          "stdin_open": true,                                                                                                                                                       
                          "environment": {                                                                                                                                                          
                            "COMMON_CONFIG_FILE": "/project/config/common.tfvars",                                                                                                                     
                            "ACCOUNT_CONFIG_FILE": "/project/management/config/account.tfvars",                                                                                                        
                            "BACKEND_CONFIG_FILE": "/project/management/config/backend.tfvars",                                                                                                        
                            "AWS_SHARED_CREDENTIALS_FILE": "/root/tmp/project/credentials",                                                                                                            
                            "AWS_CONFIG_FILE": "/root/tmp/project/config",                                                                                                                             
                            "SRC_AWS_SHARED_CREDENTIALS_FILE": "/root/tmp/project/credentials",                                                                                                        
                            "SRC_AWS_CONFIG_FILE": "/root/tmp/project/config",                                                                                                                         
                            "AWS_CACHE_DIR": "/root/tmp/project/cache",                                                                                                                                
                            "SSO_CACHE_DIR": "/root/tmp/project/sso/cache",                                                                                                                            
                            "SCRIPT_LOG_LEVEL": 3,                                                                                                                                                  
                            "MFA_SCRIPT_LOG_LEVEL": 3                                                                                                                                               
                          },                                                                                                                                                                        
                          "entrypoint": "/bin/terraform",                                                                                                                                           
                          "working_dir": "/project/management/global/base-identities",                                                                                                                 
                          "host_config": {                                                                                                                                                          
                            "NetworkMode": "default",                                                                                                                                               
                            "SecurityOpt": [                                                                                                                                                        
                              "label:disable"                                                                                                                                                       
                            ],                                                                                                                                                                      
                            "Mounts": [                                                                                                                                                             
                              {                                                                                                                                                                     
                                "Target": "/project",                                                                                                                                                  
                                "Source": "/home/user/project/",                                                                                                          
                                "Type": "bind",                                                                                                                                                     
                                "ReadOnly": false                                                                                                                                                   
                              },                                                                                                                                                                    
                              {                                                                                                                                                                     
                                "Target": "/root/tmp/project",                                                                                                                                         
                                "Source": "/home/user/.aws/project",                                                                                                                                 
                                "Type": "bind",                                                                                                                                                     
                                "ReadOnly": false                                                                                                                                                   
                              },                                                                                                                                                                    
                              {                                                                                                                                                                     
                                "Target": "/root/.ssh",                                                                                                                                             
                                "Source": "/home/user/.ssh",                                                                                                                                      
                                "Type": "bind",                                                                                                                                                     
                                "ReadOnly": false                                                                                                                                                   
                              },                                                                                                                                                                    
                              {                                                                                                                                                                     
                                "Target": "/etc/gitconfig",                                                                                                                                         
                                "Source": "/home/user/.gitconfig",                                                                                                                                
                                "Type": "bind",                                                                                                                                                     
                                "ReadOnly": false                                                                                                                                                   
                              }                                                                                                                                                                     
                            ]                                                                                                                                                                       
                          }                                                                                                                                                                         
                        }                                                                                                                                                                           
[15:59:44.251] DEBUG    Checking for layer /home/user/project/management/global/base-identities...                                                                       
[15:59:44.256] DEBUG    Checking layer /home/user/project/management/global/base-identities...                                                                           
[15:59:44.257] DEBUG    Running with entrypoint: /root/scripts/aws-mfa/aws-mfa-entrypoint.sh -- /bin/terraform                                                                                      
[15:59:44.258] DEBUG    Running command: plan -var-file=/project/config/common.tfvars -var-file=/project/management/config/account.tfvars -var-file=/project/management/config/backend.tfvars                
                        -var="region=us-east-1"                                                                                                                                                     
[18:59:44]   DEBUG      BACKEND_CONFIG_FILE=/project/management/config/backend.tfvars
[18:59:44]   DEBUG      SRC_AWS_CONFIG_FILE=/root/tmp/project/config
[18:59:44]   DEBUG      SRC_AWS_SHARED_CREDENTIALS_FILE=/root/tmp/project/credentials
[18:59:44]   DEBUG      TF_AWS_CONFIG_FILE=/root/.aws/project/config
[18:59:44]   DEBUG      TF_AWS_SHARED_CREDENTIALS_FILE=/root/.aws/project/credentials
[18:59:44]   DEBUG      AWS_REGION=us-east-1
[18:59:44]   DEBUG      AWS_OUTPUT=json
[18:59:44]   INFO       MFA: Found 1 profile/s
[18:59:44]   INFO       MFA: Attempting to get temporary credentials for profile project-management-admin
[18:59:45]   DEBUG      MFA_ROLE_ARN=arn:aws:iam::XXXXXXXXXXXX:role/OrganizationAccountAccessRole
[18:59:45]   DEBUG      MFA_SERIAL_NUMBER=arn:aws:iam::XXXXXXXXXXXX:mfa/user.name
[18:59:46]   DEBUG      MFA_PROFILE_NAME=project-security
[18:59:46]   DEBUG      MFA_TOTP_KEY=
[18:59:46]   DEBUG      TEMP_FILE=/root/tmp/project/cache/project-management-admin
[18:59:46]   DEBUG      Found cached credentials in /root/tmp/project/cache/project-management-admin
[18:59:46]   DEBUG      EXPIRATION_DATE=2022-10-20 14:11:28
[18:59:46]   DEBUG      EXPIRATION_TS=1666275088
[18:59:46]   DEBUG      CURRENT_TS=1674586786
[18:59:46]   DEBUG      CURRENT_TS_PLUS_MARGIN=1674588586
MFA: Please type in your OTP: 336593
[19:00:00]   DEBUG      MFA_TOKEN_CODE=336593
[19:00:03]   DEBUG      MFA_ASSUME_ROLE_OUTPUT=
An error occurred (
[19:00:03]   DEBUG      OTP_FAILED=true
[19:00:03]   DEBUG      RETRIES_COUNT=1
[19:00:03]   DEBUG      Found cached credentials in /root/tmp/project/cache/project-management-admin
[19:00:03]   DEBUG      EXPIRATION_DATE=2022-10-20 14:11:28
[19:00:03]   DEBUG      EXPIRATION_TS=1666275088
[19:00:03]   DEBUG      CURRENT_TS=1674586803
[19:00:03]   DEBUG      CURRENT_TS_PLUS_MARGIN=1674588603
MFA: Please type in your OTP: 873009
[19:00:22]   DEBUG      MFA_TOKEN_CODE=873009
[19:00:26]   DEBUG      MFA_ASSUME_ROLE_OUTPUT=
An error occurred (
[19:00:26]   DEBUG      OTP_FAILED=true
[19:00:26]   DEBUG      RETRIES_COUNT=2
[19:00:26]   DEBUG      Found cached credentials in /root/tmp/project/cache/project-management-admin
[19:00:26]   DEBUG      EXPIRATION_DATE=2022-10-20 14:11:28
[19:00:26]   DEBUG      EXPIRATION_TS=1666275088
[19:00:26]   DEBUG      CURRENT_TS=1674586826
[19:00:26]   DEBUG      CURRENT_TS_PLUS_MARGIN=1674588626
MFA: Please type in your OTP: 447371
[19:00:38]   DEBUG      MFA_TOKEN_CODE=447371
[19:00:42]   DEBUG      MFA_ASSUME_ROLE_OUTPUT=
An error occurred (
[19:00:42]   DEBUG      OTP_FAILED=true
[19:00:42]   DEBUG      RETRIES_COUNT=3
[19:00:42]   DEBUG      AWS_ACCESS_KEY_ID=ASIA**************
[19:00:42]   DEBUG      AWS_SECRET_ACCESS_KEY=0WkN**************
[19:00:42]   DEBUG      AWS_SESSION_TOKEN=FwoG**************
[19:00:45]   INFO       MFA: Credentials written succesfully!
╷
│ Error: error configuring S3 Backend: error validating provider credentials: error calling sts:GetCallerIdentity: ExpiredToken: The security token included in the request is expired
│       status code: 403, request id: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX
│ 
│ 
╵