AWS Security ChangesHomeSearch

AWS appstream2: Document OAuth 2.1 auth and header-based session identification for MCP server

Service: appstream2 · 2026-10-11 · Documentation medium

File: appstream2/latest/developerguide/agent-access-mcp-server.md · Type: authz

Summary

Expands the WorkSpaces Applications agent-access MCP server guide: adds OAuth 2.1 authorization via AWS Sign-In (interactive and non-interactive/headless client-credentials flows) as an alternative to SigV4, documents new stack/user-ID headers for non-domain-joined fleets, clarifies SourceIdentity-based user derivation, normalizes header names to lowercase, and adds application/session tool docs including guidance to keep streaming URLs out of the model context.

Security assessment

The change documents authentication/authorization mechanisms (SigV4 vs OAuth 2.1 bearer tokens, IAM policy enforcement, SourceIdentity preservation) and a security best practice to keep streaming URLs out of the model's context. It is security documentation rather than a fix for a specific vulnerability, so security_issue_related is false.

Evidence

As an alternative to signing requests with IAM credentials, the MCP server supports OAuth 2.1 authorization through AWS Sign-In, the same way as the AWS MCP Server. AWS Sign-In acts as the authorization server. It issues short-lived, scoped access tokens.

Diff

diff --git a/appstream2/latest/developerguide/agent-access-mcp-server.md b/appstream2/latest/developerguide/agent-access-mcp-server.md
index 2c38676..3b94713 100644
--- a//appstream2/latest/developerguide/agent-access-mcp-server.md
+++ b//appstream2/latest/developerguide/agent-access-mcp-server.md
@@ -17,3 +17 @@ When you enable agent access on a stack, agents can connect to the managed MCP s
-The MCP server is hosted in the AWS cloud. You don't need to install or maintain any server components. The server uses Streamable HTTP as its transport protocol.
-
-Agent access supports both non-domain-joined and domain-joined fleets. The connection method differs by fleet type. Non-domain-joined fleets authenticate the session with a streaming URL, while domain-joined fleets authenticate through SAML federation. For the path that matches your fleet, see Connecting to the MCP server.
+Agent access supports both non-domain-joined and domain-joined fleets. The connection method differs by fleet type. For non-domain-joined fleets, you can connect in either of two ways. In the first, you provide the stack and user ID as two headers: `x-amzn-agentaccess-workspaces-applications-stack` and `x-amzn-agentaccess-workspaces-applications-user-id`. The MCP server then creates the streaming session for you. In the second, you generate a streaming URL yourself and pass it as a header. For domain-joined fleets, authenticate through SAML federation. For the path that matches your fleet, see Connecting to the MCP server.
@@ -27,0 +26,2 @@ Agents connect to the MCP server at the following endpoint:
+Replace `region` with your Region code. For the supported Regions and their endpoints, see [WorkSpaces Applications MCP endpoints](./allowed-domains.html#allowed-domains-mcp-endpoints).
+
@@ -30 +30,13 @@ The MCP server is hosted in the AWS cloud and uses Streamable HTTP as its transp
-Every request must be SigV4-signed using IAM credentials with the service name `agentaccess-mcp`. The following Python example shows the general connection pattern using `mcp-proxy-for-aws`:
+###### Note
+
+Before an agent can connect, the fleet associated with your stack must be running and have available capacity.
+
+To connect an agent, you make two choices: how the agent authorizes its requests, and how it identifies the streaming session.
+
+### Request authorization
+
+You can authorize requests in one of two ways: SigV4 signing or OAuth 2.1 authorization through AWS Sign-In.
+
+#### SigV4 signing
+
+To use SigV4, sign each request using IAM credentials with the service name `agentaccess-mcp`. The following Python example shows the general connection pattern using `mcp-proxy-for-aws`:
@@ -51 +63 @@ For other languages, write your own SigV4 signing logic for outgoing MCP request
-How you authenticate the streaming session depends on your fleet type:
+#### OAuth 2.1 authorization
@@ -53 +65 @@ How you authenticate the streaming session depends on your fleet type:
-  * **Non-domain-joined fleets** — Pass a streaming URL as a header. See Connecting with non-domain-joined fleets.
+As an alternative to signing requests with IAM credentials, the MCP server supports OAuth 2.1 authorization through AWS Sign-In, the same way as the AWS MCP Server. AWS Sign-In acts as the authorization server. It issues short-lived, scoped access tokens. The MCP server accepts these tokens as bearer tokens. OAuth uses your existing IAM identities, permissions, and organizational controls. When you authorize an agent, it can access the MCP server on your behalf. It does not get extra permissions. AWS still checks every request against your IAM policies.
@@ -55 +67 @@ How you authenticate the streaming session depends on your fleet type:
-  * **Domain-joined fleets** — Pass a signed SAML assertion as metadata. See Connecting with domain-joined fleets.
+OAuth-compatible MCP clients — such as Kiro, Claude Code, Cursor, Codex, and Gemini — can connect directly to the MCP server endpoint without local proxy software. AWS Sign-In supports two authorization models:
@@ -56,0 +69 @@ How you authenticate the streaming session depends on your fleet type:
+  * **Interactive authorization** — For agents that can open a browser. The client registers through dynamic client registration, redirects you to an AWS Sign-In page to authenticate and approve access, and AWS Sign-In then issues and refreshes the access tokens.
@@ -57,0 +71 @@ How you authenticate the streaming session depends on your fleet type:
+  * **Non-interactive authorization** — For agents that already have AWS credentials and run without a browser (sometimes called headless authorization). The agent uses the OAuth client credentials grant to exchange SigV4-signed credentials for a short-lived access token.
@@ -59,0 +74,8 @@ How you authenticate the streaming session depends on your fleet type:
+
+
+OAuth authorization for the MCP server works the same way as it does for the AWS MCP Server, using the MCP server endpoint (`https://agentaccess-mcp.`region`.api.aws/mcp`). For setup, required IAM permissions, and governance and monitoring options, see [OAuth 2.1 authentication for AWS MCP Server](https://docs.aws.amazon.com/agent-toolkit/latest/userguide/oauth-authentication.html) in the _Agent Toolkit for AWS User Guide_ and [Sign-In with OAuth 2.0](https://docs.aws.amazon.com/signin/latest/userguide/oauth-sign-in-overview.html) in the _AWS Sign-In User Guide_.
+
+### Session identification
+
+How you identify the streaming session depends on your fleet type.
+
@@ -64 +86,9 @@ At any given time, only one agent can connect to a unique session. Named users,
-### Connecting with non-domain-joined fleets
+#### Connecting with non-domain-joined fleets
+
+For non-domain-joined fleets, you can connect in either of two ways. Provide the stack and user ID as headers, and the MCP server creates the streaming session for you. This suits MCP clients that you configure statically, because such a client can hold a fixed pair of headers but cannot generate a streaming URL or replace one when it expires. Alternatively, generate a streaming URL yourself and pass it as a header. Use this approach when you need control over session creation, such as setting the validity period.
+
+To connect with the stack and user ID, pass the following headers on every request:
+
+  * `x-amzn-agentaccess-workspaces-applications-stack` — the stack name or ARN.
+
+  * `x-amzn-agentaccess-workspaces-applications-user-id` — the user ID for the session.
@@ -66 +96,23 @@ At any given time, only one agent can connect to a unique session. Named users,
-For non-domain-joined fleets, generate a streaming URL using the `CreateStreamingURL` API and pass it as the `X-Amzn-AgentAccess-Streaming-Session-Url` header on every request. No agent-specific parameters are required. The agent behavior is determined by the stack's agent access configuration.
+
+
+
+###### Note
+
+The `x-amzn-agentaccess-workspaces-applications-user-id` header is optional. If you omit it, the MCP server derives the user identity from the authenticated session. It uses the AWS `SourceIdentity` when one is present, and the caller's IAM principal otherwise. `SourceIdentity` preserves a user's original corporate identity when they assume an IAM role. This holds even when roles are chained through an external identity provider (IdP).
+    
+    
+    from mcp_proxy_for_aws import aws_iam_streamablehttp_client
+    
+    # Connect to the MCP server with the stack and user ID
+    async with aws_iam_streamablehttp_client(
+        endpoint="https://agentaccess-mcp.region.api.aws/mcp",
+        aws_service="agentaccess-mcp",
+        aws_region="region",
+        headers={
+            "x-amzn-agentaccess-workspaces-applications-stack": "stack-name-or-arn",
+            "x-amzn-agentaccess-workspaces-applications-user-id": "user-id",
+        },
+    ) as (read, write, _):
+        ...
+
+To connect with a streaming URL instead, generate one using the `CreateStreamingURL` API and pass it as the `x-amzn-agentaccess-streaming-session-url` header on every request. No agent-specific parameters are required. The agent behavior is determined by the stack's agent access configuration.
@@ -87 +139 @@ For non-domain-joined fleets, generate a streaming URL using the `CreateStreamin
-            "X-Amzn-AgentAccess-Streaming-Session-Url": streaming_url,
+            "x-amzn-agentaccess-streaming-session-url": streaming_url,
@@ -94 +146 @@ For more information about the `CreateStreamingURL` API, see [CreateStreamingURL
-### Connecting with domain-joined fleets
+#### Connecting with domain-joined fleets
@@ -125 +177 @@ For more information about setting up SAML federation with WorkSpaces Applicatio
-You can control how your agent waits for the desktop session to become available by setting the `X-Amzn-AgentAccess-Connect-Mode` header on your MCP requests.
+You can control how your agent waits for the desktop session to become available by setting the `x-amzn-agentaccess-connect-mode` header on your MCP requests.
@@ -129 +181 @@ You can control how your agent waits for the desktop session to become available
-Connection modes apply to both non-domain-joined and domain-joined fleets. Set the `X-Amzn-AgentAccess-Connect-Mode` header alongside whichever authentication mechanism your fleet type uses (the streaming-URL header for non-domain-joined fleets, or the SAML assertion metadata for domain-joined fleets).
+Connection modes apply to both non-domain-joined and domain-joined fleets. Set the `x-amzn-agentaccess-connect-mode` header alongside whichever authentication mechanism your fleet type uses. For non-domain-joined fleets, that is either the stack and user ID headers or a streaming-URL header. For domain-joined fleets, it is the SAML assertion metadata.
@@ -147,2 +199,2 @@ The following example shows how to use POLLING mode:
-        "X-Amzn-AgentAccess-Streaming-Session-Url": streaming_url,  # non-domain-joined fleets
-        "X-Amzn-AgentAccess-Connect-Mode": "POLLING",
+        "x-amzn-agentaccess-streaming-session-url": streaming_url,  # non-domain-joined fleets
+        "x-amzn-agentaccess-connect-mode": "POLLING",
@@ -168 +220 @@ The following example shows how to use POLLING mode:
-You can control whether the streaming session is expired when your agent ends its connection by setting the `X-Amzn-AgentAccess-Expire-Streaming-Session-On-Delete` header on your MCP requests. The following values are available:
+You can control whether the streaming session is expired when your agent ends its connection by setting the `x-amzn-agentaccess-expire-streaming-session-on-delete` header on your MCP requests. The following values are available:
@@ -183 +235 @@ By default, an `mcp-proxy-for-aws` MCP client automatically handles the `DELETE`
-The MCP server provides the following tools for agents to interact with the desktop during a streaming session. All tool names use the `agentaccess___` prefix.
+The MCP server provides the following tools. Agents use them to interact with the desktop during a streaming session. All tool names use the `agentaccess___` prefix.
@@ -288,0 +341,54 @@ Parameters: `include_cursor` (optional — defaults to `false`).
+### Application tools
+
+###### Note
+
+These application tools appear in the agent's tool list only when applications are registered in the fleet image's catalog. If the image has no registered applications, these tools are not available.
+
+`launch_application`
+    
+
+Launch an application from the ones available in the fleet image's catalog.
+
+Parameters: `id` (required) — the application identifier.
+
+The tool's own description lists the identifiers of the available applications. The MCP server populates this description from the fleet image's catalog (for example, `firefox`, `notepad++`, or `eclipse`). Use one of the listed identifiers. An `id` that is not in the catalog returns `isError: true` with `SERVER_ERROR: Invalid input`. IDs are set when the image is built. You cannot work out an ID from the application name.
+
+Launching an application does not replace what is already running. The previously launched application stays open. That is why the app switcher exists.
+
+`toggle_app_switcher`
+    
+
+Open or close the app-switcher overlay.
+
+Parameters: none.
+
+This tool only toggles the overlay. To bring a particular application to the foreground, follow up with a `left_click` on its thumbnail, using coordinates read from a screenshot. No tool reports which application is currently in the foreground, so an agent that needs to know must capture a screenshot and look.
+
+###### Note
+
+The app switcher is available only when the fleet's **Stream view** is set to **Application** , which displays only the windows of applications that users open. It is not available when **Stream view** is set to **Desktop** , because WorkSpaces Applications then provides the standard desktop and taskbar for the operating system.
+
+### Session tools
+
+###### Note
+
+To watch an agent while it works, code the agent to open a streaming URL in a browser. Keep the URL out of the model's context, because it grants session access. You can create the URL in one of two ways:
+
+  * Call the `CreateStreamingURL` API with the `stack`, `fleet`, and `userId` values from `get_session_info`, then open the returned URL in a browser.
+
+  * Read the `streaming_url` value from the `_meta` field of the `get_session_info` response, then open it in a browser.
+
+
+
+
+In both cases, the agent's own code handles the URL, so it never exposes the session credentials to the model.
+
+`get_session_info`
+    
+
+Return information about the current session.
+
+Parameters: none.
+
+Returns the following identifier fields as the tool result: `mcpSessionId`, `stack`, `userId`, `workSpacesSessionId`, and `fleet`.
+