AWS Security Blog

How to Set Up Federated API Access to AWS by Using Windows PowerShell

When accessing AWS resources in an organization, we recommend that you have a standard and repeatable authentication method for purposes of security, auditability, compliance, and the capability to support role and account separation. As part of my AWS Professional Services engagements, I have helped AWS customers establish such an authentication mechanism via federated access to the AWS Management Console. Though this was useful, many of those customers also needed the ability to access their AWS resources using our APIs. However, without federated API access, you also would need to create AWS Identity and Access Management (IAM) users, which defeats the purpose of using federation.

In this blog post, I will show how to provide Windows Active Directory users federated API access in Windows PowerShell for use with the AWS Tools for Windows PowerShell by using the newly incorporated SAML support.

This post uses a strategy similar to Quint Van Deman’s blog post, How to Implement a General Solution for Federated API/CLI Access Using SAML 2.0. If you are interested in a generalized way to implement federated API access, I recommend reading that post. 

Prerequisites

To follow this post, you must have:

An overview of an Active Directory user gaining federated access to AWS service APIs

Diagram showing an Active Directory user gaining federated access to AWS service APIs

The preceding diagram shows how an Active Directory user uses AD FS to gain federated access to AWS resources:

  1. AD FS authenticates the federated user.
  2. If authentication is successful, the user is sent a Security Assertion Markup Language (SAML) assertion.
  3. The SAML assertion is sent to the AWS Security Token Service (STS) in the form of an AssumeRoleWithSAML request.
  4. If the request is valid, AWS STS returns an AssumeRoleWithSAML response containing AWS temporary credentials.
  5. The AWS temporary credentials can then be used to interact with AWS service APIs by using tools such as the AWS Tools for Windows PowerShell.

How Windows PowerShell SAML support works

Diagram showing how Windows PowerShell SAML support works

Before I use the Windows PowerShell module, I’ll walk through the preceding diagram, which shows how the process works when using the AWS Tools for Windows PowerShell SAML support:

  1. The Windows PowerShell module authenticates against AD FS by using the Windows user’s current credentials or interactively when the cmdlet is run from the command line.
  2. AD FS authenticates the user.
  3. AD FS generates a SAML authentication response that includes the assertion that identifies the user and provides information about the user. The Windows PowerShell cmdlet then extracts the list of roles the user has permissions to assume from the SAML assertion. AD FS creates a SAML authentication request that is composed of the SAML assertion and the selected AWS role’s Amazon Resource Name (ARN).
  4. AD FS then sends the SAML request to AWS STS using the AssumeRoleWithSAMLRequest API call.
  5. If the SAML request is valid, a SAML response is returned containing the AWS AccessKeyId, SecretAccessKey, and SessionToken. By default, these credentials have a valid duration of 3,600 seconds (1 hour).
  6. Now the AWS Tools for Windows PowerShell will have credentials that are ready to use to interact with any of the AWS service APIs the IAM role is authorized to access. The AWS Tools for Windows PowerShell will automatically use these credentials for any subsequent AWS API calls and renew them automatically when they expire.

How to use the Windows PowerShell SAML cmdlets

If you are ready to get started, open a new Windows PowerShell session and import the AWS Tools for Windows PowerShell module.

PS > Import-Module "C:Program Files (x86)AWS ToolsPowerShellAWSPowerShellAWSPowerShell.psd1"

How to run the Windows PowerShell SAML cmdlets

Let’s configure the endpoint settings for the AD FS system. When specifying the AD FS endpoint, be sure to replace the example AD FS hostname with your own actual AD FS hostname in the endpoint parameter.

PS > $endpoint = "https://adfs.example.com/adfs/ls/Id
pInitiatedSignOn.aspx?loginToRp=urn:amazon:webservices"

To construct the endpoint settings object, we call the Set-AWSSamlEndpoint cmdlet specifying the desired AuthenticationType parameter. Supported types include Basic, Digest, Kerberos, Negotiate, and NTLM, defaulting to Kerberos if not specified.

PS > $epName = Set-AWSSamlEndpoint -Endpoint $endpoint -StoreAs ADFS-Demo -AuthenticationType NTLM

Now, let’s look at how we authenticate with the AD FS identity provider to obtain temporary AWS credentials by using the Set-AWSSamlRoleProfile cmdlet.

To set up a profile for accounts joined to the domain, we do not need to supply credentials.

PS > Set-AWSSamlRoleProfile -StoreAs SAMLDemoProfile -EndpointName $epName

