Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[V2] --access-token should be optional to sso calls #5057

Open
mattwillsher opened this issue Mar 12, 2020 · 11 comments
Open

[V2] --access-token should be optional to sso calls #5057

mattwillsher opened this issue Mar 12, 2020 · 11 comments
Labels
feature-request A feature should be added or improved. p2 This is a standard priority issue sso v2

Comments

@mattwillsher
Copy link

aws sso login creates a cache files in ~/.aws/sso/cache which contains an access token
aws sso list-accounts and list-account-roles requires an access-token.

It would be helpful to have a mechanise to either output the current valid access token or make the argument optional and use the cached value for the current context.

@mattwillsher mattwillsher changed the title --access-token should be optional to sso calls [v2] --access-token should be optional to sso calls Mar 12, 2020
@mattwillsher mattwillsher changed the title [v2] --access-token should be optional to sso calls [V2] --access-token should be optional to sso calls Mar 12, 2020
@KaibaLopez
Copy link
Contributor

Hi @mattwillsher ,
hmm so you're saying that once you're logged in with your sso login, you want to be able to call something --profile "your current login" to use your login's access-token or have something like aws sso get-token ?

@KaibaLopez KaibaLopez self-assigned this Mar 14, 2020
@KaibaLopez KaibaLopez added the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Mar 14, 2020
@mattwillsher
Copy link
Author

mattwillsher commented Mar 16, 2020

Yes @KaibaLopez

I have the following as a workaround in my shell at the moment:

function aws-access-token() { cat $(ls -1d ~/.aws/sso/cache/* | grep -v botocore) |  jq -r "{accessToken} | .[]" }
function aws-list-accounts() { aws sso list-accounts --access-token $(aws-access-token) --output table }

Having a more direct method of getting the access token would help reduce the complexity here. Being able to tell people to just call aws sso list-accounts --output table to get a list of their accounts would be great :)

@KaibaLopez KaibaLopez added feature-request A feature should be added or improved. and removed response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. labels Mar 18, 2020
@taingalls
Copy link

I was just looking for aws sso-oidc get-token so I can use that in conjunction with aws sso get-role-credentials.

@vvdimov
Copy link

vvdimov commented Aug 26, 2020

This is related to #5261.

@skyzyx
Copy link
Contributor

skyzyx commented Mar 1, 2021

Just a note that I recently ran into this, and this thread was helpful (thank you @mattwillsher).

We have hundreds of AWS accounts, and we're just now adopting AWS SSO. Many of us use aws-vault, so converting ALL of those long-term credentials stored in the system keychain over to an AWS SSO configuration in ~/.aws/config was going to be incredibly tedious.

If requiring the access token is required, it would be awesome if you could ask the AWS CLI for just the token cached to disk and a way to read back the value. The instructions I ended up writing for my devs includes asking them to type Ctrl+C after the token is cached, so that it can be read by a script that can update the hundreds of profiles I need to manage, programmatically.

@reidca
Copy link

reidca commented Mar 21, 2022

Came across this today and am confused as to why access token is needed.

I create my session based on a profile name, then create the client from that session.

session = boto3.Session(profile_name=profile_name)
sso_client = session.client("sso")
accounts_paginator = sso_client.get_paginator("list_accounts")

The session already has the access token so why do I need to provide it to the list-accounts method?

There is no nice way of getting this token either apart from reading it from the ~/.aws/sso/cache file which feels fundamentally wrong.

Or am I missing something?

@tim-finnigan tim-finnigan added the p2 This is a standard priority issue label Nov 9, 2022
@apogrebnyak
Copy link

Here is a workaround to get to the JSON cache file until this issue is fixed:

For AWS cli > 2.13.5 the name of the cache file is the sha1sum of your sso session name in the profile.

local sso_session=$(aws configure get sso_session --profile "${profile}")
local cache_file="${HOME}/.aws/sso/cache/$(echo -n "${sso_session}" | sha1sum | awk '{print $1}').json"

local access_token=$( jq --raw-output .accessToken "${cache_file}")

@reidca
Copy link

reidca commented Sep 29, 2023

Do you know what it uses when the sso_session property for the given profile does not exist? In my case this property is not set in the profile configuration in the config file.

Do you have any documentation that i can refer to?

@reidca
Copy link

reidca commented Oct 2, 2023

i worked it out.

If you are using the old legacy format for your SSO config file then the file is the hash of the sso_start_url, if you are using the new format then it is the sso_session.

See example code in python:

AWS_SSO_CACHE_PATH = os.path.join(str(Path.home()), ".aws/sso/cache")

def identify_profile_key(profile: dict) -> str:
    if "sso_session" in profile:
        logger.info("Profile is associated with SSO token provider configuration.")
        return profile["sso_session"]
    elif "sso_start_url" in profile:
        logger.info("Profile is associated with Legacy non-refreshable configuration.")
        return profile["sso_start_url"]
    else:
        logger.error("Unknown profile configuration.")
        raise Exception("Unknown profile configuration")


def get_sso_cached_login(profile: dict) -> dict:
    # Identify the correct key to use for SHA-1 hash
    try:
        key_to_hash = identify_profile_key(profile)
    except Exception as e:
        logger.error(f"Error identifying profile key: {e}")
        raise

    # Compute the SHA-1 hash to find the cache file
    sha1_hash = hashlib.sha1(key_to_hash.encode()).hexdigest()
    cache_file_path = os.path.join(AWS_SSO_CACHE_PATH, f"{sha1_hash}.json")
    logger.info(f"Computed cache file path: {cache_file_path}")

    # Check if the cache file exists
    if not os.path.exists(cache_file_path):
        logger.error(f"Cache file '{cache_file_path}' does not exist")
        raise Exception(f"Cache file '{cache_file_path}' does not exist")

    # Load the JSON data from the cache file
    with open(cache_file_path, "r") as f:
        data = json.load(f)

    # Check for expiration
    expires_at = data.get("expiresAt")
    if expires_at is None:
        logger.error(f"Missing 'expiresAt' in {cache_file_path}")
        raise Exception(f"Missing 'expiresAt' in {cache_file_path}")

    time_now = datetime.now()
    if time_now > parse_timestamp(expires_at):
        logger.error("Current cached SSO login is expired or invalid")
        raise Exception("Current cached SSO login is expired or invalid")

    logger.info("Successfully validated SSO cache.")
    return data

@deantray
Copy link

I want to aws test-access --profile {profilename} so I can exit script. devs are logged in with SSO and CI/CD is logged in with machine tokens but all use profile to match. is there a way (it seemed so related to this is all).

@evanstucker-hates-2fa
Copy link

I wrote a script to configure all AWS IAM Identity Center (SSO) accounts and roles automatically. It requires AWS CLI v2 and jq. Download the aws_configure_all_sso.sh script here: https://codeberg.org/dedevsecops/aws

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request A feature should be added or improved. p2 This is a standard priority issue sso v2
Projects
None yet
Development

No branches or pull requests