AWS credentials retrieved from AWS SSO not available in PowerShell

See original GitHub issue

Description

Credentials obtained from the AWS CLI v2 via AWS SSO should be available to PowerShell modules

Reproduction Steps

  1. Login via AWS SSO using AWS CLI v2 aws sso login --profile dev
  2. Confirm credentials retrieved aws sts get-caller-identity
  3. Try to use credentials from PowerShell Get-StsCallerIdentity -ProfileName dev. This fails reporting Get-STSCallerIdentity: Value cannot be null. (Parameter ‘Options property cannot be empty: ClientName’)

Environment

  • Build Version: 4.1.10.0
  • OS Info: Windows 10
  • Build Environment: Terminal

This is a 🐛 bug-report

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:1
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
ashishdhingracommented, Jun 4, 2021

With AWS Powershell Tools version 4.1.13.0, the reported error is gone, but now we get another error:

Get-STSCallerIdentity: Assembly AWSSDK.SSOOIDC could not be found or loaded. This assembly must be available at runtime to use Amazon.Runtime.SSOAWSCredentials, AWSSDK.Core, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604.

However, installing and loading 2 more modules resolved the issue: Reference: https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up-windows.html

AWS.Tools modular version

  • Upgrade the AWS Powershell Tools module to latest version 4.1.13.0 using command Update-AWSToolsModule -CleanUp.
  • Install-AWSToolsModule -Name AWS.Tools.SSOOIDC
  • Install-AWSToolsModule -Name AWS.Tools.SSO
  • Import-Module AWS.Tools.SSOOIDC
  • Import-Module AWS.Tools.SSO

AWSPowerShell.NetCore large module

  • Install latest 4.1.13.0 of AWSPowerShell.NetCore using command Install-Module -name AWSPowerShell.NetCore. OR
  • Update to latest 4.1.13.0 of AWSPowerShell.NetCore using commands Uninstall-Module -Name AWSPowerShell.NetCore -AllVersions and Install-Module -name AWSPowerShell.NetCore
  • Import AWSPowerShell.NetCore module using command Import-Module AWSPowerShell.NetCore

Using AWS CLI:

Executing Get-StsCallerIdentity -ProfileName <INSERT-YOUR-PROFILE-NAME-HERE> now works:

Account      Arn
-------      ---                                                                 
139480602983 arn:aws:sts::139480602983:assumed-role/AWSReservedSSO_<<name>>...

@cpaton Please verify the fix using the above steps. Kindly let me know if this issue could be closed.

Thanks, Ashish

1reaction
falloutphilcommented, Apr 22, 2021

Yep - same for me. I can get my sso login to work with the aws cli, and boto3 will piggyback off this for python use, but I don’t seem to be able to login directly using powershell, or piggyback off a cli login like I can in python. The company I work at has now exclusivesly moved over to sso (no access or secret keys) for all AWS logins, so this basically rules out any powershell use with aws, which is a shame.

UPDATE

Some good news - It seems it’s not overly difficult to write a routine to lift the credentials from the AWS CLI and use them in PoSh - I got the crude PoC working below to return EC2 Instances using SSO on PoSh:

So you would login using the normal CLI and SSO:

aws sso login --profile <INSERT-YOUR-PROFILE-NAME-HERE>

And then you can use the temporary token from PoSh with a bit of work:

Import-Module AWSPowerShell.NetCore

# Get the accoundid and rolename
$creds = Get-AWSCredential -ProfileName <INSERT-YOUR-PROFILE-NAME-HERE>

$enc = [system.Text.Encoding]::UTF8
$data = $enc.GetBytes($creds.StartUrl)
$sha1 = New-Object System.Security.Cryptography.SHA1CryptoServiceProvider
$hash = $sha1.ComputeHash($data)

$cacheFile=""
Foreach ($byte in $hash)
{
    $cacheFile+=$byte.ToString("x2")
} 
$cacheFile+='.json'
$fullPathCacheFile = [IO.Path]::Combine($env:USERPROFILE, '.aws', 'sso', 'cache', $cacheFile)

$cacheObject = Get-Content $fullPathCacheFile | ConvertFrom-Json

if ([Datetime]$cacheObject.expiresAt -le (Get-Date))
{
    Write-Error -Message "SSO Cache Expired: $($cacheObject.expiresAt)" -Category AuthenticationError
    exit 1
}

$ssoConfig = [Amazon.SSO.AmazonSSOConfig]::new()
$ssoConfig.RegionEndpoint = [Amazon.RegionEndpoint]::GetBySystemName($cacheObject.region)

$ssoClient = [Amazon.SSO.AmazonSSOClient]::new(
    [Amazon.Runtime.AnonymousAWSCredentials]::new(), 
    $ssoConfig)

$roleCredReq = [Amazon.SSO.Model.GetRoleCredentialsRequest]::new()
$roleCredReq.AccessToken = $cacheObject.accessToken
$roleCredReq.AccountId = $creds.AccountId
$roleCredReq.RoleName = $creds.RoleName

$roleCredRes = $ssoClient.GetRoleCredentialsAsync( $roleCredReq ).GetAwaiter().GetResult()

$sessionCreds = [Amazon.Runtime.SessionAWSCredentials]::new(
    $roleCredRes.RoleCredentials.AccessKeyId,
    $roleCredRes.RoleCredentials.SecretAccessKey,
    $roleCredRes.RoleCredentials.SessionToken)

(Get-EC2Instance -Credential $sessionCreds).Instances

Or if you prefer you can even shadow the original profile and/or set a default - be careful if you do shadow it - the original script will fail if ran twice so more work would be needed to select the non-shadowed version of the profile for the initial call to get the URL… it might make more sense just to append ‘_sso’ or similar to the original profile name to avoid confusion.

$roleCredRes = $ssoClient.GetRoleCredentialsAsync( $roleCredReq ).GetAwaiter().GetResult()

Set-AWSCredential -SessionToken $roleCredRes.RoleCredentials.SessionToken `
                  -AccessKey $roleCredRes.RoleCredentials.AccessKeyId `
                  -SecretKey $roleCredRes.RoleCredentials.SecretAccessKey `
                  -StoreAs <INSERT-YOUR-PROFILE-NAME-HERE> # Shadows the original profile

Initialize-AWSDefaultConfiguration -ProfileName <INSERT-YOUR-PROFILE-NAME-HERE>

(Get-EC2Instance).Instances
Read more comments on GitHub >

github_iconTop Results From Across the Web

Using AWS Credentials - AWS Tools for PowerShell
Each AWS Tools for PowerShell command must include a set of AWS credentials, which are used to cryptographically sign the corresponding web service...
Read more >
AWSCredentialsFactory.TryGetAWSCredentials() returns ...
TryGetAWSCredentials () returns invalid SSOAWSCredentials #1821 ... AWS credentials retrieved from AWS SSO not available in PowerShell ...
Read more >
Never put AWS temporary credentials in the ... - Ben Kehoe
Here's a well-trafficked GitHub issue on the CLI stating credentials stored by the CLI when AWS SSO do not conform to “AWS standards”,...
Read more >
Resolve "Unable to locate credentials" error in Amazon S3
An "Unable to locate credentials" error indicates that Amazon S3 can't find the credentials to authenticate AWS API calls. To resolve this issue, ......
Read more >
The AWS Access Key Id does not exist in our records
It looks like some values have been already set for the environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found