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.

Walkthrough

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 — 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 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, Whole number, 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 — https://aws.amazon.com/SAML/Attributes/Role, AWS-SAML-ATTRIBUTES, FederationRole
  • Application attribute — https://aws.amazon.com/SAML/Attributes/SessionDuration, AWS-SAML-ATTRIBUTES, SessionDuration
  • Application attribute —https://aws.amazon.com/SAML/Attributes/RoleSessionName, 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 httplib2 Python library 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 httplib2, after you install PIP, launch a terminal window and run the following command: pip install httplib2

Follow the Google Directory API Python QuickStart to create a developer project and install the Google client library for Python on your local computer.

From your G Suite admin console menu, choose Security, Settings, API reference, and then select Enable API access. 

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 httplib2
import os

from apiclient import discovery
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage


try:
    import argparse
    flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
    flags = None


SCOPES = 'https://www.googleapis.com/auth/admin.directory.user'

#Full file path of client secret file on your local computer
CLIENT_SECRET_FILE = 'C:/Users/TestUser/Desktop/client_secret.json'
APPLICATION_NAME = 'Directory API Python Quickstart'

# This script will get the API credentials for your account. 
def get_credentials():
    home_dir = os.path.expanduser('~')
    credential_dir = os.path.join(home_dir, '.credentials')
    if not os.path.exists(credential_dir):
        os.makedirs(credential_dir)
    credential_path = os.path.join(credential_dir,'admin-directory_v1-python-quickstart.json')
    store = Storage(credential_path)
    credentials = store.get()
    if not credentials or credentials.invalid:
        flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
        flow.user_agent = APPLICATION_NAME
        if flags:
            credentials = tools.run_flow(flow, store, flags)
        else: # Needed only for compatibility with Python 2.6
            credentials = tools.run(flow, store)
        print('Storing credentials to ' + credential_path)
    
    return credentials

# This function will update the saml user attributes under the custom user category
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'}
    if 'customSchemas' in user.keys():
        # Replace 'SAML-USER-ATTRIBUTES' with the name of your custom user category created in G Suite
        user['customSchemas']['SAML-USER-ATTRIBUTES'] = custom_schema
        ret = service.users().update(userKey=user['id'], body=user).execute()
    else:
        user.update({'customSchemas' : {'SAML-USER-ATTRIBUTES' : custom_schema}})
        ret = service.users().update(userKey=user['id'], body=user).execute()
  
    return ret
        

def main():

    # Get the API credentials
    credentials = get_credentials()
    http = credentials.authorize(httplib2.Http())

    # Build a directory API object
    service = discovery.build('admin', 'directory_v1', http=http)


    # Get the list of users in the G Suite domain. You can choose to filter only to get
    # users in a domain. For more details, refer users.list API reference 
    results = service.users().list(customer='my_customer',orderBy='email', projection="full").execute()
    users = results.get('users');
    
    if not users:
        print('No users in the domain.')
    else:
        # Loop through every user and update the saml values. 
        for user in users:
            user = update_saml_attributes(service, user)
            
 if __name__ == '__main__':
    main()

Conclusion

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