Desktop and Application Streaming

Use Session Tags to Simplify AppStream 2.0 Permissions

Customers use Amazon AppStream 2.0 to centrally manage applications and stream them to their end users. Organizations have multiple stacks associated with different fleets to separate workloads based on underlying resources, applications, or different user permissions.

In this blog post I show you how to use session tags in the SAML assertion to be used as a condition in the AWS Identity and Access Management (IAM) policy. This allows a single role and a single policy to control the permissions for all of the AppStream 2.0 stacks.

Time to read 5 minutes
Time to complete 30 minutes
Cost to complete (estimated) $0
Learning level Advanced (300)
Services used Amazon AppStream 2.0, AWS Identity and Access Management (IAM)

Overview of solution

To enable users to sign into AppStream 2.0 by using their existing credentials, and start streaming applications, you can set up identity federation using SAML 2.0. You configure an IAM role and a relay state URL in your SAML 2.0-compliant identity provider (IdP) and enable AWS to permit your federated users access to an AppStream 2.0 stack.

When working with multiple stacks, identity administrators have to make a choice on how to assign the permissions. A role is assigned to the user, usually based on group membership. That role has the permissions to start streaming that stack. If a user is a member of multiple groups, they would get multiple roles and a role selection window would appear as shown in screenshot below. This can cause for a confusing user experience.

The image shows the role selection window prompting the user to select one of two roles.

In this blog, we use session tags in the SAML assertion as conditions in the IAM policy. This allows a single role and a single policy to control the permissions for all of the AppStream 2.0 stacks.

Walkthrough

This walkthrough allows you to configure AD FS to add a principal tag as a SAML attribute to the SAML assertion, based on a user’s group membership.

Prerequisites:

Step 1: Modify the Role

In the AD FS 3.0 and Amazon AppStream 2.0 blog, a role is assigned based on the Active Directory group. Modify the rule to always issue the same role.

  1. Open AD FS console on your AD FS 3.0 server, choose Edit Claim Issuance Policy from the Relying Party Trust for AppStream 2.0.
  2. Choose the Claim Rule for Roles
  3. Update the custom rule to always issue the same role.

=> issue(Type = "https://aws.amazon.com/SAML/Attributes/Role", Value = "arn:aws:iam::<account_id>:saml-provider/<identity_provider>,arn:aws:iam::<account_id>:role/TagBasedAppStreamAccess");

  1. Change <account_id> to your AWS account ID.
  2. Change <identity_provider> to the AWS IdP created for AppStream 2.0.

Step 2: Create new custom rule for Session Tags

Create a new rule that adds the session tags to the SAML assertion based on the users group membership. Note that this method supports up to 50 tags. This custom rule takes all of the groups that are prefixed with ‘AWS-AccountID’ and removes the ‘AWS-AccountID’ leaving it with only the group name. The group name is added as the session tag.

  1. In the Claim Issuance Policy choose Add Rule…
    • Claim rule template: Send Claims Using a Custom Rule
    • Claim rule name: Session Tags
    • Custom rule:

c:[Type == "http://temp/variable", Value =~ "(?i)^AWS-"]
=> issue(Type = RegExReplace(c.Value, "AWS-<account_id>-", "https://aws.amazon.com/SAML/Attributes/PrincipalTag:"), Value = "true");

  1. Change <account_id> to your AWS account ID.

Step 3: Create an IAM Policy

