

# Features
<a name="browser-features"></a>

Amazon Bedrock AgentCore Browser provides advanced features including CAPTCHA reduction, browser extensions, session profiles, proxy configuration, and OS-level interaction.

**Topics**
+ [Reducing CAPTCHAs with Web Bot Auth](browser-web-bot-auth.md)
+ [Using browser extensions](browser-extensions.md)
+ [Using browser profiles](browser-profiles.md)
+ [Using browser proxies](browser-proxies.md)
+ [Using browser enterprise policies](browser-enterprise-policies.md)
+ [Configure Root Certificate Authority for Amazon Bedrock AgentCore Browser](browser-root-ca-certificates.md)
+ [Browser OS action](browser-invoke.md)

# Reducing CAPTCHAs with Web Bot Auth
<a name="browser-web-bot-auth"></a>

**Note**  
Amazon Bedrock AgentCore Browser Web Bot Auth (Preview) is based on the draft IETF Web Bot Auth protocol, which is subject to change as the specification evolves toward finalization.

\$1 **Current Implementation:** 

\$1 \$1 Implementation details, API parameters, and signing mechanisms may change as we align with the finalized protocol specification \$1 WAF provider support and policies vary. Not all websites will recognize or allow signed agent traffic \$1 Domain owners retain full control over their bot policies and may block, monitor, or rate-limit agent traffic regardless of cryptographic signatures

