AWS Logo
Menu
Dynamically Securing Network Access in Amazon AppStream 2.0 Using Session Scripts

Dynamically Securing Network Access in Amazon AppStream 2.0 Using Session Scripts

Dynamically modify Windows Defender Firewall rules within AppStream using Session Scripts

Bryan May
Amazon Employee
Published May 19, 2025
Last Modified May 20, 2025

Introduction

Securing Remote Desktop Protocol (RDP) access in non-domain environments presents unique challenges for system administrators. When using Amazon AppStream 2.0, organizations often need to provide users with selective network access to specific resources while maintaining a strict security posture. Configuring network-level controls (Security Groups, NACLs) at the fleet level can possibly cast too wide of a net. This article demonstrates how to implement dynamic, user-specific RDP access controls using AppStream 2.0 session scripts, AWS Systems Manager Parameter Store, and Windows Defender Firewall.

The Challenge

In non-domain environments, traditional Group Policy and Active Directory-based controls aren't available. Organizations need to:
  • Allow access only to specific IP addresses based on user identity
  • Implement security controls that are dynamic per session
  • Maintain security without complex infrastructure

Solution Architecture

The solution combines several AWS services and features:
  1. AppStream 2.0 session scripts for execution with SYSTEM privileges
  2. AWS Systems Manager Parameter Store as a secure key value store
    1. Note: We will be using standard string, but consider SecureString for highly sensitive information or for compliance purposes
  3. Windows Defender Firewall for network access control
  4. AppStream 2.0 fleet IAM roles to securely access AWS resources

User's submit access requests for a bastion host, that is accessible to various servers


Implementation

1. SSM Parameter Store Configuration

While AppStream 2.0 offers a 'Session Context' feature, this data cannot be used directly within Session Scripts. If you only need to pass data as environment variables after the session script executes, consider using Session Context instead of this solution.
In a real-world scenario, SSM Parameters would be created programmatically as part of a larger request pipeline. For this example, we can go ahead and create one manually.
Within AWS SSM Parameter store, create a new key value text pair following this structure:
Value format:
IP.adddr1-IP.addr2-IP.addr3 (hyphen-separated IP addresses)

2. IAM Role Configuration

AppStream fleets can (optionally) be configured to inherit a single IAM role. In our case, session scripts need to be able to retrieve values from SSM Parameter store.
Create a new IAM role with the following IAM Policy attached, and then assign it to your AppStream fleet (fleet must be in the stopped state):
Replace region and account-id
Modify the Trust relationship of the IAM role to allow the appstream service to assume the role:

3. Session Script Implementation

The session script performs these key functions:
  • Identifies the current user from registry
    • In this script, we assume the user-id value passed along the CreateStreamingURL API matches the key value of our SSM Parameter
  • Retrieves allowed IPs from SSM Parameter Store
    • This is seen as a delimited list of IPs. Our script is using the (-) delimiter to parse the list and add it to an array, which will be iterated through to add our firewall rules
  • Configures Windows Firewall rules
    1. In order to restrict outbound network access in Windows Defender Firewall, we must first set the Default Behavior to "Block" instead of "Allow".
    2. Since we only care about blocking RDP access, we will then immediately add additional rules to Allow TCP and UDP traffic on all ports besides 3389.
    3. Only IP addresses contained within our SSM Parameter for the given user will be allowed as valid RDP destination hosts - regardless of what our security groups/NACLs are allowing.
Follow our public documentation for steps detailing how/where to configure the Session script. The contents of the script can be found below.

Testing the Solution

  1. Create an SSM Parameter with a key name of your appstream user, and value of a list of IP addresses
  2. Call the CreateStreamingURL API, and be sure to specify the same user-id value as your SSM Parameter user key. Paste the returned access URL into your browser.
  3. Once connected to the fleet, open notepad or file explorer and navigate to the session script log location: C:\AppStream\SessionScripts\logs\SessionStart
  4. Open the log file ending in -stdout to view the script output. You should see the verbose logging details from the script showing each step of the process
  5. Lastly, open mstsc.exe and attempt to establish an RDP connection to one of the IP addresses you allow-listed, and compare that to an IP address of a host you did not allow-list. (The allow-list should immediately bring up the RDP username and password dialog box).

Security Considerations

  • Principle of Least Privilege
    • Firewall blocks all outbound RDP by default
    • Specific allow rules only for authorized IPs
  • Parameter Security
    • Sensitive SSM parameters should use SecureString type
    • IAM roles limited to specific parameter paths
    • Parameter naming convention enables granular access control
  • Execution Context
    • Script runs with SYSTEM privileges
    • User identification via registry values
    • Firewall rules specific to RDP application
       

Best Practices

  1. Parameter Management
    • Use consistent naming conventions
    • Regular auditing of parameters
    • Clean up unused parameters
  2. Error Handling
    • Validate IP addresses via Regex
    • Maintain default-deny state in case of script errors
  3. Monitoring and Logging
    • Log script execution results
    • Monitor firewall rule changes
    • Use CloudTrail to track access requests to SSM and AppStream

Limitations and Considerations

  • 60-second session script timeout
  • Non-persistent nature of AppStream instances
  • Consider integrating session scripts with storage connector for advanced use cases
  • AWS CLI performance advantages over PowerShell modules

Alternative Approaches

The solution detailed in this article isn't needed for every use case. Before considering this approach, identify whether your network security requirements can be met via any of the below:
  1. Network-level controls (Security Groups, NACLs)
  2. VPN or Direct Connect for network isolation
  3. Third-party remote access solutions

Conclusion

This solution provides secure, manageable RDP access control for AppStream 2.0 environments without requiring Active Directory integration. By leveraging AWS services and Windows features, organizations can implement granular access controls while maintaining security and usability.
 

Any opinions in this post are those of the individual author and may not reflect the opinions of AWS.

Comments