Giter VIP home page Giter VIP logo

yawsso's Introduction

yawsso

DOI Pull Request Build Status CodeQL codecov.io coveralls.io codeclimate - Test Coverage codeclimate - Maintainability snyk kandi PyPI - Downloads PyPI PyPI - License

Yet Another AWS SSO - sync up AWS CLI v2 SSO login session to legacy CLI v1 credentials.

See also Release v1.0.0 Notes

Prerequisite

  • Required Python >= 3.7
  • Required AWS CLI v2
  • Assume you have already setup AWS SSO for your organization

Main Use Case

pip install yawsso
  • Do your per normal SSO login and, have at least one active SSO session cache:
aws sso login --profile dev
  • To sync for all named profiles in config (i.e. lazy consensus), then just:
yawsso
  • To sync default profile and all named profiles, do:
yawsso --default
  • To sync default profile only, do:
yawsso --default-only
  • To sync for selected named profile, do:
yawsso -p dev
  • To sync for multiple selected named profiles, do:
yawsso -p dev prod
  • To sync for default profile as well as multiple selected named profiles, do:
yawsso --default -p dev prod
  • To sync for all named profiles start with prefix pattern lab*, do:
(zsh)
yawsso -p 'lab*'

(bash)
yawsso -p lab*
  • To sync for all named profiles start with lab* as well as dev and prod, do:
yawsso -p 'lab*' dev prod
  • Print help to see other options:
yawsso -h
  • Then, continue per normal with your daily tools. i.e.
    • cdk deploy ...
    • terraform apply ...
    • cw ls groups
    • awsbw -L -P dev
    • sqsmover -s main-dlq -d main-queue
    • ecs-cli ps --cluster my-cluster
    • awscurl -H "Accept: application/json" --profile dev --region ap-southeast-2 "https://api..."

Additional Use Cases

Rename Profile on Sync

  • Say, you have the following profile in your $HOME/.aws/config:
[profile dev]
sso_start_url = https://myorg.awsapps.com/start
sso_region = ap-southeast-2
sso_account_id = 123456789012
sso_role_name = AdministratorAccess
region = ap-southeast-2
output = json
cli_pager =
  • You want to populate access token as, say, profile name foo in $HOME/.aws/credentials:
[foo]
region = ap-southeast-2
aws_access_key_id = XXX
aws_secret_access_key = XXX
aws_session_token = XXX
...
  • Do like so:
yawsso -p dev:foo
  • Then, you can export AWS_PROFILE=foo and use foo profile!

Export Tokens

PLEASE USE THIS FEATURE WITH CARE SINCE ENVIRONMENT VARIABLES USED ON SHARED SYSTEMS CAN GIVE UNAUTHORIZED ACCESS TO PRIVATE RESOURCES.

๐Ÿคš START FROM VERSION 1.0.0, yawsso -e EXPORT TOKENS IN ROT13 ENCODED STRING.

  • Use -e flag if you want a temporary copy-paste-able time-gated access token for an instance or external machine.

  • Please note that, it uses default profile if no additional arguments pass.

yawsso -e | yawsso decrypt
export AWS_ACCESS_KEY_ID=xxx
export AWS_SECRET_ACCESS_KEY=xxx
export AWS_SESSION_TOKEN=xxx
  • This use case is especially tailored for those who use default profile and, who would like to PIPE commands as follows.
aws sso login && yawsso -e | yawsso decrypt | pbcopy
  • Otherwise, for a named profile, do:
yawsso -p dev -e | yawsso decrypt
  • Or, right away export credentials into the current shell environment variables, do:
yawsso -p dev -e | yawsso decrypt | source /dev/stdin

Note: โ˜๏ธ are mutually exclusive with the following ๐Ÿ‘‡ auto copy into your clipboard. Choose one, a must!

  • If you have pyperclip package installed, yawsso will copy access tokens to your clipboard instead.
yawsso -e
Credentials copied to your clipboard for profile 'default'
  • You may pip install pyperclip or, together with yawsso as follows.
pip install 'yawsso[all]'

Login

  • You can also use yawsso subcommand login to SSO login then sync all in one go.

๐Ÿ™‹โ€โ™‚๏ธ NOTE: It uses default profile or AWS_PROFILE environment variable if optional argument --profile is absent

yawsso login -h
yawsso login
  • Otherwise you can pass the login profile as follows:
yawsso login --profile dev
  • Due to lazy consensus design, yawsso will sync all named profiles once SSO login has succeeded. If you'd like to sync only upto this login profile then use --this flag to limit as follows.

๐Ÿ‘‰ Login using default profile and sync only upto this default profile

yawsso login --this

๐Ÿ‘‰ Login using named profile dev and sync only upto this dev profile

yawsso login --profile dev --this

๐Ÿ‘‰ Login using named profile dev and sync as foo. See above for more details on renaming, limited to one profile.

yawsso login --profile dev:foo

Login then Export token

  • Exporting access token also support with login subcommand as follows:

๐Ÿ‘‰ Login using default profile, sync only upto this default profile and, print access token

yawsso login -e | yawsso decrypt

๐Ÿ‘‰ Login using named profile dev, sync only upto this dev profile and, print access token