\$1 For the latest protocol specification, see the [IETF draft](https://datatracker.ietf.org/doc/html/draft-meunier-web-bot-auth-architecture).

Amazon Bedrock AgentCore Browser reduces CAPTCHA challenges through Web Bot Auth, a draft IETF protocol that cryptographically identifies AI agents to websites and bot control vendors.

## Overview
<a name="browser-web-bot-auth-overview"></a>

AI agents frequently encounter anti-bot mechanisms when browsing websites, including CAPTCHA challenges, rate limiting, and request blocking. These security measures are designed to prevent malicious automated traffic but often block legitimate AI agents as well.

Websites implement these defenses because they cannot reliably distinguish between legitimate agents and malicious bots. Traditional identification methods like IP addresses or User-Agent strings can be easily spoofed and do not provide verifiable identity.

Web Bot Auth addresses this challenge by implementing the [IETF HTTP Message Signatures for automated traffic Architecture](https://datatracker.ietf.org/doc/html/draft-meunier-web-bot-auth-architecture) draft protocol. This protocol enables AI agents to cryptographically sign their HTTP requests, providing websites with verifiable proof of the agent’s identity.

When Web Bot Auth is enabled, Amazon Bedrock AgentCore Browser automatically signs each HTTP request with a private key and includes verification headers. Bot control vendors (such as Cloudflare, Akamai Technologies, and HUMAN Security) can verify these signatures against public key directories and apply appropriate policies configured by website owners.

This approach provides a standardized method for legitimate automation to identify itself while preserving website owners' control over access policies.

## How it works
<a name="browser-web-bot-auth-how-it-works"></a>

Web Bot Auth uses the IETF HTTP Message Signatures standard to cryptographically sign HTTP requests:

1.  **Agent Registration** : Amazon Bedrock AgentCore registers with bot control vendors (Cloudflare, reCAPTCHA, etc.) and provides public keys for verification

1.  **Request Signing** : When enabled, the Browser Tool automatically signs each HTTP request using a private key

1.  **Signature Headers** : Three headers are added to each request:
   +  `Signature` : The cryptographic signature
   +  `Signature-Agent` : Points to the public key directory for verification
   +  `Signature-Input` : Specifies which components were signed

1.  **Verification** : The website’s bot control system fetches the public key and verifies the signature to confirm the request comes from Amazon Bedrock AgentCore

1.  **Policy Application** : Based on the verified identity, the website can apply appropriate policies. Domain owners can configure their bot control systems to:
   +  **Block all traffic** : Reject all automated requests regardless of authentication
   +  **Allow only signed bots** : Accept requests only from verified agents with valid Web Bot Auth signatures
   +  **Allow signed bots from specific directories** : Permit authenticated agents to access only certain paths or resources on the website

## Enabling Web Bot Auth
<a name="browser-web-bot-auth-enable"></a>

To enable Web Bot Auth, you need to configure it when creating a Browser Tool:

**Example**  

1. To create a Browser Tool with Web Bot Auth enabled using the AWS CLI:

   ```
   aws bedrock-agentcore-control create-browser \
     --region <Region> \
     --name "my-browser-with-auth" \
     --description "Browser with Web Bot Auth enabled" \
     --network-configuration '{"networkMode": "PUBLIC"}' \
     --execution-role-arn "arn:aws:iam::<account-id>:role/<execution-role>" \
     --browser-signing '{"enabled": true}'
   ```

1. To create a Browser Tool with Web Bot Auth enabled using Boto3:

   ```
   import boto3
   
   client = boto3.client('bedrock-agentcore-control', region_name='us-west-2')
   
   response = client.create_browser(
       name='my-browser-with-auth',
       description='Browser with Web Bot Auth enabled',
       networkConfiguration={
           'networkMode': 'PUBLIC'
       },
       executionRoleArn='arn:aws:iam::<account-id>:role/<execution-role>',
       browserSigning={
           'enabled': True
       }
   )
   ```

1. ====== To enable Web Bot Auth in the console

1. Open the AgentCore console at [https://console.aws.amazon.com/bedrock-agentcore/home\$1](https://console.aws.amazon.com/bedrock-agentcore/home#).

1. In the navigation pane, choose **Built-in tools**.

1. Choose **Create browser tool**.

1. Provide a unique **Tool name** and optional **Description**.

1. Under **Network settings** , choose **Public network**.

1. In the **Web Bot Auth configuration** section, select the **Use Web Bot Auth** check box.

1. Under **Permissions** , specify an IAM execution role that defines what AWS resources the Browser Tool can access.

1. Configure other browser settings as needed and choose **Create**.

**Important**  
Web Bot Auth requires an execution role with a trust policy, but does not require any managed or inline policies. The feature is disabled by default and must be explicitly enabled during browser creation. You should add the following trust policy to the execution role: [source,json,subs="verbatim,attributes"] ---- \$1 "Version":"2012-10-17", "Statement": [\$1 "Sid": "BedrockAgentCoreBuiltInTools", "Effect": "Allow", "Principal": \$1 "Service": "bedrock-agentcore.amazonaws.com" \$1, "Action": "sts:AssumeRole", "Condition": \$1 "StringEquals": \$1 "aws:SourceAccount": "111122223333" \$1, "ArnLike": \$1 "aws:SourceArn": "arn:aws:bedrock-agentcore:us-east-1:111122223333:\$1" \$1 \$1 \$1] \$1 ----

## Supported Bot Control Vendors
<a name="browser-web-bot-auth-supported-vendors"></a>

Amazon Bedrock AgentCore currently supports Web Bot Auth with the following bot control vendors:
+  **Cloudflare** 
+  **HUMAN Security** 
+  **Akamai Technologies** 
+  **DataDome** 

Additional bot control vendors will be supported as partnerships are established. The authentication works transparently - once enabled, your agents can browse websites protected by these services with reduced friction.

## Considerations
<a name="browser-web-bot-auth-considerations"></a>
+  **Transparent Operation** : Web Bot Auth works automatically once enabled. No additional code changes are required in your agent applications.
+  **Performance Impact** : Signing requests adds minimal latency to HTTP requests.
+  **Vendor Coverage** : The feature only works with websites that use supported bot control vendors. Websites using other anti-bot solutions may still present challenges.
+  **Policy Dependent** : Even with authentication, website owners control their bot policies. Some sites may still restrict or monitor agent traffic based on their specific requirements.

# Using browser extensions
<a name="browser-extensions"></a>

Browser Extensions allow you to install custom extensions into browser sessions at session creation time. This enables you to customize browser behavior with your own extensions for automation tasks, web scraping, testing, and more.

## Overview
<a name="browser-extensions-overview"></a>

Browser Extensions in Amazon Bedrock AgentCore work as follows:

1. You provide a list of browser extension ZIP files stored in your own Amazon S3 buckets

1. The service validates that you have access to these Amazon S3 objects using your credentials

1. During browser session startup, extensions are downloaded from your Amazon S3 bucket and installed to the browser session

## Prerequisites
<a name="browser-extensions-prerequisites"></a>

Before using browser extensions, ensure you have:
+ Completed the general Browser [Prerequisites](browser-quickstart.md#browser-prerequisites) 
+ An Amazon Amazon S3 bucket to store your extension ZIP files
+ IAM permissions to access the Amazon S3 bucket containing your extensions. Add the following permissions to your IAM policy:

  ```
  {
  "Version": "2012-10-17",		 	 	 
      "Statement": [
          {
              "Sid": "ExtensionS3Access",
              "Effect": "Allow",
              "Action": [
                  "s3:GetObject",
                  "s3:GetObjectVersion"
              ],
              "Resource": [
                  "arn:aws:s3:::<S3Bucket>/<path_to_extensions>/*"
              ]
          }
      ]
  }
  ```
**Note**  
The Amazon S3 bucket must be in the same AWS account as the browser session. Extensions have a 10 MB file size limit and a maximum of 10 extensions per session.

## Preparing Extension Files
<a name="browser-extensions-preparing"></a>

To prepare an extension for use with Browser Tool:

1.  **Create a Chrome Extension** 

   Your extension should follow the standard Chromium extension format and adhere to [Chromium extension guidelines](https://www.chromium.org/developers/design-documents/extensions/) . Each extension must include a valid `manifest.json` file.

1.  **Create a ZIP File** 

   Zip the extension directory contents (not the parent folder):

   ```
   cd my-extension
   zip -r ../my-extension.zip.
   ```

1.  **Upload to S3** 

   Upload the ZIP file to your Amazon S3 bucket:

   ```
   aws s3 cp my-extension.zip s3://my-extensions-bucket/extensions/my-extension.zip
   ```

## Creating a browser session with extensions
<a name="browser-extensions-create-session"></a>

You can create a browser session with extensions using the AWS CLI, SDK, or API.

**Example**  

1. To start a browser session with extensions using the AWS CLI:

   ```
   aws bedrock-agentcore start-browser-session \
     --region <Region> \
     --browser-identifier "aws.browser.v1" \
     --name "my-session-with-extensions" \
     --session-timeout-seconds 1800 \
     --extensions '[
       {
         "location": {
           "s3": {
             "bucket": "my-extensions-bucket",
             "prefix": "extensions/my-extension.zip"
           }
         }
       }
     ]'
   ```

1. To start a browser session with extensions using the AWS SDK for Python (Boto3):

   ```
   import boto3
   
   region = "us-west-2"
   client = boto3.client('bedrock-agentcore', region_name=region)
   
   response = client.start_browser_session(
       browserIdentifier="aws.browser.v1",
       name="my-session-with-extensions",
       sessionTimeoutSeconds=1800,
       viewPort={
           'height': 1080,
           'width': 1920
       },
       extensions=[
           {
               "location": {
                   "s3": {
                       "bucket": "my-extensions-bucket",
                       "prefix": "extensions/my-extension.zip"
                   }
               }
           },
           {
               "location": {
                   "s3": {
                       "bucket": "my-extensions-bucket",
                       "prefix": "extensions/another-extension.zip",
                       "versionId": "abc123"  # Optional - for versioned S3 buckets
                   }
               }
           }
       ]
   )
   
   print(f"Session ID: {response['sessionId']}")
   print(f"Status: {response['status']}")
   print(f"Automation Stream: {response['streams']['automationStream']['streamEndpoint']}")
   ```

1. To start a browser session with extensions using the API:

   ```
   # Using awscurl
   awscurl -X PUT \
     "https://bedrock-agentcore.<Region>.amazonaws.com/browsers/aws.browser.v1/sessions/start" \
     -H "Content-Type: application/json" \
     -H "Accept: application/json" \
     --service bedrock-agentcore \
     --region <Region> \
     -d '{
       "name": "my-session-with-extensions",
       "sessionTimeoutSeconds": 1800,
       "viewPort": {
         "height": 1080,
         "width": 1920
       },
       "extensions": [
         {
           "location": {
             "s3": {
               "bucket": "my-extensions-bucket",
               "prefix": "extensions/my-extension.zip"
             }
           }
         },
         {
           "location": {
             "s3": {
               "bucket": "my-extensions-bucket",
               "prefix": "extensions/another-extension.zip"
             }
           }
         }
       ]
     }'
   ```

# Using browser profiles
<a name="browser-profiles"></a>

Browser profiles enable you to persist and reuse browser profile data across multiple browser sessions. A browser profile stores session information including cookies and local storage.

For example, you can authenticate to a website once in a browser session and save the profile data to browser profile resource. When you start a new browser session with that saved profile, your authentication state is preserved, and you remain logged in. This enables agents to perform tasks on authenticated websites without requiring manual intervention.

## Overview
<a name="browser-profiles-overview"></a>

Browser profiles in Amazon Bedrock AgentCore work as follows:

1. Create a browser profile resource that will be reuse across browser sessions

1. Start a browser session and perform actions (such as login a website or put item in shopping cart) that populate cookies and localstorage

1. Save the profile data from current browser session to the browser profile resource

1. Start new browser sessions using the saved profile to restore the previous state

## Prerequisites
<a name="browser-profiles-prerequisites"></a>

Before using browser profiles, ensure you have:
+ Completed the general Browser [Prerequisites](browser-quickstart.md#browser-prerequisites) 
+ IAM permissions to manage profile resources. Add the following permissions to your IAM policy:

  ```
  {
  "Version": "2012-10-17",		 	 	 
      "Statement": [
          {
              "Sid": "BedrockAgentCoreBrowserProfileManagementAccess",
              "Effect": "Allow",
              "Action": [
                  "bedrock-agentcore:CreateBrowserProfile",
                  "bedrock-agentcore:ListBrowserProfiles",
                  "bedrock-agentcore:GetBrowserProfile",
                  "bedrock-agentcore:DeleteBrowserProfile"
              ],
              "Resource": "arn:aws:bedrock-agentcore:<Region>:<account_id>:browser-profile/*"
          }
      ]
  }
  ```
+ IAM permissions to save and load profiles. Add the following permissions to your IAM policy:

  ```
  {
  "Version": "2012-10-17",		 	 	 
      "Statement": [
          {
              "Sid": "BedrockAgentCoreBrowserProfileUsageAccess",
              "Effect": "Allow",
              "Action": [
                  "bedrock-agentcore:StartBrowserSession",
                  "bedrock-agentcore:SaveBrowserSessionProfile"
              ],
              "Resource": [
                  "arn:aws:bedrock-agentcore:<Region>:<account_id>:browser-profile/*",
                  "arn:aws:bedrock-agentcore:<Region>:<account_id>:browser-custom/*",
                  "arn:aws:bedrock-agentcore:<Region>:<account_id>:browser/*"
              ]
          }
      ]
  }
  ```

## Getting started with browser profiles
<a name="browser-profiles-getting-started"></a>

This section walks you through creating a browser profile, saving session data to it, and reusing the profile in subsequent sessions.

### Step 1: Create a browser profile
<a name="browser-profiles-step1"></a>

Create a browser profile resource to store session data.

**Example**  

1. To create a browser profile using the AWS CLI:

   ```
   aws bedrock-agentcore-control create-browser-profile \
     --region <Region> \
     --name "profile_demo" \
     --description "example profile"
   ```

1. To create a browser profile using the AWS SDK for Python (Boto3):

   ```
   import boto3
   
   region = "us-west-2"
   client = boto3.client('bedrock-agentcore-control', region_name=region)
   
   response = client.create_browser_profile(
       name="profile_demo",
       description="example profile"
   )
   
   profile_id = response['profileId']
   print(f"Created profile: {profile_id}")
   ```

1. To create a browser profile using the API:

   ```
   awscurl -X PUT \
     "https://bedrock-agentcore-control.<Region>.amazonaws.com/browser-profiles" \
     -H "Content-Type: application/json" \
     --service bedrock-agentcore-control \
     --region <Region> \
     -d '{
       "name": "profile_demo",
       "description": "example profile",
       "clientToken": "FC21DD1F-FA7B-40EC-8D3A-12E029A1BFF3"
     }'
   ```

### Step 2: Start a browser session and perform actions
<a name="browser-profiles-step2"></a>

Start a browser session and perform actions such as login a website. The session state, including cookies and local storage, will be captured.

**Example**  

1. To start a browser session using the AWS CLI:

   ```
   aws bedrock-agentcore start-browser-session \
     --region <Region> \
     --browser-identifier "aws.browser.v1" \
     --name "my-session" \
     --session-timeout-seconds 3600
   ```

   Use the returned session ID to interact with the browser and perform your desired actions (for example, login into a website).

1. To start a browser session using Boto3:

   ```
   import boto3
   
   region = "us-west-2"
   client = boto3.client('bedrock-agentcore', region_name=region)
   
   response = client.start_browser_session(
       browserIdentifier="aws.browser.v1",
       name="my-session",
       sessionTimeoutSeconds=3600
   )
   
   session_id = response['sessionId']
   print(f"Session ID: {session_id}")
   
   # Use the session to perform actions (e.g., login to a website)
   # ... your browser automation code here ...
   ```

1. To start a browser session using the API:

   ```
   awscurl -X PUT \
     "https://bedrock-agentcore.<Region>.amazonaws.com/browsers/aws.browser.v1/sessions/start" \
     -H "Content-Type: application/json" \
     -H "Accept: application/json" \
     --service bedrock-agentcore \
     --region <Region> \
     -d '{
       "name": "my-session",
       "sessionTimeoutSeconds": 3600
     }'
   ```

### Step 3: Save the session to a profile
<a name="browser-profiles-step3"></a>

After performing actions in the browser session, save the current state to your browser profile. This captures cookies, local storage, and other session data.

**Example**  

1. To save a browser session to a profile using the AWS CLI:

   ```
   aws bedrock-agentcore save-browser-session-profile \
     --region <Region> \
     --profile-identifier "<ProfileId>" \
     --browser-identifier "aws.browser.v1" \
     --session-id "<SessionId>"
   ```

1. To save a browser session to a profile using Boto3:

   ```
   import boto3
   
   region = "us-west-2"
   client = boto3.client('bedrock-agentcore', region_name=region)
   
   response = client.save_browser_session_profile(
       profileIdentifier=profile_id,  # From Step 1
       browserIdentifier="aws.browser.v1",
       sessionId=session_id  # From Step 2
   )
   
   print(f"Profile saved successfully")
   ```

1. To save a browser session to a profile using the API:

   ```
   awscurl -X PUT \
     "https://bedrock-agentcore.<Region>.amazonaws.com/browser-profiles/<ProfileId>/save" \
     -H "Content-Type: application/json" \
     -H "Accept: application/json" \
     --service bedrock-agentcore \
     --region <Region> \
     -d '{
       "browserIdentifier": "aws.browser.v1",
       "sessionId": "<SessionId>",
       "clientToken": "52866F95-4468-4B6C-920C-09A00D36F04E"
     }'
   ```

### Step 4: Start a new session with the profile
<a name="browser-profiles-step4"></a>

Start a new browser session using the saved profile. The session will be initialized with the saved state, including authentication cookies and local storage.

**Example**  

1. To start a browser session with a profile using the AWS CLI:

   ```
   aws bedrock-agentcore start-browser-session \
     --region <Region> \
     --browser-identifier "aws.browser.v1" \
     --name "session-with-profile" \
     --session-timeout-seconds 3600 \
     --profile-configuration '{
       "profileIdentifier":"<ProfileId>"
     }'
   ```

1. To start a browser session with a profile using Boto3:

   ```
   import boto3
   
   region = "us-west-2"
   client = boto3.client('bedrock-agentcore', region_name=region)
   
   response = client.start_browser_session(
       browserIdentifier="aws.browser.v1",
       name="session-with-profile",
       sessionTimeoutSeconds=3600,
       profileConfiguration={
           "profileIdentifier": profile_id  # From Step 1
       }
   )
   
   new_session_id = response['sessionId']
   print(f"New session started with profile: {new_session_id}")
   print("Session is now authenticated with saved cookies and state")
   ```

1. To start a browser session with a profile using the API:

   ```
   awscurl -X PUT \
     "https://bedrock-agentcore.<Region>.amazonaws.com/browsers/aws.browser.v1/sessions/start" \
     -H "Content-Type: application/json" \
     -H "Accept: application/json" \
     --service bedrock-agentcore \
     --region <Region> \
     -d '{
       "name": "session-with-profile",
       "sessionTimeoutSeconds": 3600,
       "profileConfiguration": {
         "profileIdentifier": "<ProfileId>"
       },
       "clientToken": "8FAAFF7F-7803-4C40-A7BD-139C6D008646"
     }'
   ```

## Browser profile operations
<a name="browser-profiles-operations"></a>

This section describes additional operations for managing browser profiles.

### Listing browser profiles
<a name="browser-profiles-list"></a>

You can list all browser profiles in your account.

**Example**  

1. To list browser profiles using the AWS CLI:

   ```
   aws bedrock-agentcore-control list-browser-profiles \
     --region <Region>
   ```

1. To list browser profiles using Boto3:

   ```
   import boto3
   
   region = "us-west-2"
   client = boto3.client('bedrock-agentcore-control', region_name=region)
   
   response = client.list_browser_profiles()
   
   for profile in response.get('items', []):
       print(f"Profile ID: {profile['profileId']}")
       print(f"Name: {profile['name']}")
       print(f"Status: {profile['status']}")
       print("---")
   ```

1. To list browser profiles using the API:

   ```
   awscurl -X POST \
     "https://bedrock-agentcore-control.<Region>.amazonaws.com/browser-profiles/list" \
     -H "Content-Type: application/json" \
     --service bedrock-agentcore-control \
     --region <Region>
   ```

### Getting browser profile details
<a name="browser-profiles-get"></a>

You can retrieve details about a specific browser profile.

**Example**  

1. To get browser profile details using the AWS CLI:

   ```
   aws bedrock-agentcore-control get-browser-profile \
     --region <Region> \
     --profile-id "<ProfileId>"
   ```

1. To get browser profile details using Boto3:

   ```
   import boto3
   
   region = "us-west-2"
   client = boto3.client('bedrock-agentcore-control', region_name=region)
   
   response = client.get_browser_profile(
       profileId=profile_id
   )
   
   print(f"Profile ID: {response['profileId']}")
   print(f"Name: {response['name']}")
   print(f"Description: {response.get('description', 'N/A')}")
   print(f"Status: {response['status']}")
   print(f"Created: {response['createdAt']}")
   ```

1. To get browser profile details using the API:

   ```
   awscurl -X GET \
     "https://bedrock-agentcore-control.<Region>.amazonaws.com/browser-profiles/<ProfileId>" \
     -H "Content-Type: application/json" \
     --service bedrock-agentcore-control \
     --region <Region>
   ```

### Deleting a browser profile
<a name="browser-profiles-delete"></a>

When you no longer need a browser profile, you can delete it to free up resources.

**Example**  

1. To delete a browser profile using the AWS CLI:

   ```
   aws bedrock-agentcore-control delete-browser-profile \
     --region <Region> \
     --profile-id "<ProfileId>"
   ```

1. To delete a browser profile using Boto3:

   ```
   import boto3
   
   region = "us-west-2"
   client = boto3.client('bedrock-agentcore-control', region_name=region)
   
   response = client.delete_browser_profile(
       profileId=profile_id
   )
   
   print(f"Profile deleted successfully")
   ```

1. To delete a browser profile using the API:

   ```
   awscurl -X DELETE \
     "https://bedrock-agentcore-control.<Region>.amazonaws.com/browser-profiles/<ProfileId>" \
     -H "Content-Type: application/json" \
     --service bedrock-agentcore-control \
     --region <Region>
   ```

## Use cases
<a name="browser-profiles-use-cases"></a>

Browser profiles are useful for:
+  **Persistent authentication** : Maintain login sessions across multiple browser invocations without re-authenticating each time
+  **Multi-step workflows** : Execute complex workflows that span multiple sessions while preserving state and context (in cookies or localstorage)
+  **Automated tasks** : Enable AI agents to perform tasks on authenticated websites without manual intervention

## Considerations
<a name="browser-profiles-considerations"></a>
+  **Profile Persistence** : Profile data is saved when you explicitly call the save operation. Ensure you save the profile before terminating the session to preserve the state.
+  **Session Isolation** : Each browser session using a profile operates independently. Changes made in one session are not visible in other concurrent sessions.
+  **Profile Loading** : Saved profile changes only apply to new sessions. Active sessions continue using the profile state from when they were started and will not reflect updates made to the profile after session starts.
+  **Security** : Browser profiles may contain sensitive data such as authentication cookies. Ensure proper IAM policies are in place to restrict access to profile resources.
+  **Profile Updates** : When you save a session to a profile, it overwrites the previous profile data. Consider your workflow carefully to avoid losing important state information.
+  **Cookie Expiration** : Cookies have their own expiration times set by websites. Browser profiles preserve cookies, but expired cookies are automatically removed by the browser according to their expiration dates.

# Using browser proxies
<a name="browser-proxies"></a>

Amazon Bedrock AgentCore Browser supports routing browser traffic through your own external proxy servers. This enables organizations to:
+  **Achieve IP stability** by routing traffic through proxies with known egress IPs, eliminating re-authentication cycles caused by rotating AWS IP addresses
+  **Support IP allowlisting** by providing stable, controllable egress addresses for services that require IP-based access controls
+  **Integrate with corporate infrastructure** by routing through your existing proxy servers for access to internal webpages and resources

## Overview
<a name="browser-proxies-overview"></a>

When you create a browser session with proxy configuration, AgentCore Browser configures the browser to route HTTP and HTTPS traffic through your specified proxy servers.

![\[Browser proxies request flow showing traffic routing from the browser session through a customer-managed proxy server to destination websites.\]](http://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/images/browser-proxies-flow.png)


Request flow:

1. You call `StartBrowserSession` with a `proxyConfiguration` specifying your proxy server.

1. If using authentication, AgentCore retrieves proxy credentials from AWS Secrets Manager.

1. The browser session starts with your proxy configuration applied.

1. Browser traffic routes through your proxy server based on your domain routing rules.

1. Your proxy server forwards requests to destination websites.

The proxy server is infrastructure you own and manage. AgentCore Browser connects to it as a client.

Proxy configuration applies the Chromium `--proxy-server` flag to the browser instance at startup, directing traffic through the specified proxy at the browser level. For scenarios that require network-layer enforcement—for example, when browser-level settings could be modified during runtime—deploy browser sessions within your own VPC. See [Configure Amazon Bedrock AgentCore Runtime and tools for VPC](agentcore-vpc.md).

## Prerequisites
<a name="browser-proxies-prerequisites"></a>

Before configuring browser proxies, ensure you have:
+  **General browser prerequisites** – Complete the standard browser tool setup. See [Get started with AgentCore Browser](browser-quickstart.md).
+  **Proxy server** – An HTTP/HTTPS proxy server that is accessible from the public internet (or reachable within your VPC if using VPC configuration) and supports the HTTP CONNECT method for HTTPS traffic tunneling.
+  ** AWS Secrets Manager secret** (if using authentication) – A secret containing proxy credentials in JSON format with `username` and `password` keys.
+  **IAM permissions** (if using authentication) – The IAM identity calling `StartBrowserSession` must have `secretsmanager:GetSecretValue` permission for the credential secret.

## Getting started
<a name="browser-proxies-getting-started"></a>

This section shows the simplest configuration to route browser traffic through a proxy.

### Step 1: Create a credentials secret (if using authentication)
<a name="browser-proxies-step1"></a>

If your proxy requires authentication, create a secret in AWS Secrets Manager:

```
aws secretsmanager create-secret \
  --name "my-proxy-credentials" \
  --secret-string '{"username":"<your-username>","password":"<your-password>"}'
```

Credential format requirements:


| Field | Allowed characters | 
| --- | --- | 
|   `username`   |  Alphanumeric plus `@ . _ + = -`   | 
|   `password`   |  Alphanumeric plus @ . \$1 \$1 = - \$1 \$1 \$1 % \$1  | 

Characters not allowed: colon ( `:` ), newlines, spaces, quotes.

### Step 2: Add IAM permissions
<a name="browser-proxies-step2"></a>

Add this policy to the IAM identity that will create browser sessions:

```
{
"Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "secretsmanager:GetSecretValue",
            "Resource": "arn:aws:secretsmanager:AWS Region:AWS account:secret:secret-name*"
        }
    ]
}
```

### Step 3: Create a browser session with proxy
<a name="browser-proxies-step3"></a>

You can create a browser session with proxy configuration using the AWS CLI, SDK, or API.

**Example**  

1. To start a browser session with a proxy using the AWS CLI:

   ```
   aws bedrock-agentcore start-browser-session \
     --browser-identifier "aws.browser.v1" \
     --name "my-proxy-session" \
     --proxy-configuration '{
       "proxies": [{
         "externalProxy": {
           "server": "your-proxy-hostname",
           "port": 8080,
           "credentials": {
             "basicAuth": {
               "secretArn": "arn:aws:secretsmanager:region:account-id:secret:secret-name"
             }
           }
         }
       }]
     }'
   ```

   For proxies using IP allowlisting instead of credentials, omit the `credentials` field:

   ```
   aws bedrock-agentcore start-browser-session \
     --browser-identifier "aws.browser.v1" \
     --name "my-proxy-session" \
     --proxy-configuration '{
       "proxies": [{
         "externalProxy": {
           "server": "your-proxy-hostname",
           "port": 8080
         }
       }]
     }'
   ```

1. To start a browser session with a proxy using the AWS SDK for Python (Boto3):

   ```
   import boto3
   
   client = boto3.client('bedrock-agentcore', region_name='region')
   
   response = client.start_browser_session(
       browserIdentifier="aws.browser.v1",
       name="my-proxy-session",
       proxyConfiguration={
           "proxies": [{
               "externalProxy": {
                   "server": "your-proxy-hostname",
                   "port": 8080,
                   "credentials": {
                       "basicAuth": {
                           "secretArn": "arn:aws:secretsmanager:region:account-id:secret:secret-name"
                       }
                   }
               }
           }]
       }
   )
   print(f"Session ID: {response['sessionId']}")
   ```

   For proxies using IP allowlisting instead of credentials, omit the `credentials` field:

   ```
   proxyConfiguration={
       "proxies": [{
           "externalProxy": {
               "server": "your-proxy-hostname",
               "port": 8080
           }
       }]
   }
   ```

1. To start a browser session with a proxy using the API:

   ```
   PUT /browsers/aws.browser.v1/sessions/start HTTP/1.1
   Host: bedrock-agentcore.region.amazonaws.com
   Content-Type: application/json
   Authorization: AWS4-HMAC-SHA256 ...
   
   {
     "name": "my-proxy-session",
     "proxyConfiguration": {
       "proxies": [{
         "externalProxy": {
           "server": "your-proxy-hostname",
           "port": 8080,
           "credentials": {
             "basicAuth": {
               "secretArn": "arn:aws:secretsmanager:region:account-id:secret:secret-name"
             }
           }
         }
       }]
     }
   }
   ```

## Configuration options
<a name="browser-proxies-configuration"></a>

### Domain-based routing
<a name="browser-proxies-domain-routing"></a>

Use `domainPatterns` to route specific domains through designated proxies:

**Example**  

1. 

   ```
   aws bedrock-agentcore start-browser-session \
     --browser-identifier "aws.browser.v1" \
     --name "domain-routing-session" \
     --proxy-configuration '{
       "proxies": [
         {
           "externalProxy": {
             "server": "corp-proxy.example.com",
             "port": 8080,
             "domainPatterns": [".company.com", ".internal.corp"]
           }
         },
         {
           "externalProxy": {
             "server": "general-proxy.example.com",
             "port": 8080
           }
         }
       ]
     }'
   ```

1. 

   ```
   proxyConfiguration={
       "proxies": [
           {
               "externalProxy": {
                   "server": "corp-proxy.example.com",
                   "port": 8080,
                   "domainPatterns": [".company.com", ".internal.corp"]
               }
           },
           {
               "externalProxy": {
                   "server": "general-proxy.example.com",
                   "port": 8080
               }
           }
       ]
   }
   ```

1. 

   ```
   {
     "proxyConfiguration": {
       "proxies": [
         {
           "externalProxy": {
             "server": "corp-proxy.example.com",
             "port": 8080,
             "domainPatterns": [".company.com", ".internal.corp"]
           }
         },
         {
           "externalProxy": {
             "server": "general-proxy.example.com",
             "port": 8080
           }
         }
       ]
     }
   }
   ```

With this configuration:
+ Requests to \$1.company.com and \$1.internal.corp route through `corp-proxy.example.com` 
+ All other requests route through `general-proxy.example.com` (default)

Domain pattern format:


| Pattern | Matches | Does not match | 
| --- | --- | --- | 
|   `.example.com`   |   `example.com` , `www.example.com` , `api.example.com`   |   `notexample.com`   | 
|   `example.com`   |   `example.com` (exact match only)  |   `www.example.com`   | 

Use `.example.com` (leading dot) for subdomains. Do not use \$1.example.com.

### Bypass domains
<a name="browser-proxies-bypass"></a>

Use `bypass.domainPatterns` for domains that should connect directly without any proxy:

**Example**  

1. 

   ```
   aws bedrock-agentcore start-browser-session \
     --browser-identifier "aws.browser.v1" \
     --name "bypass-session" \
     --proxy-configuration '{
       "proxies": [{
         "externalProxy": {
           "server": "proxy.example.com",
           "port": 8080
         }
       }],
       "bypass": {
         "domainPatterns": [".amazonaws.com"]
       }
     }'
   ```

1. 

   ```
   proxyConfiguration={
       "proxies": [{
           "externalProxy": {
               "server": "proxy.example.com",
               "port": 8080
           }
       }],
       "bypass": {
           "domainPatterns": [".amazonaws.com"]
       }
   }
   ```

1. 

   ```
   {
     "proxyConfiguration": {
       "proxies": [{
         "externalProxy": {
           "server": "proxy.example.com",
           "port": 8080
         }
       }],
       "bypass": {
         "domainPatterns": [".amazonaws.com"]
       }
     }
   }
   ```

**Note**  
Proxy configuration is a browser-level routing setting and does not provide network-level traffic control. For network-layer enforcement, deploy browser sessions in your VPC. See [Configure Amazon Bedrock AgentCore Runtime and tools for VPC](agentcore-vpc.md).

### Routing precedence
<a name="browser-proxies-routing-precedence"></a>

Traffic routes according to this precedence (highest to lowest):

1.  **Bypass domains** – Domains matching `bypass.domainPatterns` connect directly.

1.  **Proxy domain patterns** – Domains matching a proxy’s `domainPatterns` route through that proxy (first match wins based on array order).

1.  **Default proxy** – Unmatched domains route through the proxy without `domainPatterns`.

## Complete examples
<a name="browser-proxies-complete-examples"></a>

The following examples show a full proxy configuration with domain patterns, bypass domains, and authentication credentials.

**Example**  

1. 

   ```
   aws bedrock-agentcore start-browser-session \
     --browser-identifier "aws.browser.v1" \
     --name "proxy-session" \
     --proxy-configuration '{
       "proxies": [{
         "externalProxy": {
           "server": "proxy-hostname",
           "port": 8080,
           "domainPatterns": [".company.com"],
           "credentials": {
             "basicAuth": {
               "secretArn": "arn:aws:secretsmanager:region:account-id:secret:secret-name"
             }
           }
         }
       }],
       "bypass": {
         "domainPatterns": [".amazonaws.com"]
       }
     }'
   ```

1. 

   ```
   import boto3
   
   client = boto3.client('bedrock-agentcore', region_name='region')
   
   response = client.start_browser_session(
       browserIdentifier="aws.browser.v1",
       name="proxy-session",
       proxyConfiguration={
           "proxies": [{
               "externalProxy": {
                   "server": "proxy-hostname",
                   "port": 8080,
                   "domainPatterns": [".company.com"],
                   "credentials": {
                       "basicAuth": {
                           "secretArn": "arn:aws:secretsmanager:region:account-id:secret:secret-name"
                       }
                   }
               }
           }],
           "bypass": {
               "domainPatterns": [".amazonaws.com"]
           }
       }
   )
   print(f"Session ID: {response['sessionId']}")
   ```

1. 

   ```
   PUT /browsers/aws.browser.v1/sessions/start HTTP/1.1
   Host: bedrock-agentcore.region.amazonaws.com
   Content-Type: application/json
   Authorization: AWS4-HMAC-SHA256 ...
   
   {
     "name": "proxy-session",
     "proxyConfiguration": {
       "proxies": [{
         "externalProxy": {
           "server": "proxy-hostname",
           "port": 8080,
           "domainPatterns": [".company.com"],
           "credentials": {
             "basicAuth": {
               "secretArn": "arn:aws:secretsmanager:region:account-id:secret:secret-name"
             }
           }
         }
       }],
       "bypass": {
         "domainPatterns": [".amazonaws.com"]
       }
     }
   }
   ```

## Use cases
<a name="browser-proxies-use-cases"></a>

### IP stability for session-based portals
<a name="browser-proxies-use-case-ip-stability"></a>

Healthcare and financial portals often validate sessions based on source IP address. Rotating AWS IP addresses cause frequent re-authentication. Route traffic through a proxy with stable egress IPs to maintain session continuity.

### Corporate infrastructure integration
<a name="browser-proxies-use-case-corporate"></a>

Organizations that route traffic through corporate proxies can extend this practice to AgentCore Browser sessions, enabling access to internal webpages and resources that require proxy-based connectivity.

### Geographic content access
<a name="browser-proxies-use-case-geographic"></a>

Access region-specific content or test regional website variations by routing traffic through proxies in specific geographic locations.

### Partner network access
<a name="browser-proxies-use-case-partner"></a>

Route partner-specific traffic through dedicated proxy infrastructure while using general proxies for other traffic.

## Session behavior
<a name="browser-proxies-session-behavior"></a>

### Configuration lifecycle
<a name="browser-proxies-config-lifecycle"></a>
+  **Set at creation** – Proxy configuration is set once at session creation. Configuration changes at runtime are not supported. Create a new session to use different settings.
+  **Session-scoped** – Each browser session has independent proxy configuration.
+  **Timeout** – Standard session timeouts apply. Proxy configuration is discarded when the session ends.

### Connectivity behavior
<a name="browser-proxies-connectivity-behavior"></a>
+  **Fail-open** – Proxy connectivity is not validated at session creation. Sessions configured with unavailable proxies will show errors when loading pages.
+  **Runtime errors** – Connection failures appear as browser error pages, visible in Live View for troubleshooting.
+  **No automatic retry** – Failed requests are not automatically retried.

## Cross-account secret access
<a name="browser-proxies-cross-account"></a>

If the credentials secret is in a different AWS account, configure the following:

 **Secret resource policy** (in the account owning the secret):

```
{
"Version": "2012-10-17",		 	 	 
    "Statement": [{
        "Effect": "Allow",
        "Principal": {"AWS": "arn:aws:iam::caller-account-id:root"},
        "Action": "secretsmanager:GetSecretValue",
        "Resource": "*"
    }]
}
```

 **KMS key policy** (if using a customer-managed KMS key):

```
{
    "Effect": "Allow",
    "Principal": {"AWS": "arn:aws:iam::caller-account-id:root"},
    "Action": "kms:Decrypt",
    "Resource": "*"
}
```

## Security considerations
<a name="browser-proxies-security"></a>

### Credential protection
<a name="browser-proxies-credential-protection"></a>
+ Credentials are stored in AWS Secrets Manager and fetched using your IAM credentials.
+ Credentials are never returned in API responses. `GetBrowserSession` returns only `secretArn`.
+ Credentials are not written to logs.

### Access control
<a name="browser-proxies-access-control"></a>
+ IAM permissions control which identities can use which credential secrets.
+ Cross-account access requires explicit resource policies.

## Performance considerations
<a name="browser-proxies-performance"></a>
+  **Capacity** – Ensure your proxy can handle expected request volume.
+  **Bypass** – Add AWS endpoints to `bypass.domainPatterns` for latency-sensitive calls.
+  **Proximity** – Use proxies geographically close to your AWS Region.

## Constraints
<a name="browser-proxies-constraints"></a>


| Constraint | Limit | Adjustable | 
| --- | --- | --- | 
|  Maximum proxies per session  |  5  |  Yes  | 
|  Maximum domain patterns per proxy  |  100  |  Yes  | 
|  Maximum bypass domain patterns  |  100  |  Yes  | 
|  Server hostname length  |  253 characters  |  No  | 
|  Domain pattern length  |  253 characters  |  No  | 
|  Port range  |  1–65535  |  No  | 

To request an increase for adjustable constraints, contact AWS support.

## Limitations
<a name="browser-proxies-limitations"></a>

Before configuring browser proxies, review these limitations to ensure the feature meets your requirements:


| Limitation | Details | 
| --- | --- | 
|  Traffic routing  |  Proxy configuration is a browser-level setting applied at session startup. It is not a network-level control and does not guarantee that all traffic will transit the proxy. For network-layer enforcement, use [Configure Amazon Bedrock AgentCore Runtime and tools for VPC](agentcore-vpc.md).  | 
|  Supported protocols  |  HTTP and HTTPS proxies only. SOCKS4 and SOCKS5 proxies are not supported.  | 
|  Authentication  |  HTTP Basic authentication or no authentication (IP allowlisting). NTLM, Kerberos, and certificate-based authentication are not supported.  | 
|  Proxy changes  |  Proxy configuration is set once at session creation. Configuration changes at runtime are not supported. Create a new session to change proxy settings.  | 
|  Proxy rotation  |  Automatic proxy rotation for IP cycling or load distribution is not supported. Create new sessions to rotate proxies.  | 
|  Connection validation  |  Proxy connectivity is not validated at session creation. Connection errors appear at runtime.  | 

# Using browser enterprise policies
<a name="browser-enterprise-policies"></a>

Enterprise policies allow you to control browser behavior using the [Chromium enterprise policy](https://www.chromium.org/administrators/linux-quick-start/) mechanism. You provide policy files as JSON in your Amazon S3 bucket, and the service applies them to browser sessions automatically.

## Overview
<a name="browser-enterprise-policies-overview"></a>

Chromium enterprise policies can be applied at two enforcement levels:
+  **Managed** – Required and mandated by an administrator. These cannot be overridden. Managed policies are written to `/etc/chromium/policies/managed/`.
+  **Recommended** – Set at user level and take lower precedence to managed policies in the event of a conflict. Recommended policies are written to `/etc/chromium/policies/recommended/`.

For more details about Chrome policy types and precedence, see the [Chromium Linux Quick Start](https://www.chromium.org/administrators/linux-quick-start/).

Managed policies can be set using the `CreateBrowser` API and apply to all sessions created with that custom browser. Recommended policies are set at session level using the `StartBrowserSession` API and apply only to that specific session. They need to be re-applied to every new session.

You create JSON policy files following the [Chrome Enterprise Policy List](https://chromeenterprise.google/policies/) , upload them to your Amazon S3 bucket, and reference them when creating a browser or starting a session.

## Prerequisites
<a name="browser-enterprise-policies-prerequisites"></a>

Before using enterprise policies, ensure you have:
+ Completed the general Browser [Prerequisites](browser-quickstart.md#browser-prerequisites) 
+ An Amazon S3 bucket in the same region as your browser to store policy JSON files
+ IAM permissions to access the Amazon S3 bucket containing your policy files. Add the following permissions to your IAM policy:

  ```
  {
  "Version": "2012-10-17",		 	 	 
      "Statement": [
          {
              "Sid": "EnterprisePolicyS3Access",
              "Effect": "Allow",
              "Action": [
                  "s3:GetObject",
                  "s3:GetObjectVersion"
              ],
              "Resource": [
                  "arn:aws:s3:::<S3Bucket>/<path_to_policies>/*"
              ]
          }
      ]
  }
  ```
+ Policy JSON files following the Chromium enterprise policy format. Each file must contain valid policy keys from the [Chrome Enterprise Policy List](https://chromeenterprise.google/policies/).

## Preparing policy files
<a name="browser-enterprise-policies-preparing"></a>

Create JSON files containing the policies you want to apply. Each file should contain a flat JSON object with policy keys and values.

 **Example managed policy file** 

This file disables autofill and password saving:

```
{
    "AutofillAddressEnabled": false,
    "AutofillCreditCardEnabled": false,
    "PasswordManagerEnabled": false
}
```

 **Example recommended policy file** 

This file is used to set policies at session level:

```
{
    "BookmarkBarEnabled": true,
    "SpellCheckServiceEnabled": false,
    "TranslateEnabled": false
}
```

Upload the policy files to your Amazon S3 bucket:

```
aws s3 cp managed-policies.json s3://my-policy-bucket/policies/managed-policies.json
aws s3 cp recommended-policies.json s3://my-policy-bucket/policies/recommended-policies.json
```

**Note**  
You can specify up to 10 enterprise policy files. The Amazon S3 bucket must be in the same region as the browser.

## Creating a custom browser with managed policies
<a name="browser-enterprise-policies-custom-browser"></a>

To enforce enterprise policies that cannot be overridden, create a custom browser with managed policies. Managed policies are applied to every session created with this browser.

**Example**  

1. 

   ```
   aws bedrock-agentcore-control create-browser \
     --region <Region> \
     --name "my-managed-browser" \
     --enterprise-policies '[
       {
         "type": "MANAGED",
         "location": {
           "s3": {
             "bucket": "my-policy-bucket",
             "prefix": "policies/managed-policies.json"
           }
         }
       }
     ]'
   ```

1. 

   ```
   import boto3
   
   region = "us-west-2"
   client = boto3.client('bedrock-agentcore-control', region_name=region)
   
   response = client.create_browser(
       name="my-managed-browser",
       enterprisePolicies=[
           {
               "type": "MANAGED",
               "location": {
                   "s3": {
                       "bucket": "my-policy-bucket",
                       "prefix": "policies/managed-policies.json"
                   }
               }
           }
       ]
   )
   
   browser_id = response['browserId']
   print(f"Created browser: {browser_id}")
   ```

1. 

   ```
   awscurl -X PUT \
     "https://bedrock-agentcore-control.<Region>.amazonaws.com/browsers" \
     -H "Content-Type: application/json" \
     --service bedrock-agentcore-control \
     --region <Region> \
     -d '{
       "name": "my-managed-browser",
       "enterprisePolicies": [
         {
           "type": "MANAGED",
           "location": {
             "s3": {
               "bucket": "my-policy-bucket",
               "prefix": "policies/managed-policies.json"
             }
           }
         }
       ]
     }'
   ```

## Starting a session with recommended policies
<a name="browser-enterprise-policies-recommended"></a>

Recommended policies can be applied to sessions using the default browser ( `aws.browser.v1` ) as well as custom browsers that may already include managed policies.

**Tip**  
For the default browser, set `browserIdentifier` to `aws.browser.v1`.

**Example**  

1. 

   ```
   aws bedrock-agentcore start-browser-session \
     --region <Region> \
     --browser-identifier "<BrowserId>" \
     --name "my-session-with-policies" \
     --session-timeout-seconds 1800 \
     --enterprise-policies '[
       {
         "type": "RECOMMENDED",
         "location": {
           "s3": {
             "bucket": "my-policy-bucket",
             "prefix": "policies/recommended-policies.json"
           }
         }
       }
     ]'
   ```

1. 

   ```
   import boto3
   
   region = "us-west-2"
   client = boto3.client('bedrock-agentcore', region_name=region)
   
   response = client.start_browser_session(
       browserIdentifier="<BrowserId>",
       name="my-session-with-policies",
       sessionTimeoutSeconds=1800,
       enterprisePolicies=[
           {
               "type": "RECOMMENDED",
               "location": {
                   "s3": {
                       "bucket": "my-policy-bucket",
                       "prefix": "policies/recommended-policies.json"
                   }
               }
           }
       ]
   )
   
   print(f"Session ID: {response['sessionId']}")
   ```

1. 

   ```
   awscurl -X PUT \
     "https://bedrock-agentcore.<Region>.amazonaws.com/browsers/<BrowserId>/sessions/start" \
     -H "Content-Type: application/json" \
     -H "Accept: application/json" \
     --service bedrock-agentcore \
     --region <Region> \
     -d '{
       "name": "my-session-with-policies",
       "sessionTimeoutSeconds": 1800,
       "enterprisePolicies": [
         {
           "type": "RECOMMENDED",
           "location": {
             "s3": {
               "bucket": "my-policy-bucket",
               "prefix": "policies/recommended-policies.json"
             }
           }
         }
       ]
     }'
   ```

## Considerations
<a name="browser-enterprise-policies-considerations"></a>
+ You can specify up to 10 enterprise policy files.
+ Each policy file must have a `.json` extension and cannot exceed 5 MB in size.
+ The Amazon S3 bucket must be in the same region as the browser.
+ Policy files are read from Amazon S3 at the time of the API call. Changes to policy files in Amazon S3 after calling `CreateBrowser` or `StartBrowserSession` are not reflected.
+ Policy JSON files must contain valid keys from the [Chrome Enterprise Policy List](https://chromeenterprise.google/policies/).

# Configure Root Certificate Authority for Amazon Bedrock AgentCore Browser
<a name="browser-root-ca-certificates"></a>

By default, Amazon Bedrock AgentCore Browser sessions trust only publicly recognized certificate authorities. If your agents need to access internal services, corporate websites, or resources behind a TLS-intercepting proxy that use certificates signed by a private CA, you must provide your custom root CA certificates when starting a session.

Amazon Bedrock AgentCore retrieves the PEM-encoded certificate content from AWS Secrets Manager using your caller credentials, validates the X.509 format and expiry, and installs the certificates into the session’s OS trust store. This enables the browser to establish trusted HTTPS connections to your internal resources.

## How it works
<a name="browser-root-ca-how-it-works"></a>

Root Certificate Authority for Amazon Bedrock AgentCore Browser works as follows:

1. You provide a list of certificate locations, each pointing to a secret in AWS Secrets Manager that contains a PEM-encoded root CA certificate.

1. Amazon Bedrock AgentCore uses your caller credentials to retrieve each certificate from AWS Secrets Manager.

1. Each certificate is validated for correct X.509 PEM format and checked to ensure it has not expired and is not used before its validity start date.

1. Valid certificates are deployed to the session’s OS trust store, making them available to the browser and any network clients within the sandbox.

Certificates configured at the tool level (through `CreateBrowser` ) are combined with any certificates provided at session start time. This allows you to set organization-wide certificates on the tool and add session-specific certificates as needed.

**Note**  
Certificate configuration is a one-time operation per session. Once certificates are installed, they cannot be modified for the duration of that session.

## Prerequisites
<a name="browser-root-ca-prerequisites"></a>

Before configuring root CA certificates, ensure you have the following:
+ Completed the general [Prerequisites](browser-quickstart.md#browser-prerequisites).
+ Your root CA certificates stored as secrets in AWS Secrets Manager. Each secret must contain valid PEM-encoded X.509 certificate
+ IAM permissions to read the certificate secrets from AWS Secrets Manager. Add the following permissions to your IAM policy:

  ```
  {
  "Version": "2012-10-17",		 	 	 
      "Statement": [
          {
              "Sid": "SecretsManagerCertificateAccess",
              "Effect": "Allow",
              "Action": [
                  "secretsmanager:GetSecretValue"
              ],
              "Resource": "arn:aws:secretsmanager:<Region>:<account-id>:secret:<secret-name>"
          }
      ]
  }
  ```

## Store your certificate in AWS Secrets Manager
<a name="browser-root-ca-store-certificate"></a>

Before you can use a root CA certificate with Amazon Bedrock AgentCore Browser, you must store it as a secret in AWS Secrets Manager. The secret value must be the PEM-encoded certificate content.

**Example**  

1. 

   ```
   aws secretsmanager create-secret \
     --name "my-corporate-root-ca" \
     --description "Corporate root CA certificate for AgentCore sessions" \
     --secret-string file://my-root-ca.pem \
     --region <region>
   ```

1. 

   ```
   import boto3
   
   client = boto3.client('secretsmanager', region_name='<region>')
   
   # Read the PEM certificate file
   with open('my-root-ca.pem', 'r') as f:
       cert_content = f.read()
   
   response = client.create_secret(
       Name='my-corporate-root-ca',
       Description='Corporate root CA certificate for AgentCore sessions',
       SecretString=cert_content
   )
   
   print(f"Secret ARN: {response['ARN']}")
   ```

Note the secret ARN from the output. You will use this ARN when starting sessions with certificate configuration.

**Important**  
The secret must contain a valid PEM-encoded X.509 certificate. The certificate must not be expired and must be within its validity period. Amazon Bedrock AgentCore validates the certificate format and expiry before installing it.

## Start a browser session with custom certificates
<a name="browser-root-ca-session"></a>

To start a browser session that trusts your custom root CA certificates, include the `certificates` parameter in your `StartBrowserSession` request.

**Example**  

1. 

   ```
   aws bedrock-agentcore start-browser-session \
     --browser-identifier "aws.browser.v1" \
     --name "session-with-custom-ca" \
     --certificates '[
       {
         "location": {
           "secretsManager": {
             "secretArn": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>"
           }
         }
       }
     ]'
   ```

1. 

   ```
   import boto3
   
   client = boto3.client('bedrock-agentcore', region_name='<region>')
   
   response = client.start_browser_session(
       browserIdentifier="aws.browser.v1",
       name="session-with-custom-ca",
       certificates=[
           {
               "location": {
                   "secretsManager": {
                       "secretArn": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>"
                   }
               }
           }
       ]
   )
   
   print(f"Session ID: {response['sessionId']}")
   print(f"Status: {response['status']}")
   ```

1. 

   ```
   {
     "name": "session-with-custom-ca",
     "certificates": [
       {
         "location": {
           "secretsManager": {
             "secretArn": "arn:aws:secretsmanager:<region>:<account-id>:secret:<secret-name>"
           }
         }
       }
     ]
   }
   ```

## Using multiple certificates
<a name="browser-root-ca-multiple-certificates"></a>

You can provide multiple root CA certificates in a single browser session. This is useful when your environment requires trust for multiple internal certificate authorities, such as separate CAs for different internal services or environments.

**Example**  

1. 

   ```
   aws bedrock-agentcore start-browser-session \
     --browser-identifier "aws.browser.v1" \
     --name "session-with-multiple-cas" \
     --certificates '[
       {
         "location": {
           "secretsManager": {
             "secretArn": "arn:aws:secretsmanager:<region>:<account-id>:secret:corporate-root-ca"
           }
         }
       },
       {
         "location": {
           "secretsManager": {
             "secretArn": "arn:aws:secretsmanager:<region>:<account-id>:secret:proxy-ca"
           }
         }
       }
     ]'
   ```

1. 

   ```
   response = client.start_browser_session(
       browserIdentifier="aws.browser.v1",
       name="session-with-multiple-cas",
       certificates=[
           {
               "location": {
                   "secretsManager": {
                       "secretArn": "arn:aws:secretsmanager:<region>:<account-id>:secret:corporate-root-ca"
                   }
               }
           },
           {
               "location": {
                   "secretsManager": {
                       "secretArn": "arn:aws:secretsmanager:<region>:<account-id>:secret:proxy-ca"
                   }
               }
           }
       ]
   )
   ```

## Configure certificates at the tool level
<a name="browser-root-ca-tool-level"></a>

You can configure certificates at the tool level when creating a custom browser. Certificates configured at the tool level are automatically applied to every session started with that tool, in addition to any certificates provided at session start time.

This is useful for organization-wide certificates that should be trusted by all browser sessions.

**Example**  

1. 

   ```
   response = client.create_browser(
       name="corporate-browser",
       description="Browser with corporate CA trust",
       certificates=[
           {
               "location": {
                   "secretsManager": {
                       "secretArn": "arn:aws:secretsmanager:<region>:<account-id>:secret:corporate-root-ca"
                   }
               }
           }
       ]
   )
   
   browser_id = response['browserIdentifier']
   print(f"Browser ID: {browser_id}")
   ```

When you start a session with a browser that has certificates configured, the tool-level certificates are combined with any session-level certificates. Tool-level certificates are applied first, followed by session-level certificates.

## Certificate requirements and limits
<a name="browser-root-ca-certificate-requirements"></a>

Certificates must meet the following requirements:


| Requirement | Details | 
| --- | --- | 
|  Format  |  PEM-encoded X.509 certificate  | 
|  Storage  |   AWS Secrets Manager secret (as a string value, not binary)  | 
|  Validity  |  Certificate must not be expired and must be within its validity period (between `notBefore` and `notAfter` dates)  | 
|  Maximum certificates per session  |  10 per session and 10 per tool. A session can have up to 20 certificates in total.  | 
|  Secret ARN format  |   `arn:aws:secretsmanager:region:account-id:secret:secret-name`   | 
|  Location type  |  Only AWS Secrets Manager is supported as a certificate location  | 

# Browser OS action
<a name="browser-invoke"></a>

The InvokeBrowser API provides direct operating system-level control over Amazon Bedrock AgentCore Browser sessions. While the WebSocket-based automation endpoint uses Chrome DevTools Protocol (CDP) for browser interaction, InvokeBrowser operates at the OS level, enabling actions that CDP cannot handle — such as interacting with print dialogs, keyboard shortcuts, right-click context menus, JavaScript alerts, and capturing full-screen screenshots.

## Overview
<a name="browser-invoke-overview"></a>

The Amazon Bedrock AgentCore Browser provides two ways to interact with a browser session:
+  **WebSocket-based automation (CDP)** : Uses the Chrome DevTools Protocol over a WebSocket connection. This is ideal for standard browser automation tasks such as navigating pages, clicking DOM elements, filling forms, and extracting page content. Libraries like Playwright and browser-use connect through this endpoint.
+  **OS-level actions (InvokeBrowser)** : Uses a REST API to perform operating system-level interactions through mouse, keyboard, and screenshot actions. This complements CDP by handling scenarios where browser-level automation is insufficient.

Use InvokeBrowser when your agent needs to:
+ Interact with native OS dialogs such as print dialogs, file upload/download dialogs, or authentication prompts that are outside the browser DOM
+ Dismiss JavaScript alerts, confirms, or prompts that block CDP execution
+ Use keyboard shortcuts (for example, ctrl\$1a, ctrl\$1p) that trigger OS-level behavior
+ Interact with right-click context menus rendered by the operating system
+ Capture full desktop screenshots that include content outside the browser viewport, such as OS notifications or multi-window layouts
+ Perform drag-and-drop operations that span across browser windows or between the browser and the desktop

InvokeBrowser follows the same pattern as InvokeCodeInterpreter: a single unified operation with action-type dispatch. You send a request with exactly one action, and receive a corresponding result.

## Supported actions
<a name="browser-invoke-supported-actions"></a>

InvokeBrowser supports the following action types through the `BrowserAction` union. Exactly one action member must be set per request.

### Mouse actions
<a name="browser-invoke-mouse-actions"></a>

For all mouse actions, coordinate values ( `x` , `y` ) must be strictly within the browser session viewport bounds. Valid ranges are 1 < x < viewportWidth-2 and 1 < y < viewportHeight-2. The default viewport size is 1456×819 pixels, which can be configured when starting a session using the `viewPort` parameter.


| Action | Required fields | Optional fields | Description | 
| --- | --- | --- | --- | 
|   `mouseClick`   |   `x` (Integer), `y` (Integer)  |   `button` (MouseButton), `clickCount` (Integer)  |  Click at the specified coordinates. `clickCount` : 1–10. `button` : LEFT, RIGHT, MIDDLE.  | 
|   `mouseMove`   |   `x` (Integer), `y` (Integer)  |  —  |  Move cursor to the specified coordinates.  | 
|   `mouseDrag`   |   `startX` (Integer), `startY` (Integer), `endX` (Integer), `endY` (Integer)  |   `button` (MouseButton)  |  Drag from start to end position. `button` defaults to LEFT.  | 
|   `mouseScroll`   |   `x` (Integer), `y` (Integer)  |   `deltaX` (Integer), `deltaY` (Integer)  |  Scroll at the specified position. `deltaX` / `deltaY` : -1000 to 1000. Negative `deltaY` scrolls down.  | 

### Keyboard actions
<a name="browser-invoke-keyboard-actions"></a>


| Action | Required fields | Optional fields | Description | 
| --- | --- | --- | --- | 
|   `keyType`   |   `text` (String)  |  —  |  Type a string of text. Maximum length: 10,000 characters.  | 
|   `keyPress`   |   `key` (String)  |   `presses` (Integer)  |  Press a key N times. `presses` : 1–100. Defaults to 1.  | 
|   `keyShortcut`   |   `keys` (KeyList)  |  —  |  Press a key combination (for example, `["ctrl", "s"]` ). Maximum 5 keys.  | 

### Screenshot action
<a name="browser-invoke-screenshot-action"></a>


| Action | Required fields | Optional fields | Description | 
| --- | --- | --- | --- | 
|   `screenshot`   |  —  |   `format` (ScreenshotFormat)  |  Capture the full OS desktop (not just the browser viewport). Format: PNG only.  | 

## Considerations
<a name="browser-invoke-considerations"></a>
+  **ASCII-only text input** : The `keyType` action supports ASCII characters only. Non-ASCII characters (such as Unicode or multi-byte characters) are skipped during input.
+  **No key name validation** : The `keyPress` and `keyShortcut` actions do not validate whether the specified key names are supported. If you provide an unrecognized key name, the API returns a SUCCESS status without performing the intended action. Refer to the supported key names listed above.
+  **Supported key names** : Key names for `keyPress` and `keyShortcut` actions must be in lowercase. Supported keys include single characters ( `a` – `z` , `0` – `9` ), and named keys such as `enter` , `tab` , `space` , `backspace` , `delete` , `escape` , `ctrl` , `alt` , `shift`.

## Request and response format
<a name="browser-invoke-request-response"></a>

### Request
<a name="browser-invoke-request"></a>

```
POST /browsers/{browserIdentifier}/sessions/invoke HTTP/1.1
x-amzn-browser-session-id: sessionId
Content-type: application/json
```

The request body contains an `action` field with exactly one member of the `BrowserAction` union set:

```
{
    "action": {
        "mouseClick": {
            "x": 100,
            "y": 200,
            "button": "LEFT",
            "clickCount": 1
        }
    }
}
```

### Response
<a name="browser-invoke-response"></a>

The `sessionId` is returned via the `x-amzn-browser-session-id` response header. The response body contains a `result` field with the corresponding action result.

On success:

```
{
    "result": {
        "mouseClick": {
            "status": "SUCCESS",
            "error": null
        }
    }
}
```

On failure, the `status` field is set to FAILED and the `error` field contains a description of the failure.

## Examples
<a name="browser-invoke-examples"></a>

The following examples show how to invoke browser actions using the AWS CLI, AWS SDK for Python (Boto3), and the API.

**Example**  

1. To click at a specific position:

   ```
   aws bedrock-agentcore invoke-browser \
     --region <Region> \
     --browser-identifier "aws.browser.v1" \
     --session-id "<your-session-id>" \
     --action '{"mouseClick": {"x": 100, "y": 200, "button": "LEFT", "clickCount": 1}}'
   ```

   To type text:

   ```
   aws bedrock-agentcore invoke-browser \
     --region <Region> \
     --browser-identifier "aws.browser.v1" \
     --session-id "<your-session-id>" \
     --action '{"keyType": {"text": "Hello, world!"}}'
   ```

   To press a keyboard shortcut:

   ```
   aws bedrock-agentcore invoke-browser \
     --region <Region> \
     --browser-identifier "aws.browser.v1" \
     --session-id "<your-session-id>" \
     --action '{"keyShortcut": {"keys": ["ctrl", "s"]}}'
   ```

   To take a screenshot:

   ```
   aws bedrock-agentcore invoke-browser \
     --region <Region> \
     --browser-identifier "aws.browser.v1" \
     --session-id "<your-session-id>" \
     --action '{"screenshot": {"format": "PNG"}}'
   ```

1. To click at a specific position:

   ```
   response = dp_client.invoke_browser(
       browserIdentifier="aws.browser.v1",
       sessionId="<your-session-id>",
       action={
           "mouseClick": {
               "x": 100,
               "y": 200,
               "button": "LEFT",
               "clickCount": 1
           }
       }
   )
   print(f"Status: {response['result']['mouseClick']['status']}")
   ```

   To type text:

   ```
   response = dp_client.invoke_browser(
       browserIdentifier="aws.browser.v1",
       sessionId="<your-session-id>",
       action={
           "keyType": {
               "text": "Hello, world!"
           }
       }
   )
   ```

   To take a screenshot and save it:

   ```
   import base64
   
   response = dp_client.invoke_browser(
       browserIdentifier="aws.browser.v1",
       sessionId="<your-session-id>",
       action={
           "screenshot": {
               "format": "PNG"
           }
       }
   )
   
   if response['result']['screenshot']['status'] == 'SUCCESS':
       image_data = base64.b64decode(response['result']['screenshot']['data'])
       with open("screenshot.png", "wb") as f:
           f.write(image_data)
       print("Screenshot saved as screenshot.png")
   ```

1. To click at a specific position:

   ```
   awscurl -X POST \
     "https://bedrock-agentcore.<Region>.amazonaws.com/browsers/aws.browser.v1/sessions/invoke" \
     -H "Content-Type: application/json" \
     -H "Accept: application/json" \
     -H "x-amzn-browser-session-id: <your-session-id>" \
     --service bedrock-agentcore \
     --region <Region> \
     -d '{
       "action": {
           "mouseClick": {
               "x": 100,
               "y": 200,
               "button": "LEFT",
               "clickCount": 1
           }
       }
     }'
   ```

   To take a screenshot:

   ```
   awscurl -X POST \
     "https://bedrock-agentcore.<Region>.amazonaws.com/browsers/aws.browser.v1/sessions/invoke" \
     -H "Content-Type: application/json" \
     -H "Accept: application/json" \
     -H "x-amzn-browser-session-id: <your-session-id>" \
     --service bedrock-agentcore \
     --region <Region> \
     -d '{
       "action": {
           "screenshot": {
               "format": "PNG"
           }
       }
     }'
   ```