Alternatively, for accounts that are not joined to the domain, you can interactively provide Windows Active Directory credentials and then select an AWS role to which the user has access. This is useful if you use a separate Active Directory user to segregate duties and roles within your organization (for example, administration functions).

PS > $credential = Get-Credential -Message "Enter the domain credentials for the endpoint"

Set-AWSSamlRoleProfile -EndpointName $epName -NetworkCredential $credential -StoreAs SAMLDemoProfile

In both cases the cmdlet will prompt you to select which role should be stored in the profile. In the following example, I select the ADFS-Dev role.

Select Role
Select the role to be assumed when this profile is active
[1] 1 - ADFS-Dev  [2] 2 - ADFS-Production  [?] Help (default is "1"): 1

A specific role can also be specified without being prompted, by supplying the RoleARN, PrincipalARN, and optional NetworkCredential parameters (provided the role is present in the assertion we get after authentication).

PS > $params = @{

    "NetworkCredential"=$credential,   
    "PrincipalARN"="arn:aws:iam::012345678912:saml-provider/ADFS"
    "RoleARN"=" arn:aws:iam::012345678912:role/ADFS-Dev"
}

PS > $epName | Set-AWSSamlRoleProfile @params -StoreAs SAMLDemoProfile1 -Verbose

For computers joined to the domain, you can create profiles for all roles at one time (the role name will be used as the profile name).

PS > Set-AWSSamlRoleProfile -EndpointName $epName -StoreAllRoles
ADFS-Dev
ADFS-Production

The names of the role profiles are what you supply to Set-AWSCredentials (or to any –ProfileName parameter on cmdlets) to automatically get temporary AWS credentials for the role detailed in the profile.

Using the SAMLDemoProfile to interact with AWS service APIs

Now let’s use the temporary AWS credentials obtained by using the SAMLDemoProfile profile to interact with AWS service APIs.

Example 1:

In this example, we will list all the available Amazon S3 buckets in the AWS account of the role we have assumed. This is a common task for administrators managing S3 from the Windows PowerShell command line.

 PS > Get-S3Bucket –ProfileName SAMLDemoProfile

 CreationDate                                                BucketName
 ------------                                                ----------
 7/25/2013 3:16:56 AM                                        mybucket1
 4/15/2015 12:46:50 AM                                       mybucket2
 4/15/2015 6:15:53 AM                                        mybucket3
 1/12/2015 11:20:16 PM                                       mybucket4

Notice how we provided the –ProfileName when we called the Get-S3Bucket cmdlet. The profile manager has made temporary credentials available to the cmdlet.

These credentials will expire after 1 hour (this is a limit enforced by AWS STS). However, the AWS Tools for Windows PowerShell will automatically refresh the credentials by obtaining a new SAML assertion when the tools detect that the current credentials have expired.

For users joined to the domain, this process is invisible because we do not need to prompt users to enter Windows credentials. For users not joined to the domain, the tools will pop up a Windows PowerShell credential prompt requesting the user’s password, which is then used to reauthenticate the user to get a fresh assertion.

Example 2:

Now let’s list all Amazon EC2 instances in the Sydney region using the ADFS-Production profile. You may want to do this to get a list of all the EC2 instances in the region in order to manage your EC2 fleet.

PS > (Get-Ec2Instance –ProfileName ADFS-Production –Region ap-southeast-2).Instances | Select InstanceType, @{Name="Servername";Expression={$_.tags | where key -eq "Name" | Select Value -Expand Value}}

 InstanceType                                                Servername
 ------------                                                ----------
 t2.small                                                    DC2
 t1.micro                                                    NAT1
 t1.micro                                                    RDGW1
 t1.micro                                                    RDGW2
 t1.micro                                                    NAT2
 t2.small                                                    DC1
 t2.micro                                                    BUILD

These examples show only two of many ways to manage your AWS resources by using the temporary credentials provided by Windows PowerShell SAML support. All the cmdlets provided by the AWS Tools for Windows PowerShell will make use of the temporary credentials set by the –ProfileName on any cmdlet. This approach streamlines how you interact with AWS resources without having to create and manage IAM user accounts, and enhances security by always using short-lived temporary credentials.

If you are interested in implementing federated API access to AWS in your own Windows PowerShell cmdlets or C# applications, see the aws-saml-adfs-cmdlet-sample GitHub repository.

We always appreciate your feedback, so please post your questions or suggestions in the “Comments” section below. You can also go to the IAM forum with questions or comments.

– Daniel