yawsso login --profile dev -e | yawsso decrypt

Auto Login then Sync

  • Like login, you may use yawsso subcommand auto to SSO login then sync all in one go.
  • It will check if SSO session has expired and, if so, yawsso will attempt to auto login again.
yawsso auto -h

(either)
yawsso auto --profile dev

(or)
export AWS_PROFILE=dev
yawsso auto

Set Region

  • You can also set region from the config file to the shared credentials file
  • Do like so:
yawsso -r -p dev
yawsso -r -p dev:foo
yawsso -r auto --profile dev

Encryption

yawsso can encrypt and decrypt some arbitrary string from stdin using ROT13 (a simple letter substitution cipher) as follows.

echo 'Hello this is a test' | yawsso encrypt
Uryyb guvf vf n grfg

echo 'Uryyb guvf vf n grfg' | yawsso decrypt
Hello this is a test

(or Pipe through some text corpus)
cat test.txt | yawsso encrypt

(or on Windows)
type test.txt | yawsso encrypt

This is the same as using trivial Unix tr command as follows.

echo 'Hello this is a test' | tr 'A-Za-z' 'N-ZA-Mn-za-m'
Uryyb guvf vf n grfg

echo 'Uryyb guvf vf n grfg' | tr 'A-Za-z' 'N-ZA-Mn-za-m'
Hello this is a test

Hence, you could also decode yawsso exported tokens using tr command, like so.

yawsso -p dev -e | tr 'A-Za-z' 'N-ZA-Mn-za-m'

Develop

  • Create virtual environment, activate it and then:
make install
make test
python -m yawsso --trace version

(Windows)

python -m venv venv
.\venv\Scripts\activate
pip install ".[dev,test]" .
pytest
python -m yawsso --trace version
  • Create issue or pull request welcome

License

MIT License

License: MIT

yawsso's People

Contributors

bondsb avatar bradsbrown avatar brainstorm avatar codacy-badger avatar dalvarezquiroga avatar frbender avatar mikebourgault avatar supergibbs avatar victorskl avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

yawsso's Issues

yawsso auto without cache

When running yawsso auto if there is a previous AWS SSO cache, it will properly cause the login function to execute and renew the credentials. If there is no cache present, yawsso auto fails with the following error:

Can not find valid AWS CLI v2 SSO login cache in /user/profile/.aws/sso/cache for profile profile-name.

The AWS cache is removed automatically by homebrew updates of the awscli formula.

I suggest that if the cache is empty, but there is valid configuration for SSO, that yawsso auto calls aws sso login or similar, and then performs any needed actions to generate the v1 creds afterward.

Not able to sync all profiles

Hi,

I am currently trying yawsso. I have multiple profiles setup in my config file.
As describe in the doc: running yawsso should sync all profiles in my credentials file, but I have only the default profile which is synced.

When specifying the profile via the option -p it is working.

Rename profile on sync

Not sure if a wider problem but the dotnet sdk doesn't support assuming a role with the source_profile is an SSO config. So yawsso sounds like a great workaround but the sdk decided to prioritize config file over the credentials file. When yawsso syncs I have the source_profile in both files and it still fails.

Feature request to rename a profile on sync so I cound have [profile rolesso] in config and on sync it becomes [role] in the credentials file.

Maybe yawsso -p rolesso:role? From the docs, profile names "can use letters, numbers, hyphens ( - ), and underscores ( _ ), but no spaces."

Relates to aws/aws-sdk-net#1853

Sync fails when values have double-quotes

When parameters have double-quotes, and these values are split for use in a child shell, the split ignores double-quotes, resulting in a " in the parameter, which conflicts with a shell command.

basics

  • yawsso 0.6.2
  • MacOS 12.4
  • AWSCLI 2.7.13
  • bash 3.2.57(1)
  • Python 3.9.12 (via brew)

stack dump

  File "/usr/local/lib/python3.9/site-packages/yawsso/cli.py", line 260, in get_role_max_session_duration
    get_role_success, get_role_output = invoke(cmd_get_role)
  File "/usr/local/lib/python3.9/site-packages/yawsso/cli.py", line 117, in invoke
    output = subprocess.check_output(shlex.split(cmd), stderr=subprocess.STDOUT).decode()
  File "/usr/local/Cellar/[email protected]/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/shlex.py", line 315, in split
    return list(lex)
  File "/usr/local/Cellar/[email protected]/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/shlex.py", line 300, in __next__
    token = self.get_token()
  File "/usr/local/Cellar/[email protected]/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/shlex.py", line 109, in get_token
    raw = self.read_token()
  File "/usr/local/Cellar/[email protected]/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/shlex.py", line 191, in read_token
    raise ValueError("No closing quotation")
ValueError: No closing quotation

debug

--- /usr/local/lib/python3.9/site-packages/yawsso/cli.py	2022-07-28 15:01:52.000000000 -0700
+++ /usr/local/lib/python3.9/site-packages/yawsso/cli.py	2022-07-28 15:01:39.000000000 -0700
@@ -114,4 +114,5 @@
 def invoke(cmd):
     try:
+        print("trying [{}]".format(cmd))
         output = subprocess.check_output(shlex.split(cmd), stderr=subprocess.STDOUT).decode()
         success = True

