Search code examples
amazon-web-servicespowershellrestauthenticationamazon-cognito

How do I obtain temporary AWS credentials for an unauthenticated role in PowerShell using a Cognito IdentityPool?


I was writing a PowerShell script that needed to access an AWS S3 bucket using an unauthenticated role via Cognito and had trouble finding much documentation. All of the documentation I was able to find for the AWS PowerShell SDK discussed storing your AccessKey and SecretKey but never how to get those credentials using Cognito when you aren't using a user pool.


Solution

  • There may be other ways to do this with PowerShell (I haven't been able to find them yet.) but you can obtain temporary credentials through Cognito using AWS's REST API.

    The following PowerShell example shows how to:

    • Set your REST URL
    • Get an id from the Cognito Identity provider
    • Use the received id to request temporary credentials (AccessKey will begin with AS instead of AK)
    • Set the temporary credentials

    For more information see:

    #Ensure we communicate using TLS 1.2
    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
    function Get-CognitoRestURL {
        param(
            [parameter(Mandatory)]$Region
        )
        return  "https://cognito-identity.{0}.amazonaws.com/" -f $Region
    }
    
    function Get-AWSTempCredentials {
        param(
            [parameter(Mandatory)]$IdentityPoolId,
            [parameter(Mandatory)]$Region
        )
    
        try {
            $cognitoRestURL = Get-CognitoRestURL -Region $Region
            $requestTempId = Invoke-RestMethod -Uri $cognitoRestURL -Method "POST" `
            -Headers @{
                "authority"=$cognitoRestURL
                "x-amz-target"="AWSCognitoIdentityService.GetId"
                "x-amz-user-agent"="aws-powershell callback"
            } -ContentType "application/x-amz-json-1.1" -Body "{`"IdentityPoolId`":`"$($IdentityPoolId)`"}"
        } catch {
            Write-Error $_
            #Request failed, we don't have the data we need to continue
            break
        }
        try {
            $tempCredentials = Invoke-RestMethod -Uri $cognitoRestURL -Method "POST" `
            -Headers @{
                "x-amz-target"="AWSCognitoIdentityService.GetCredentialsForIdentity"
                "x-amz-user-agent"="aws-powershell callback"
            } -ContentType "application/x-amz-json-1.1" -Body "{`"IdentityId`":`"$($requestTempId.IdentityId)`"}"
        } catch {
            Write-Error $_
            #Request failed, we don't have the data we need to continue
            break
        }
    
        return $tempCredentials
    }
    
    function Set-AWSTempCredentials {
        param(
            [parameter(Mandatory)]$AccessKeyId,
            [parameter(Mandatory)]$SecretKey,
            [parameter(Mandatory)]$SessionToken,
            [parameter(Mandatory)]$ProfileName,
            [parameter(Mandatory)]$Region
        )
    
        Set-AWSCredential -AccessKey $AccessKeyId -SecretKey $SecretKey -SessionToken $SessionToken -StoreAs $ProfileName
        return Get-AWSCredential -ProfileName $ProfileName
    }
    
    $region = "us-west-1"
    $IdentityPoolId = "us-west-1:12a01023-4567-123a-bcd1-12345a0b1abc"
    
    $response = Get-AWSTempCredentials -IdentityPoolId $IdentityPoolId -Region $region 
    Set-AWSTempCredentials -AccessKeyId $response.Credentials.AccessKeyId `
                           -SecretKey $response.Credentials.SecretKey `
                           -SessionToken $response.Credentials.SessionToken `
                           -ProfileName MyTempCredentials `
                           -Region $region