In IAM, create a policy for the AppStream 2.0 role. This policy will use conditions to provide access to AppStream 2.0 based on the SAML attributes populated by the Active Directory groups.

  1. In the IAM Console, choose Policies
  2. Choose Create policy
  3. Choose the JSON tab and enter the following:
    1. {
          "Version": "2012-10-17",
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": "appstream:Stream",
                  "Resource": "arn:aws:appstream:<region_code>:<account_id>:stack/<stack_name_1>",
                  "Condition": {
                      "StringEquals": {
                          "appstream:userId": "${saml:sub}",
                          "aws:PrincipalTag/<AD_group_1>": "true"
                      }
                  }
              },
              {
                  "Effect": "Allow",
                  "Action": "appstream:Stream",
                  "Resource": "arn:aws:appstream:<region_code>:<account_id>:stack/<stack_name_2>",
                  "Condition": {
                      "StringEquals": {
                          "appstream:userId": "${saml:sub}",
                          "aws:PrincipalTag/<AD_group_2>": "true"
                      }
                  }
              }
          ]
      }
      
  4. Change <region_code> to the AWS Region AppStream 2.0 is deployed.
  5. Change <account_id> to your AWS Account ID.
  6. Change <stack_name_1> and <stack_name_2> to the name of the AppStream 2.0 stacks associated to the <AD_group_1> and <AD_group_2>
    1. For example, if you have a stack called Desktop-Stack, and an Active Directory group called AWS-012345678910-DesktopStack, enter:
      1. <stack_name_1> as Desktop-Stack
      2. <AD_group_1> as DesktopStack
    2. Choose Next: Tags, these are optional
    3. Choose Next: Review
    4. Enter a policy name and choose Create Policy

Step 4: Create an IAM role

In IAM, create a role for your AppStream 2.0 users to assume. All AppStream 2.0 users will assume this role to simplify permissions.

  1. In the IAM Console, choose Roles
  2. Choose Create Role
  3. For Select type of trusted entity, choose SAML 2.0 federation
  4. For Choose a SAML 2.0 provider:
    1. SAML provider: select the provider specified in the AD FS configuration
    2. Do not select Allow programmatic access only or Allow programmatic and AWS Management Console Access
    3. Attribute: SAML:aud
    4. Value: https://signin.aws.amazon.com/saml
  5. Attach permission polices: select the policy you created in Step 3.
  6. Choose Next: Tags, these are optional
  7. Choose Next: Review
  8. For Role name, enter the role name specified in Step 1. For this blog, we are using TagBasedAppStreamAccess
  9. Choose Create role
  10. Select the role you created and select Trust relationships. Choose Edit trust Relationship.
  11. Update Action to include sts:TagSession.
    1. {
        "Version": "2012-10-17",
        "Statement": [
          {
            "Effect": "Allow",
            "Principal": {
              "Federated": "arn:aws:iam::<account_id>:saml-provider/<saml_provider>"
            },
            "Action": [
              "sts:AssumeRoleWithSAML",
              "sts:TagSession"
            ],
            "Condition": {
              "StringEquals": {
                "SAML:aud": "https://signin.aws.amazon.com/saml"
              }
            }
          }
        ]
      }

Step 5: Test

Now that we have created a role and a policy for AppStream 2.0, we can test. You can use the Excel spreadsheet or another third-party tool to generate the RelayState URL.

Add a test user to the groups that correspond to the AppStream 2.0 stacks they should access. A user should be able to access the AppStream 2.0 Application Catalog without a role selection window. Trying accessing multiple stacks and verify that the user is able to access.

Next, remove the user from one of the groups and try to access the stacks again. The user will be able to access the stacks that correspond to the Active Directory groups in the IAM policy, but will get an error if they do not have permission.

You can verify the SAML assertion and the SAML attributes using a SAML decoder, or a browser extension.

In my example I have two Active Directory groups, AWS-012345678910-DesktopStack and AWS-012345678910-CADStack. In the assertion, you can see the two attributes that are added.

<Attribute Name="https://aws.amazon.com/SAML/Attributes/PrincipalTag:CADStack">
 <AttributeValue>true</AttributeValue> 
</Attribute> 
<Attribute Name="https://aws.amazon.com/SAML/Attributes/PrincipalTag:DesktopStack">
 <AttributeValue>true</AttributeValue> 
</Attribute>

Conclusion

You can use session tags to simplify permissions for multiple AppStream 2.0 stacks and prevent the role selection window from showing to end users. This allows administrators to link users to a specially crafted AD FS Relay State URL and prevent any issues with selecting the wrong role.

Session tags allow administrators to have a single role and single policy for all AppStream 2.0 users, while maintaining the principle of least privilege.