Desktop and Application Streaming

Setting up G Suite SAML 2.0 federation with Amazon AppStream 2.0

If you’re using G Suite, you can set up federation to third-party web apps using the G Suite management console and assign those applications to users in your G-Suite domain. In this post, I walk through the steps involved in setting up SAML 2.0 federation to an Amazon AppStream 2.0 stack using G Suite.

AppStream 2.0 and SAML 2.0

AppStream 2.0 supports identity federation to AppStream 2.0 stacks through Security Assertion Markup Language (SAML) 2.0. You can use an identity provider (IdP) that supports SAML 2.0 to provide an onboarding flow for your AppStream 2.0 users. The list of IdPs includes Active Directory Federation Services (AD FS) in Windows Server, Ping One Federation Server, Okta, and G Suite.

This feature offers your users the convenience of one-click access to their AppStream 2.0 applications using their existing identity credentials. You also have the security benefit of identity authentication by your IdP. You can control which users have access to a particular AppStream 2.0 stack.

Solution overview

This post walks through the following steps:

  1. Create a SAML 2.0 application in the G Suite management console.
  2. Create an AWS SAML IdP in IAM.
  3. Create an IAM federation role.
  4. Create a custom user attribute category in the G Suite admin console.
  5. Add custom SAML attribute mappings.
  6. Populate the values of the custom SAML attributes for a user.
  7. Assign the SAML application to the user.


To complete this tutorial, you need the following:

Step 1: Create a SAML 2.0 application in the G Suite management console

Log in into your G Suite admin console using your admin account and choose Apps, SAML Apps. 

Choose the plus icon (+) to create a new SAML application and choose SETUP MY OWN CUSTOM APP.

Download the IdP metadata and save it locally. You use this file in Step 2 to create the AWS IdP. Choose Next.

Provide a name for your SAML 2.0 application, description, and an optional logo to easily identify the application in the user login portal. After entering the inputs, choose Next. 

Provide the following input for various fields and then choose Next.

  • ACS URL —
  • Entity ID — urn:amazon:webservices.
    This is a parameter used by AWS (the service provider) to uniquely identify the SAML application. Every stack is configured as a SAML application in G Suite. You need to have a unique entity ID value for every AppStream 2.0 SAML application. To do so, just add a numerical counter as a suffix to this value. For example:

    • Stack1 app Entity ID – urn:amazon:webservices
    • Stack2 app Entity ID – urn:amazon:webservices1
    • Stack3 app Entity ID – urn:amazon:webservices2
  • Start URL — Relay state URL of your AppStream 2.0 stack. For more information, see Step 6: Configure the Relay State of Your Federation.
  • Signed Response — Leave it unchecked.
  • Name ID — Basic Information, Primary Email.
  • Name ID Format — Persistent.


Skip the next page, Attribute Mapping, and choose Finish.

Step 2: Create an AWS SAML IdP in IAM

You need an IdP created in IAM. This IdP defines your organization’s IdP-to-AWS trust relationship using the metadata document generated by the IdP software in your organization. For more information and instructions, see Creating and Managing a SAML Identity Provider (AWS Management Console).

For the IdP metadata, use the metadata file downloaded earlier from the G Suite console. After you create the IdP, note the IdP ARN available from the details page. You need it later.

Step 3: Create an IAM federation role

You need an IAM role to provide users with the permissions to access an AppStream 2.0 stack. The permissions defined in this IAM role dictate the stacks to which the federating users have access.

You can choose to provide permissions to all stacks in your AWS account or individually list the stacks that can be accessed by the user assuming this role on federation.  After you create the IAM role, note the role ARN available from the details page. You need it later.

For more information and instructions, see Step 2: Create a SAML 2.0 Federation IAM Role and Step 3: Embed an Inline Policy for the IAM Role.

Step 4: Create a custom user attribute category in the G Suite admin console

Navigate to the users dashboard by choosing Directory, Users.
From the top right corner in the Users dashboard, choose Manage User Attributes, Add Custom Category.

Provide a name for the category and a description, add the SAML attributes as defined below, and then choose Add.

  • Attribute name — FederationRole, Text, Visible to admin, Single Value
  • Attribute name — SessionDuration, Text, Visible to admin, Single Value

Step 5: Add custom SAML attribute mappings

Navigate to the newly created SAML app. Choose Main menu, Apps, SAML Apps and select the newly created application.

Choose Attribute Mapping, Add New Mapping, add three mappings as defined below, and then choose Save.

  • Application attribute —, AWS-SAML-ATTRIBUTES, FederationRole
  • Application attribute —, AWS-SAML-ATTRIBUTES, SessionDuration
  • Application attribute —, Basic Information, Primary Email

