Managing credentials in PowerShell

0

I am looking to improve and simplify two PowerShell scripts. As requirements evolved, so did the scripts. However, I think they are more complex than they need to be but somewhat stumped. My goals are a) load credentials the best way from SAML so that they can be used as the default profile with the PowerShell tools, be available in the .NET SDK for Visual Studio, and usable by Terraform/Packer.

  1. The first script is to set up the credentials from a SAML assertion. Because the initial use-case was for Terraform/Packer, I originally was just setting the environment variables. In order to add support for Visual Studio, I then added a profile. Should I be doing anything differently to store the credentials as the default profile within PowerShell?
$resp = Use-STSRoleWithSAML -PrincipalArn $PrincipalArn -RoleArn $RoleArn  -SAMLAssertion $SamlResponse -DurationInSeconds $duration
Set-AWSCredential -AccessKey $resp.Credentials.AccessKeyId -SecretKey $resp.Credentials.SecretAccessKey -SessionToken $resp.Credentials.SessionToken -StoreAs SAMLsession
$env:AWS_ACCESS_KEY_ID = $resp.Credentials.AccessKeyId
$env:AWS_SECRET_ACCESS_KEY = $resp.Credentials.SecretAccessKey
$env:AWS_SESSION_TOKEN = $resp.Credentials.SessionToken
  1. Now that I have credentials, I often switch roles. Currently, I obtain the credentials and pass via the -Credential switch. However, if I forget to include the switch, I interact with the wrong account. Is there a better way to set the temporary credentials as the default and restore the original later? This is often done because I can assume role into multiple accounts from the master, and I often will iterate through them. In this case, I only care about the PowerShell profile as I don’t need this iteration for Visual Studio and saving the environment variables should be easy enough.
$awsaccounts = Get-ORGAccountList | Where-Object {$_.Status -eq "ACTIVE"}
ForEach ($awsaccount in $awsaccounts) { 
	$Creds = (Use-STSRole -RoleArn "arn:aws:iam::$($awsaccount.Id):role/OrganizationAccountAccessRole" -RoleSessionName "$env:USERNAME").Credentials
	$instances = Get-EC2Instance -Credential $Creds
	#Stuff
}
rsrcno
asked 6 years ago1426 views
2 Answers
0

At this time our Visual Studio toolkit does not support credential profiles based on SAML or other temporary credentials. The only profiles it will show are those containing long-term access and secret keys. We have a backlog item to expand this, but no ETA that I can share at this time.

If you are using SAML in conjunction with ADFS and our Windows PowerShell module (AWSPowerShell) then the tools contain a couple of cmdlets to make working with federated credentials easier than having to poke them into environment variables and manage the rotation yourself. Take a look at Set-AWSSamlEndpoint and Set-AWSSamlRoleProfile. These take your federated identity and create a credential profile that will

(1) prompt you for a password if not domain joined, when credentials need to be generated
(2) automatically refresh when the generated credentials expire

You use the profile they create in the same way as other credential profiles with the PowerShell tools. These docs - https://docs.aws.amazon.com/powershell/latest/userguide/saml-pst.html - and an (old) blog post may help - https://aws.amazon.com/blogs/developer/new-support-for-federated-users-in-the-aws-tools-for-windows-powershell/

AWS
Steve
answered 6 years ago
0

We are unfortunately not using ADFS.

I believe I solved the issue for my use case. I definitely have some cleaning up to do, but I think this is 95% of the way there. Please critique.

When getting credentials, in addition to save the credentials as SAMLsession, I can save it without -StoreAs. This will set it as the default credentials for PowerShell.

resp = Use-STSRoleWithSAML -PrincipalArn $PrincipalArn -RoleArn $RoleArn  -SAMLAssertion $SamlResponse -DurationInSeconds $duration
Set-AWSCredential -AccessKey $resp.Credentials.AccessKeyId -SecretKey $resp.Credentials.SecretAccessKey -SessionToken $resp.Credentials.SessionToken -StoreAs SAMLsession
Set-AWSCredential -AccessKey $resp.Credentials.AccessKeyId -SecretKey resp.Credentials.SecretAccessKey -SessionToken $resp.Credentials.SessionToken
$env:AWS_ACCESS_KEY_ID = $resp.Credentials.AccessKeyId
$env:AWS_SECRET_ACCESS_KEY = $resp.Credentials.SecretAccessKey
$env:AWS_SESSION_TOKEN = $resp.Credentials.SessionToken

Every time I assume role, I can use Set-AWSCredentials again to move the assumed role into the default

$awsaccounts = Get-ORGAccountList | Where-Object {$_.Status -eq "ACTIVE"}
ForEach ($awsaccount in $awsaccounts) {
	$Creds = (Use-STSRole -RoleArn "arn:aws:iam::$($awsaccount.Id):role/OrganizationAccountAccessRole" -RoleSessionName "$env:USERNAME").Credentials
	Set-AWSCredentials -Credential $Creds
	$instances = Get-EC2Instance
	#Stuff
}

After I'm done looping, I can copy the SAMLsession back into the default and reset the environment variables as well.

Set-AWSCredentials -Credential (Get-AWSCredential -ProfileName SAMLsession)
$env:AWS_ACCESS_KEY_ID = (Get-AWSCredential -ProfileName SAMLsession).GetCredentials().AccessKey
$env:AWS_SECRET_ACCESS_KEY = (Get-AWSCredential -ProfileName SAMLsession).GetCredentials().SecretKey
$env:AWS_SESSION_TOKEN = (Get-AWSCredential -ProfileName SAMLsession).GetCredentials().Token

Again, I'm happy to take feedback on this.

rsrcno
answered 6 years ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions