Desktop and Application Streaming

Setting up Google Workspace SAML 2.0 federation with Amazon AppStream 2.0

August 2022: This post has been updated by Dylan Barlett for Google Workspace (formerly G Suite).

If you’re using Google Workspace (formerly G Suite), you can set up federation to third-party web apps using the Google Workspace management console and assign those applications to users in your Google Workspace 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 Google Workspace.

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 Google Workspace.

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 Google Workspace 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 Google Workspace 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.

Walkthrough

To complete this tutorial, you need the following:

  • A Google Workspace subscription with an admin account
  • An AWS account
  • An Amazon AppStream 2.0 stack (see Stream Desktop Applications)

Step 1: Create a SAML 2.0 application in the Google Workspace management console

Log in into your Google Workspace admin console using your admin account and choose Apps, Web and mobile apps. 

Choose Add app, then choose Add custom SAML app.

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 Continue.

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

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

  • ACS URL — https://signin.aws.amazon.com/saml.
  • 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 Google Workspace. 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 Format — PERSISTENT.
  • Name ID — Basic Information > Primary Email.

Service provider details as described above

Skip the next page, Attributes, 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 Google Workspace 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 Google Workspace admin console

Navigate to the users dashboard by choosing Directory, Users.

From the top right corner in the Users dashboard, choose More options, Manage custom attributes. Then choose ADD CUSTOM ATTRIBUTE.

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

SAML User attributes as described above

Step 5: Add custom SAML attribute mappings

Navigate to the newly created SAML app: choose Apps, Web and mobile apps and select the newly created application. Expand the SAML attribute mapping panel and select ADD MAPPING, add three mappings as defined below, and then choose SAVE.

  • SAML-USER-ATTRIBUTES > FederationRole -> https://aws.amazon.com/SAML/Attributes/Role
  • SAML-USER-ATTRIBUTES > SessionDuration -> https://aws.amazon.com/SAML/Attributes/SessionDuration
  • Basic Information > Primary email -> https://aws.amazon.com/SAML/Attributes/RoleSessionName

Google Directory attributes

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 the User information panel.

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 Google Workspace account.
  • Turn on the app for a group or organizational unit under your Google Workspace 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

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

The Google Workspace 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 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 be saved in the same path as the script, below.

The following Python script extracts all the users in your Google Workspace 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 Google Workspace 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 Google Workspace Admin SDK documentation.

When you run 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 = ['https://www.googleapis.com/auth/admin.directory.user']


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:
            creds.refresh(Request())
        else:
            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 org_path parameter allows OU paths with
    # spaces.
    org_path = "orgUnitPath='/AppStream Staff'"

    results = service.users().list(
        customer='my_customer',
        query=org_path,
        # 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.
        maxResults=10,
        orderBy='email'
    ).execute()
    users = results.get('users', [])

    if not users:
        print('No users in the domain.')
    else:
        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.
            user_updated = update_saml_attributes(service, user)
            print(u'{0} {1} {2}'.format(
                user['primaryEmail'],
                user['id'],
                user_updated
            ))


if __name__ == '__main__':
    main()

Conclusion

This completes the walkthrough for configuring Google Workspace 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