Step 6: Populate the values of the custom SAML attributes for a user

Select a user whose custom attribute values have to be updated from the Users dashboard. In the User details page, choose User Information.

Edit the values for SAML-USER-ATTRIBUTES, the custom attribute category, as defined below, and choose Save. 

  • Federation Role — Comma-separated string of the IAM federation role ARN and IdP ARN in the following format: <Role-ARN>,<IDP-ARN>
  • SessionDuration — The maximum duration of the AppStream 2.0 session in seconds. For this post, enter 3600.

Repeat the steps for other users to whom to assign this SAML application. To avoid editing the SAML attribute values manually for every user, follow the steps at the end of this guide to programmatically update the custom user attribute values.

Step 7: Assign the SAML application to the user

Choose the SAML application from the Apps dashboard.
From the details page, you can choose to do one of the following:

  • Turn on the app for every user in your G Suite account.
  • Turn on the app for a selective organization under your G Suite account.

Test the federation by choosing the SAML apps from the Google Apps menu. You may have to choose More to see the SAML app.

Update custom SAML user attribute values programmatically for multiple values

G Suite does not allow you the option to bulk edit users and update their SAML attribute values.  To do that, you have to use the G Suite admin SDK to programmatically update the details of multiple users.

The G Suite Admin SDK offers support for multiple programming languages like Python and Java. In this post, you use Python.

Before using this script, you need to install Python, PIP, and a few Google Python libraries on your machine from which you will be executing this script::

  • For more information about installing Python, see Python For Beginners.
  • For more information about installing PIP, see Installation in the pip 10.0.1 documentation.
  • To install the required Google Python Libraries, after you install PIP, launch a terminal window and run the following command: pip install –upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib

Follow the Google Directory API Python QuickStart to enable the Directory API, configure your OAuth client for Desktop app, and download your credentials.json file. This file will need to saved in the same path as the script, below.

The following Python script extracts all the users in your G Suite domain and updates the FederationRole and SessionDuration values of the custom user category SAML-USER-ATTRIBUTES. You can apply the settings for all users in your G Suite domain or use the search filters of the users.list API to apply the changes to only a selected set of users. For more information, see Users: list in the G Suite Admin SDK documentation.

When you execute the script, a Google form pops up. Sign in using your admin credentials, consent to the script accessing the Directory API, and choose Submit.

from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request

# If modifying these scopes, delete the file token.pickle.
SCOPES = ['']

def get_credentials():
    """Shows basic usage of the Admin SDK Directory API.
    Prints the emails and names of the first 10 users in the domain.
    creds = None
    # The file token.pickle stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)

    return creds

def  update_saml_attributes(service, user):
    custom_schema = {
        "SessionDuration": "3600",
        "FederationRole": "arn:aws:iam::123456789012:role/GoogleSSORole,arn:aws:iam::123456789012:saml-provider/Google-SSO-Provider"
    user.update({'customSchemas' : {'SAML-USER-ATTRIBUTES' : custom_schema}})
    ret = service.users().update(userKey=user['id'], body=user).execute()
    return ret['customSchemas']

def main():

    creds = get_credentials()

    service = build('admin', 'directory_v1', credentials=creds)

    # Call the Admin SDK Directory API
    # print('Getting the first 10 users in the domain')
    # The use of single quotes on the orgPath parameter allows OU paths with spaces
    orgPath = "orgUnitPath='/AppStream Staff'"

    results = service.users().list(customer='my_customer', 
        # comment out maxResults to make changes to more than the first 10 users. This is currently set to limit errors affecting more than 10 users until you've tested the script
    users = results.get('users', [])

    if not users:
        print('No users in the domain.')
        print('Updated users with the following customSchemas')
        for user in users:
            # Uncomment the following line to print users for confirmation/testing
            # print(u'{0} ({1})'.format(user['primaryEmail'], user['name']['fullName']))
            # The following will update the user customSchemas - comment out if you're only testing
            userUpdated = update_saml_attributes(service, user)
            print(u'{0} {1} {2}'.format(user['primaryEmail'], user['id'], userUpdated))

if __name__ == '__main__':


This completes the walkthrough for configuring G Suite SSO for SAML 2.0 federation to AppStream 2.0. For every AppStream 2.0 stack, you have to create a separate SAML application. To learn more, see Single Sign-on Access to AppStream 2.0 Using SAML 2.0

To learn more about AppStream 2.0, see the following:

– Vinothkumar Narasimhan, Sr. Product Manager, Amazon AppStream 2.0