yields:

trying [aws iam get-role --output json --profile {profilename} --role-name profile_role" --region {region}]
Traceback (most recent call last):
  File "/usr/local/bin/yawsso", line 8, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.9/site-packages/yawsso/cli.py", line 544, in main
    credentials = update_profile(profile_name, config)
  File "/usr/local/lib/python3.9/site-packages/yawsso/cli.py", line 363, in update_profile
    credentials = fetch_credentials_with_assume_role(profile_name, profile)
  File "/usr/local/lib/python3.9/site-packages/yawsso/cli.py", line 272, in fetch_credentials_with_assume_role
    duration_seconds = get_role_max_session_duration(profile_name, profile)
  File "/usr/local/lib/python3.9/site-packages/yawsso/cli.py", line 260, in get_role_max_session_duration
    get_role_success, get_role_output = invoke(cmd_get_role)
  File "/usr/local/lib/python3.9/site-packages/yawsso/cli.py", line 117, in invoke
    output = subprocess.check_output(shlex.split(cmd), stderr=subprocess.STDOUT).decode()
  File "/usr/local/Cellar/[email protected]/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/shlex.py", line 315, in split
    return list(lex)
  File "/usr/local/Cellar/[email protected]/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/shlex.py", line 300, in __next__
    token = self.get_token()
  File "/usr/local/Cellar/[email protected]/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/shlex.py", line 109, in get_token
    raw = self.read_token()
  File "/usr/local/Cellar/[email protected]/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/shlex.py", line 191, in read_token
    raise ValueError("No closing quotation")
ValueError: No closing quotation

Repaired by:

--- .aws/config	2022-07-28 14:33:42.000000000 -0700
+++ .aws/config	2022-07-28 14:33:47.000000000 -0700
@@ -42,3 +42,3 @@
 source_profile = ...
-role_arn = "arn:aws:iam::123456789012:role/profile_role"
+role_arn = arn:aws:iam::123456789012:role/profile_role
 region = ...region...

How does it find aws-cli version?

I am running the command but got this message:

$ yawsso -p 00 -e
Required AWS CLI v2. Found aws-cli/1.18.0 Python/3.7.4 Darwin/20.2.0 botocore/1.12.253

it says AWS Cli version is 1.18.0. However, I have installed v2.

$ aws --version
aws-cli/2.1.22 Python/3.7.4 Darwin/20.2.0 exe/x86_64 prompt/off

how does yawsso find the aws cli version?

Login named profile then print env var issue

yawsso login --profile dev -e

... should/expected to do

  1. invoke login process for named profile dev
  2. then print out exportable env vars for -e flag

Instead, it just shows:

Not an AWS SSO profile nor no source_profile found. Skip syncing profile `default`

Note: in this case console message "Not an AWS SSO profile nor no source_profile found. Skip syncing profile default" is still okay as it just warns the user that the default profile is not SSO profile. However, it finds a bit confusing.

Add login subcommand

Now, one has to do:

aws sso login --profile=dev
yawsso -p dev

Add login subcommand option, so that:

yawsso login --profile dev

... would invoke SSO login then sync the profile (and/or all named profiles) automatically.

yawsso -e only exports Linux form of environment variables

In most cases yawsso works extremely well for both Linux and Windows. There is one exception: the command yawsso -e prefaces each variable with "export " while Windows uses "set ". It would be great to have an option for Windows development as well. Maybe -ew as the option?

Thank you for writing such a great tool.

aws_session_expiration value is incorrect ...uses UTC time rather than the UTC timezone offset

I am based in the UK and we are currently in British Summer Time (BST)
The UTC offset for BST is UTC + 1:00

When I run yawsso it successfully creates the credentials in the 'credential' file for the specific SSO profile. In the credentials profile there is a variable called 'aws_session_expiration'. This variable is populated with the UTC time rather that UTC + 1 for the BST offset. (I assume its the default 1 hour expiry for an assumed role in IAM) . This means that the token has expired before i can use it and I get a token expired error.

Interestingly, if i manually change the 'aws_session_expiration' variable and add 1 hour or remove the aws_session_expiration' variable, the token works correctly ie the token is valid, but the 'aws_session_expiration' variable is written incorrectly or is not required

Also, i cannot find any documentation for this variable in the AWS CLI v1 documentation...
https://docs.aws.amazon.com/cli/latest/topic/config-vars.html

The session_expiration_ variable is written here...
line 80-81

dt_utc = str(datetime.utcfromtimestamp(ts_expires_millisecond / 1000.0).isoformat() + '+0000')

PS
You have done a great job here! This is a fantastic utility and fixes the mess that AWS have created with AWS CLI v2

Improve subcommand and args handling

Python built-in argparse does work well for simple CLI args parsing. But it does not cover well for sub-commands, global/sub-level args help options and growing CLI App use cases.

  • CLI args and help option become a bit convoluted, see L353
  • App logic started needing a bit of dance around it, see L394
  • Introduce unnecessary bug, see #24

Potential solution is refactored to adapt Click or docopt. ... will be trying with Click, first.

ca_bundle ignored for some profiles

At work we have TLS inspection, and I set ca_bundle in the ~/.aws/config file to an appropriate certificate.

Running yawsso only picks up the certificate for my default profile. For other profiles, ca_bundle seems to be ignored. I receive an error:

Error executing command: 'aws sts get-caller-identity'. Exception: SSL validation failed for https://portal.sso.us-east-1.amazonaws.com/federation/credentials?role_name=redacted&account_id=redacted [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1076)

A workaround is to set the environment variable AWS_CA_BUNDLE. This is picked up each time.

New Windows -e process is too restrictive

The change implemented in #69 makes an assumption, that if you are in Windows, you don't use bash or the export syntax.

While it may be correct in some situations, there are Windows environments where bash is being used. It's not a huge deal to transform the PowerShell-compatible output into a bash-compatible one, but it would be great if there was a cli flag that could just say - use a specific style of export temporary variables.

Time formatting error

I just loaded yawsso on a macbook pro with an M1 running python 3.9.1, and it appears to be failing due to datetime formatting issue. I ran a few versions of the command to hopefully help troubleshoot.

โžœ  ~ file $(which python)
/opt/local/bin/python: Mach-O 64-bit executable arm64
โžœ  ~ yawsso --default
Traceback (most recent call last):
  File "/Users/me/.local/bin//yawsso", line 8, in <module>
    sys.exit(main())
  File "/Users/me/.local/pipx/venvs/yawsso/lib/python3.9/site-packages/yawsso/cli.py", line 509, in main
    credentials = update_profile("default", config)
  File "/Users/me/.local/pipx/venvs/yawsso/lib/python3.9/site-packages/yawsso/cli.py", line 345, in update_profile
    credentials = fetch_credentials(profile_name, profile)
  File "/Users/me/.local/pipx/venvs/yawsso/lib/python3.9/site-packages/yawsso/cli.py", line 224, in fetch_credentials
    cached_login = check_sso_cached_login_expires(profile_name, profile)
  File "/Users/me/.local/pipx/venvs/yawsso/lib/python3.9/site-packages/yawsso/cli.py", line 215, in check_sso_cached_login_expires
    expires_utc = parse_sso_cached_login_expiry(cached_login)
  File "/Users/me/.local/pipx/venvs/yawsso/lib/python3.9/site-packages/yawsso/cli.py", line 180, in parse_sso_cached_login_expiry
    expires_utc = datetime.strptime((cached_login["expiresAt"]), datetime_format_in_sso_cached_login)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/_strptime.py", line 568, in _strptime_datetime
    tt, fraction, gmtoff_fraction = _strptime(data_string, format)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/_strptime.py", line 349, in _strptime
    raise ValueError("time data %r does not match format %r" %
ValueError: time data '2020-12-28T23:44:36Z' does not match format '%Y-%m-%dT%H:%M:%SUTC'
โžœ  ~ yawsso
Traceback (most recent call last):
  File "/Users/me/.local/bin//yawsso", line 8, in <module>
    sys.exit(main())
  File "/Users/me/.local/pipx/venvs/yawsso/lib/python3.9/site-packages/yawsso/cli.py", line 540, in main
    credentials = update_profile(profile_name, config)
  File "/Users/me/.local/pipx/venvs/yawsso/lib/python3.9/site-packages/yawsso/cli.py", line 345, in update_profile
    credentials = fetch_credentials(profile_name, profile)
  File "/Users/me/.local/pipx/venvs/yawsso/lib/python3.9/site-packages/yawsso/cli.py", line 224, in fetch_credentials
    cached_login = check_sso_cached_login_expires(profile_name, profile)
  File "/Users/me/.local/pipx/venvs/yawsso/lib/python3.9/site-packages/yawsso/cli.py", line 215, in check_sso_cached_login_expires
    expires_utc = parse_sso_cached_login_expiry(cached_login)
  File "/Users/me/.local/pipx/venvs/yawsso/lib/python3.9/site-packages/yawsso/cli.py", line 180, in parse_sso_cached_login_expiry
    expires_utc = datetime.strptime((cached_login["expiresAt"]), datetime_format_in_sso_cached_login)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/_strptime.py", line 568, in _strptime_datetime
    tt, fraction, gmtoff_fraction = _strptime(data_string, format)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/_strptime.py", line 349, in _strptime
    raise ValueError("time data %r does not match format %r" %
ValueError: time data '2020-12-28T23:44:36Z' does not match format '%Y-%m-%dT%H:%M:%SUTC'

I am not sure if it's python 3.9.1's _strptime behavior has changed in general, on arm, or what. Let me know if I can help troubleshoot it any more or if you need more detail.

KeyError: 'refreshToken' after updating to 1.2.0

After upgrading to yawsso 1.2.0 I'm getting the following:

$ yawsso 
Traceback (most recent call last):
  File "/usr/bin/yawsso", line 33, in <module>
    sys.exit(load_entry_point('yawsso==1.2.0', 'console_scripts', 'yawsso')())
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/yawsso/cli.py", line 229, in main
    credentials = core.update_profile(profile_name, co.config)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/yawsso/core.py", line 279, in update_profile
    credentials = fetch_credentials(profile_name, profile)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/yawsso/core.py", line 149, in fetch_credentials
    role_cred_success, role_cred_output = session_refresh(profile_name, profile, cached_login)
                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/yawsso/core.py", line 131, in session_refresh
    create_token_success, create_token_output = create_access_token(cached_login)
                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/yawsso/core.py", line 96, in create_access_token
    f"--refresh-token {cached_login['refreshToken']}"
                       ~~~~~~~~~~~~^^^^^^^^^^^^^^^^
KeyError: 'refreshToken'

Nothing changed in my environment and downgrading to 1.1.0 fixes it.

Let me know if you need any more information.

redacted trace output

2024-03-15 10:50:56,297 yawsso       TRACE    Logging level: TRACE
2024-03-15 10:50:56,297 yawsso       TRACE    args: Namespace(default=False, default_only=False, profiles=None, bin=None, debug=False, trace=True, export_vars1=False, version=False, region=False, command=None)
2024-03-15 10:50:56,297 yawsso       TRACE    AWS_CONFIG_FILE: /home/emil/.aws/config
2024-03-15 10:50:56,297 yawsso       TRACE    AWS_SHARED_CREDENTIALS_FILE: /home/emil/.aws/credentials
2024-03-15 10:50:56,297 yawsso       TRACE    AWS_SSO_CACHE_PATH: /home/emil/.aws/sso/cache
2024-03-15 10:50:56,297 yawsso       TRACE    Cache SSO JSON files: ['/home/emil/.aws/sso/cache/934cfeb368censored6f278483.json', '/home/emil/.aws/sso/cache/112304e768e6667bd8b7e0f3df49ea691fb9466c.json']
2024-03-15 10:50:56,647 yawsso       DEBUG    aws-cli/2.15.19 Python/3.11.8 Linux/6.7.4-arch1-1 source/x86_64.arch prompt/off
2024-03-15 10:50:56,649 yawsso       DEBUG    Current named profiles in config: ['censored-setup', 'censored:fullaccess', 'censored:readonly', 'censored:ops', 'censored:readonly', ...']
2024-03-15 10:50:56,649 yawsso       DEBUG    Syncing named profiles: ['censored-setup', 'censored:fullaccess', 'censored:readonly', 'censored:ops', 'censored:readonly', 'censored:ops', 'censored:fullaccess', 'censored:readonly', ...']
2024-03-15 10:50:56,649 yawsso       TRACE    Syncing profile... censored-setup: {'sso_start_url': 'https://censored.awsapps.com/start#/', 'sso_region': 'eu-west-1', 'region': 'eu-west-1', 'sso_account_id': 'censored', 'sso_role_name': 'dummy'}
2024-03-15 10:50:56,649 yawsso       TRACE    Using cached SSO login: /home/emil/.aws/sso/cache/934cfeb368censored6f278483.json
2024-03-15 10:50:57,350 yawsso       TRACE    EXCEPTION: 'An error occurred (ForbiddenException) when calling the GetRoleCredentials operation: No access'
2024-03-15 10:50:57,350 yawsso       TRACE    Attempt using SSO refreshToken to generate accessToken
Traceback (most recent call last):
  File "/tmp/.env/bin/yawsso", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/tmp/.env/lib/python3.11/site-packages/yawsso/cli.py", line 229, in main
    credentials = core.update_profile(profile_name, co.config)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/.env/lib/python3.11/site-packages/yawsso/core.py", line 279, in update_profile
    credentials = fetch_credentials(profile_name, profile)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/.env/lib/python3.11/site-packages/yawsso/core.py", line 149, in fetch_credentials
    role_cred_success, role_cred_output = session_refresh(profile_name, profile, cached_login)
                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/.env/lib/python3.11/site-packages/yawsso/core.py", line 131, in session_refresh
    create_token_success, create_token_output = create_access_token(cached_login)
                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/.env/lib/python3.11/site-packages/yawsso/core.py", line 96, in create_access_token
    f"--refresh-token {cached_login['refreshToken']}"
                       ~~~~~~~~~~~~^^^^^^^^^^^^^^^^
KeyError: 'refreshToken'

ValueError on time data again

โฏ pip list | grep yawsso
yawsso              0.6.2
โฏ aws --version
aws-cli/2.2.5 Python/3.9.5 Darwin/19.6.0 source/x86_64 prompt/off

ValueError: time data '2021-05-25T23:20:06Z' does not match format '%Y-%m-%dT%H:%M:%SUTC'

If I manually hack the json file ( fgrep -lr that timestamp in ~/.aws ) to match what the error is giving and yawsso works just fine.

SSO "expiresAt" date format mismatch

After a recent aws-cli update, yawsso breaks with the following exception:

Traceback (most recent call last):
  File "$HOME/.local/bin/yawsso", line 8, in <module>
    sys.exit(main())
  File "$HOME/.local/pipx/venvs/yawsso/lib/python3.8/site-packages/yawsso/cli.py", line 540, in main
    credentials = update_profile(profile_name, config)
  File "$HOME/.local/pipx/venvs/yawsso/lib/python3.8/site-packages/yawsso/cli.py", line 345, in update_profile
    credentials = fetch_credentials(profile_name, profile)
  File "$HOME/.local/pipx/venvs/yawsso/lib/python3.8/site-packages/yawsso/cli.py", line 224, in fetch_credentials
    cached_login = check_sso_cached_login_expires(profile_name, profile)
  File "$HOME/.local/pipx/venvs/yawsso/lib/python3.8/site-packages/yawsso/cli.py", line 215, in check_sso_cached_login_expires
    expires_utc = parse_sso_cached_login_expiry(cached_login)
  File "$HOME/.local/pipx/venvs/yawsso/lib/python3.8/site-packages/yawsso/cli.py", line 180, in parse_sso_cached_login_expiry
    expires_utc = datetime.strptime((cached_login["expiresAt"]), datetime_format_in_sso_cached_login)
  File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/_strptime.py", line 568, in _strptime_datetime
    tt, fraction, gmtoff_fraction = _strptime(data_string, format)
  File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/_strptime.py", line 349, in _strptime
    raise ValueError("time data %r does not match format %r" %
ValueError: time data '2020-12-28T20:47:20Z' does not match format '%Y-%m-%dT%H:%M:%SUTC'
# aws --version
aws-cli/2.1.14 Python/3.9.1 Darwin/19.6.0 source/x86_64 prompt/off

# yawsso --version
yawsso 0.6.0

Relevant issue in aws-java-sdk-v2: aws/aws-sdk-java-v2#2190

I am not sure if this is breaking with an aws-cli update since I cannot find anything relevant in its changelog, so I suspect this might be following a server-side change which updates the expiresAt format to ISO 8601.

yawsso can handle this without breaking compatibility with the old UTC format by doing this:

def parse_sso_cached_login_expiry(cached_login):
    # older versions of aws-cli might use non-standard format with `UTC` instead of `Z`
    expires_at = cached_login["expiresAt"].replace('UTC', 'Z')
    datetime_format_in_sso_cached_login = "%Y-%m-%dT%H:%M:%SZ"
    expires_utc = datetime.strptime(expires_at, datetime_format_in_sso_cached_login)
    return expires_utc

Getting The requested role with name AdministratorAccess does not exist

yawsso is failing saying that AdministratorAccess does not exists... which it doesn't. But SSO has created the following role:

AWSReservedSSO_AdministratorAccess_17b6698160a088de

This used to work for me.

Steps I am taking:

$ aws configure sso
SSO start URL [None]: https://#@#@.awsapps.com/start#/                                                                                                                                                  
SSO Region [None]: us-west-2                                                                                                                                                                                
There are 8 AWS accounts available to you.
Using the account ID #@#@#
The only role available to you is: AdministratorAccess
Using the role name "AdministratorAccess"
CLI default client Region [us-west-2]:                                                                                                                                                                      
CLI default output format [None]:                                                                                                                                                                           
CLI profile name [AdministratorAccess-#@#@#@]: prod-ic                                                                                                                                                

To use this profile, specify the profile name using --profile, as shown:

aws s3 ls --profile prod-ic
$ aws sso login --profile=prod-ic
Attempting to automatically open the SSO authorization page in your default browser.
If the browser does not open or you wish to use a different device to authorize this request, open the following URL:

https://device.sso.us-west-2.amazonaws.com/

Then enter the code:

#@#@#@#@
Successully logged into Start URL: https://#@#@#@.awsapps.com/start#/
$ yawsso
Error executing command: `aws sts get-caller-identity`. Exception: An error occurred (ForbiddenException) when calling the GetRoleCredentials operation: The requested role with name AdministratorAccess does not exist

Expected yawsso should return without error

Automatically log in when sync fails

Hello and thanks for this useful tool!

Our use case is like this:

yawsso --profile x

# if exit code != 0
yawsso --login --profile x

It would be awesome if this could be a single command, doing a sync if possible, and doing login only if necessary.

How does this sound to you?

ValueError: time data '2023-03-16T15:11:53.540Z' does not match format '%Y-%m-%dT%H:%M:%SZ'

Ran into this weird one.. I'm running yawsso on a cron in the background and I noticed it wasn't executing. Here are the logs:

%  /Users/diranged/src/dotfiles/.venv3-darwin/bin/yawsso
Traceback (most recent call last):
  File "/Users/diranged/src/dotfiles/.venv3-darwin/bin/yawsso", line 8, in <module>
    sys.exit(main())
  File "/Users/diranged/src/dotfiles/.venv3-darwin/lib/python3.9/site-packages/yawsso/cli.py", line 225, in main
    credentials = core.update_profile(profile_name, co.config)
  File "/Users/diranged/src/dotfiles/.venv3-darwin/lib/python3.9/site-packages/yawsso/core.py", line 245, in update_profile
    credentials = fetch_credentials(profile_name, profile)
  File "/Users/diranged/src/dotfiles/.venv3-darwin/lib/python3.9/site-packages/yawsso/core.py", line 104, in fetch_credentials
    cached_login = check_sso_cached_login_expires(profile_name, profile)
  File "/Users/diranged/src/dotfiles/.venv3-darwin/lib/python3.9/site-packages/yawsso/core.py", line 95, in check_sso_cached_login_expires
    expires_utc = parse_sso_cached_login_expiry(cached_login)
  File "/Users/diranged/src/dotfiles/.venv3-darwin/lib/python3.9/site-packages/yawsso/core.py", line 60, in parse_sso_cached_login_expiry
    expires_utc = datetime.strptime(expires_at, datetime_format_in_sso_cached_login)
  File "/usr/local/Cellar/[email protected]/3.9.10/Frameworks/Python.framework/Versions/3.9/lib/python3.9/_strptime.py", line 568, in _strptime_datetime
    tt, fraction, gmtoff_fraction = _strptime(data_string, format)
  File "/usr/local/Cellar/[email protected]/3.9.10/Frameworks/Python.framework/Versions/3.9/lib/python3.9/_strptime.py", line 349, in _strptime
    raise ValueError("time data %r does not match format %r" %
ValueError: time data '2023-03-16T15:11:53.540Z' does not match format '%Y-%m-%dT%H:%M:%SZ'

Here's the sso cache'd cred file:

% cat /Users/diranged/.aws/sso/cache/5c6808f7452a7d6e84611eccd4cfc2ca096b1913.json | jq . 
{
  "startUrl": "https://XXX.awsapps.com/start",
  "region": "us-east-1",
  "accessToken": "xxx",
  "expiresAt": "2023-03-16T15:11:53.540Z",
  "clientId": "Q1vjMsXxIFRjaxD-7Da7EHVzLWVhc3QtMQ",
  "clientSecret": "xxx",
  "registrationExpiresAt": "2023-06-11T17:08:17Z",
  "refreshToken": "xxx"
}

And the AWS CLi ver:

% aws --version
aws-cli/2.11.2 Python/3.11.2 Darwin/22.3.0 source/arm64 prompt/off

Error: "no section: 'default'

Testing this out, and we're seeing this error when we try to run it:

% ./.venv3/bin/yawsso                  
No section: 'default'
% ./.venv3/bin/yawsso --version
yawsso 1.1.0
% ./.venv3/bin/yawsso --debug  
2023-03-10 15:53:38,681 yawsso       DEBUG    Logging level: DEBUG
2023-03-10 15:53:38,928 yawsso       DEBUG    aws-cli/2.11.0 Python/3.11.2 Darwin/22.3.0 source/arm64 prompt/off
2023-03-10 15:53:38,928 yawsso       DEBUG    Current named profiles in config: ['default', 'eng']
2023-03-10 15:53:38,928 yawsso       DEBUG    Syncing named profiles: ['default', 'eng']
2023-03-10 15:53:38,929 yawsso       ERROR    No section: 'default'
% 

Any thoughts?

Add parameter to control setting the region in the .aws/credentials file

Hi @victorskl,

I came across the issue reported in #76 because I was wondering why the aws clients are telling me that there is no default region defined in the profile. It has been working before, but then since I updated yawsso I started to have an issue. So actually my request would be the opposite as what is explained in #76. Do you think it would be possible to implement a parameter so that you can define whether you want the region in the credentials file or not? Something like a switch "-r" to tell it to copy the region for example?
yawsso -p dev:foo -r

Tildes aren't being expanded on file paths

Hi!

It looks like some assertions are using the "raw" paths to check for file existence:

yawsso/yawsso/cli.py

Lines 409 to 411 in 75000b1

assert os.path.exists(aws_config_file), f"{aws_config_file} does not exists"
assert os.path.exists(aws_shared_credentials_file), f"{aws_shared_credentials_file} does not exists"
assert os.path.exists(aws_sso_cache_path), f"{aws_sso_cache_path} does not exists"

(the above's from version 0.5, currently available on pip, but it also appears to be present on 0.6rc)

That's leading to failures when the paths contain a tilde (i.e. for the user's home).
I've confirmed that manually expanding the path on the config vars solved it.

$> yawsso 
~/xxx/aws/config does not exists

$> bat ~/xxx/aws/config                                                                                               <aws:stedi>
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
       โ”‚ File: /Users/aisamu/xxx/aws/config
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
   1   โ”‚ [xxx]
   2   โ”‚ region=us-east-1
   3   โ”‚ duration_seconds = 43200
   4   โ”‚
   5   โ”‚ [profile xxx/dev]
   6   โ”‚ ... 

Apparently, the expansion has to be done explicitly on Python ๐Ÿ˜ž: https://stackoverflow.com/a/2057072

Thanks for this super useful tool!

-e should pbcopy exports to clipboard instead of displaying into terminal

Instead of just crudely showing them on the terminal as it is now (making live demos very risky), it should say sth like AWS environment variables copied to your clipboard!.

Should just involve piping to pbcopy (on OSX), most probably there's a better cross-platform way of doing that though.

Either create AWS_SHARED_CREDENTIALS_FILE, or make it more clear it just needs to be created if it doesn't exist yet

I had no version of AWS CLI v1 running on my system ever, so yawsso failed on me by saying ".../.aws/crendetials does not exist".

As a user I did not know that the credentials file just needed to exist as an empty file for the script to work. I had expected, that the tool would "just create" the file if it didn't exist yet.

Maybe the behavior can be changed, or the output could contain something like "please create this as an empty file if you want to use this path". That way a user wouldn't start a search for his/her error.

Does not sync credentials for profiles that use source_profile

The setup I have is one account is the organization account that has the SSO and then there are several other accounts where I use the sso from the org account when assuming a role. Example:

[default]
sso_start_url = https://foo.awsapps.com/start#/
sso_region = us-east-1
sso_account_id = 123456789
sso_role_name = Engineering
region = us-east-1
output = json

[profile dev]
role_arn = arn:aws:iam::456789123:role/FullAdmin
source_profile = default
region = us-east-1
output = json

[profile qc]
role_arn = arn:aws:iam::789123456:role/FullAdmin
source_profile = default
region = us-east-1
output = json

[profile prod]
role_arn = arn:aws:iam::987654321:role/DevOps
source_profile = default
region = us-east-1
output = json

When I run yawsso It works for the default profile but fails on dev:

$ yawsso
2020-06-05 08:47:12,409 yawsso.cli   INFO     yawsso 0.3.0
2020-06-05 08:47:12,900 yawsso.cli   INFO     aws-cli/2.0.17 Python/3.7.3 Linux/4.4.0-174-generic botocore/2.0.0dev21
2020-06-05 08:47:12,903 yawsso.cli   INFO     Current named profiles in config: ['dev', 'qc', 'prod']
2020-06-05 08:47:12,903 yawsso.cli   ERROR    Your `dev` profile is not valid AWS SSO profile. Try `aws configure sso` first.

I would expect that it would get the credentials from the cache in ~/.aws/cli/cache for these source_profile assumed role situations. In fact, if I get those creds and put them in my ~/.aws/credentials then older tools without sso support (like terraform, docker-credential-ecr-login, etc) work fine.

syncing for all named profiles fails when cache for first profile is not active on first time set up

Hello,

Summary
When I try to sync all named profiles with yawsso, it fails unless the first profile in config is cached.

yawsso version
yawsso 0.7.2

aws-cli version
aws-cli/2.7.11 Python/3.10.5 Darwin/21.5.0 source/arm64 prompt/off

system
image

On first time use...

I have 4 sso profiles in my config:

[profile prodDeveloper]
...
[profile prodQABuilder]
...
[profile prodLeadDeveloper]
...
[profile prodAdmin]
...

I have prodAdmin cached, but nothing else and try to run yawsso

โฏ yawsso
Current cached SSO login is expired since 2022-06-30T04:53:01-04:00. Try login again.

โฏ export AWS_PROFILE=prodAdmin

โฏ aws sso login
Attempting to automatically open the SSO authorization page in your default browser.
If the browser does not open or you wish to use a different device to authorize this request, open the following URL:
....
Successfully logged into Start URL: https://d-92677f5210.awsapps.com/start#/

โฏ yawsso
Current cached SSO login is expired since 2022-06-30T04:53:01-04:00. Try login again.

I then login for prodDeveloper and everything works

โฏ export AWS_PROFILE=prodDeveloper

โฏ aws sso login
Attempting to automatically open the SSO authorization page in your default browser.
If the browser does not open or you wish to use a different device to authorize this request, open the following URL:
....
Successfully logged into Start URL: https://staxlabs.awsapps.com/start#/

โฏ yawsso
SUCCESS

I'm not sure if this is also a problem after the first time use, but I wanted to document it while I could.

I'll also try to take a look into the code base, i want more experience with python and hopefully I can hack it out.

yawsso needs to ignore the expiresAt parameter in .aws/sso/cache/<thing>.json

I have been dealing with AWS support for a while and it appears that the expiresAt parameter is not accurate as the refresh token should still be valid.

Yet yawsso just exits out whenever you try to run it after the expiresAt value has passed (which is usually only one hour).

So please just ignore the value and continue to ask for new credentials just as the auto refresh would work within the CLI.

yawsso doesn't recognize new-style SSO profiles

I'm setting up a brand new machine, and it appears that AWS (I'm using CLI v2.9.1 on Windows) has introduced a new kind of SSO configuration since the last time I did this.

In short, by pulling some of the common SSO settings out into their own section in the config, AWS gains the ability to automatically refresh the SSO session credentials that may be used by different profiles.

This is causing problems with yawsso, which is looking for specific keys in the profile section.

Old-style config file

[profile my-profile]
sso_account_id = 12345
sso_role_name = BasicAccess
sso_start_url = https://example.com/start
sso_region = us-east-1

New-style config file

[sso-session MySession]
sso_start_url = https://example.com/start
sso_region = us-east-1
sso_registration_scopes = sso:account:access

[profile my-profile]
sso_session = MySession
sso_account_id = 12345
sso_role_name = BasicAccess
region = us-east-1

can't get aws credentials in cmd line

$ yawsso login --profile profile-name -e
$Rai:NJF_NPPRFF_XRL_VQ=""
$Rai:NJF_FRPERG_NPPRFF_XRL="
"
$Rai:NJF_FRFFVBA_GBXRA="
********************"

I don't understand why it's not providing AWS_ACCESS_KEY which it used to; this is the same output regardless of powershell or gitbash. However, credentials are generated and can see in .aws/credentials file and they do work but not able to see on cmd line.

I have tried uninstalling and installing back.
I am running yawsso 1.0.1 the version

could someone please help.

Many thanks

Fix distutils packaging warning

DEPRECATION: Configuring installation scheme with distutils config files is deprecated and will no longer work in the near future

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.