Skip to content

Commit 439495f

Browse files
authored
feat(agentcore): add new properties for runtime, browser (#36003)
### Issue # (if applicable) Add support for new properties in agentcore alpha package: - Runtime: - [Code Configuration](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-bedrockagentcore-runtime-codeconfiguration.html) (Direct code deployment) - [Lifecycle configuration](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-bedrockagentcore-runtime-lifecycleconfiguration.html) - [Request header configuration](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-bedrockagentcore-runtime-requestheaderconfiguration.html) - Browser: - [Browser signing](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-properties-bedrockagentcore-browsercustom-browsersigning.html) Also fix a warning (@param userPoolClients) in JSDoc due to wrong param name (missing 's') ### Reason for this change Supporting new features ### Description of changes Adding support for new properties, not changing existing implementation ### Describe any new or updated permissions being added Granting permissions on bucket when using code configuration as a runtime artifact ### Description of how you validated changes unit tests, integration tests, manual tests Example: - Deploying a runtime from a zip available in S3: ```ts const agentArtifact = AgentRuntimeArtifact.fromS3({ bucketName: 'XXXXXXXXXX', objectKey: 'deployment_package.zip', }, AgentCoreRuntime.PYTHON_3_13, ['main.py']); const runtime1 = new Runtime(this, 'MinimalRuntime', { runtimeName: 'minimal_runtime', agentRuntimeArtifact: agentArtifact, requestHeaderConfiguration: { allowList: ['X-Amzn-Bedrock-AgentCore-Runtime-Custom-H1'] }, lifecycleConfiguration: { idleRuntimeSessionTimeout: Duration.minutes(10), maxLifetime: Duration.hours(4), }, }); // Grant permission to invoke Bedrock models ... ``` <img width="1062" height="79" alt="image" src="https://github.com/user-attachments/assets/5af7a392-5d31-4e5a-b2c0-b3a2e7fd57b6" /> - Deploying a browser with signing enabled ```ts new BrowserCustom(this, 'Browser', { browserCustomName: 'my-browser', description: 'Strands browser', browserSigning: BrowserSigning.ENABLED, }); ``` <img width="1232" height="339" alt="Screenshot 2025-11-19 at 4 53 22 PM" src="https://github.com/user-attachments/assets/f9906ddb-ed37-4170-8cf9-6d8b08c92a2e" /> ### Checklist - [X] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 01534a0 commit 439495f

33 files changed

+1305
-217
lines changed

packages/@aws-cdk/aws-bedrock-agentcore-alpha/README.md

Lines changed: 119 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ This construct library facilitates the deployment of Bedrock AgentCore primitive
8080
- [Creating a Runtime](#creating-a-runtime)
8181
- [Option 1: Use an existing image in ECR](#option-1-use-an-existing-image-in-ecr)
8282
- [Option 2: Use a local asset](#option-2-use-a-local-asset)
83+
- [Option 3: Use direct code deployment](#option-3-use-direct-code-deployment)
8384
- [Granting Permissions to Invoke Bedrock Models or Inference Profiles](#granting-permissions-to-invoke-bedrock-models-or-inference-profiles)
8485
- [Runtime Versioning](#runtime-versioning)
8586
- [Managing Endpoints and Versions](#managing-endpoints-and-versions)
@@ -163,6 +164,8 @@ to production by simply updating the endpoint to point to the newer version.
163164
| `authorizerConfiguration` | `RuntimeAuthorizerConfiguration` | No | Authorizer configuration for the agent runtime. Use `RuntimeAuthorizerConfiguration` static methods to create configurations for IAM, Cognito, JWT, or OAuth authentication |
164165
| `environmentVariables` | `{ [key: string]: string }` | No | Environment variables for the agent runtime. Maximum 50 environment variables |
165166
| `tags` | `{ [key: string]: string }` | No | Tags for the agent runtime. A list of key:value pairs of tags to apply to this Runtime resource |
167+
| `lifecycleConfiguration` | LifecycleConfiguration | No | The life cycle configuration for the AgentCore Runtime. Defaults to 900 seconds (15 minutes) for idle, 28800 seconds (8 hours) for max life time |
168+
| `requestHeaderConfiguration` | RequestHeaderConfiguration | No | Configuration for HTTP request headers that will be passed through to the runtime. Defaults to no configuration |
166169

167170
### Runtime Endpoint Properties
168171

@@ -180,7 +183,7 @@ to production by simply updating the endpoint to point to the newer version.
180183

181184
Reference an image available within ECR.
182185

183-
```typescript
186+
```typescript fixture=default
184187
const repository = new ecr.Repository(this, "TestRepository", {
185188
repositoryName: "test-agent-runtime",
186189
});
@@ -201,7 +204,7 @@ Reference a local directory containing a Dockerfile.
201204
Images are built from a local Docker context directory (with a Dockerfile), uploaded to Amazon Elastic Container Registry (ECR)
202205
by the CDK toolkit,and can be naturally referenced in your CDK app.
203206

204-
```typescript
207+
```typescript fixture=default
205208
const agentRuntimeArtifact = agentcore.AgentRuntimeArtifact.fromAsset(
206209
path.join(__dirname, "path to agent dockerfile directory")
207210
);
@@ -212,6 +215,40 @@ const runtime = new agentcore.Runtime(this, "MyAgentRuntime", {
212215
});
213216
```
214217

218+
#### Option 3: Use direct code deployment
219+
220+
With the container deployment method, developers create a Dockerfile, build ARM-compatible containers, manage ECR repositories, and upload containers for code changes. This works well where container DevOps pipelines have already been established to automate deployments.
221+
222+
However, customers looking for fully managed deployments can benefit from direct code deployment, which can significantly improve developer time and productivity. Direct code deployment provides a secure and scalable path forward for rapid prototyping agent capabilities to deploying production workloads at scale.
223+
224+
With direct code deployment, developers create a zip archive of code and dependencies, upload to Amazon S3, and configure the bucket in the agent configuration. A ZIP archive containing Linux arm64 dependencies needs to be uploaded to S3 as a pre-requisite to Create Agent Runtime.
225+
226+
For more information, please refer to the [documentation](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-get-started-code-deploy.html).
227+
228+
```typescript fixture=default
229+
// S3 bucket containing the agent core
230+
const codeBucket = new s3.Bucket(this, "AgentCode", {
231+
bucketName: "my-code-bucket",
232+
removalPolicy: RemovalPolicy.DESTROY, // For demo purposes
233+
});
234+
235+
// the bucket above needs to contain the agent code
236+
237+
const agentRuntimeArtifact = agentcore.AgentRuntimeArtifact.fromS3(
238+
{
239+
bucketName: codeBucket.bucketName,
240+
objectKey: 'deployment_package.zip',
241+
},
242+
agentcore.AgentCoreRuntime.PYTHON_3_12,
243+
['opentelemetry-instrument', 'main.py']
244+
);
245+
246+
const runtimeInstance = new agentcore.Runtime(this, "MyAgentRuntime", {
247+
runtimeName: "myAgent",
248+
agentRuntimeArtifact: agentRuntimeArtifact,
249+
});
250+
```
251+
215252
### Granting Permissions to Invoke Bedrock Models or Inference Profiles
216253

217254
To grant the runtime permissions to invoke Bedrock models or inference profiles:
@@ -254,7 +291,7 @@ the steps below to understand how to use versioning with runtime for controlled
254291
When you first create an agent runtime, AgentCore automatically creates Version 1 of your runtime. At this point, a DEFAULT endpoint is
255292
automatically created that points to Version 1. This DEFAULT endpoint serves as the main access point for your runtime.
256293

257-
```ts
294+
```typescript fixture=default
258295
const repository = new ecr.Repository(this, "TestRepository", {
259296
repositoryName: "test-agent-runtime",
260297
});
@@ -271,7 +308,7 @@ After the initial deployment, you can create additional endpoints for different
271308
endpoint that explicitly points to Version 1. This allows you to maintain stable access points for specific environments while keeping the
272309
flexibility to test newer versions elsewhere.
273310

274-
```ts
311+
```typescript fixture=default
275312
const repository = new ecr.Repository(this, "TestRepository", {
276313
repositoryName: "test-agent-runtime",
277314
});
@@ -296,7 +333,7 @@ configurations), AgentCore automatically creates a new version (Version 2). Upon
296333
- The DEFAULT endpoint automatically updates to point to Version 2
297334
- Any explicitly pinned endpoints (like the production endpoint) remain on their specified versions
298335

299-
```ts
336+
```typescript fixture=default
300337
const repository = new ecr.Repository(this, "TestRepository", {
301338
repositoryName: "test-agent-runtime",
302339
});
@@ -315,7 +352,7 @@ Once Version 2 exists, you can create a staging endpoint that points to the new
315352
new version in a controlled environment before promoting it to production. This separation ensures that production traffic continues
316353
to use the stable version while you validate the new version.
317354

318-
```ts
355+
```typescript fixture=default
319356
const repository = new ecr.Repository(this, "TestRepository", {
320357
repositoryName: "test-agent-runtime",
321358
});
@@ -338,7 +375,7 @@ const stagingEndpoint = runtime.addEndpoint("staging", {
338375
After thoroughly testing the new version through the staging endpoint, you can update the production endpoint to point to Version 2.
339376
This controlled promotion process ensures that you can validate changes before they affect production traffic.
340377

341-
```ts
378+
```typescript fixture=default
342379
const repository = new ecr.Repository(this, "TestRepository", {
343380
repositoryName: "test-agent-runtime",
344381
});
@@ -362,7 +399,7 @@ RuntimeEndpoint can also be created as a standalone resource.
362399

363400
#### Example: Creating an endpoint for an existing runtime
364401

365-
```typescript
402+
```typescript fixture=default
366403
// Reference an existing runtime by its ID
367404
const existingRuntimeId = "abc123-runtime-id"; // The ID of an existing runtime
368405

@@ -387,7 +424,7 @@ IAM authentication is the default mode, when no authorizerConfiguration is set t
387424

388425
To configure AWS Cognito User Pool authentication:
389426

390-
```typescript
427+
```typescript fixture=default
391428
declare const userPool: cognito.UserPool;
392429
declare const userPoolClient: cognito.UserPoolClient;
393430
declare const anotherUserPoolClient: cognito.UserPoolClient;
@@ -411,7 +448,7 @@ const runtime = new agentcore.Runtime(this, "MyAgentRuntime", {
411448

412449
To configure custom JWT authentication with your own OpenID Connect (OIDC) provider:
413450

414-
```typescript
451+
```typescript fixture=default
415452
const repository = new ecr.Repository(this, "TestRepository", {
416453
repositoryName: "test-agent-runtime",
417454
});
@@ -434,7 +471,7 @@ const runtime = new agentcore.Runtime(this, "MyAgentRuntime", {
434471

435472
To configure OAuth 2.0 authentication:
436473

437-
```typescript
474+
```typescript fixture=default
438475
const repository = new ecr.Repository(this, "TestRepository", {
439476
repositoryName: "test-agent-runtime",
440477
});
@@ -463,7 +500,7 @@ The AgentCore Runtime supports two network modes for deployment:
463500

464501
By default, runtimes are deployed in PUBLIC network mode, which provides internet access suitable for less sensitive or open-use scenarios:
465502

466-
```typescript
503+
```typescript fixture=default
467504
const repository = new ecr.Repository(this, "TestRepository", {
468505
repositoryName: "test-agent-runtime",
469506
});
@@ -481,7 +518,7 @@ const runtime = new agentcore.Runtime(this, "MyAgentRuntime", {
481518

482519
For enhanced security and network isolation, you can deploy your runtime within a VPC:
483520

484-
```typescript
521+
```typescript fixture=default
485522
const repository = new ecr.Repository(this, "TestRepository", {
486523
repositoryName: "test-agent-runtime",
487524
});
@@ -510,8 +547,7 @@ const runtime = new agentcore.Runtime(this, "MyAgentRuntime", {
510547

511548
When using VPC mode, the Runtime implements `ec2.IConnectable`, allowing you to manage network access using the `connections` property:
512549

513-
```typescript
514-
550+
```typescript fixture=default
515551
const vpc = new ec2.Vpc(this, 'MyVpc', {
516552
maxAzs: 2,
517553
});
@@ -544,6 +580,58 @@ runtime.connections.allowTo(databaseSecurityGroup, ec2.Port.tcp(5432), 'Allow Po
544580
runtime.connections.allowToAnyIpv4(ec2.Port.tcp(443), 'Allow HTTPS outbound');
545581
```
546582

583+
### Other configuration
584+
585+
#### Lifecycle configuration
586+
587+
The LifecycleConfiguration input parameter to CreateAgentRuntime lets you manage the lifecycle of runtime sessions and resources in Amazon Bedrock AgentCore Runtime. This configuration helps optimize resource utilization by automatically cleaning up idle sessions and preventing long-running instances from consuming resources indefinitely.
588+
589+
You can configure:
590+
591+
- idleRuntimeSessionTimeout: Timeout in seconds for idle runtime sessions. When a session remains idle for this duration, it will trigger termination. Termination can last up to 15 seconds due to logging and other process completion. Default: 900 seconds (15 minutes)
592+
- maxLifetime: Maximum lifetime for the instance in seconds. Once reached, instances will initialize termination. Termination can last up to 15 seconds due to logging and other process completion. Default: 28800 seconds (8 hours)
593+
594+
For additional information, please refer to the [documentation](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-lifecycle-settings.html).
595+
596+
```typescript fixture=default
597+
const repository = new ecr.Repository(this, "TestRepository", {
598+
repositoryName: "test-agent-runtime",
599+
});
600+
601+
const agentRuntimeArtifact = agentcore.AgentRuntimeArtifact.fromEcrRepository(repository, "v1.0.0");
602+
603+
new agentcore.Runtime(this, 'test-runtime', {
604+
runtimeName: 'test_runtime',
605+
agentRuntimeArtifact: agentRuntimeArtifact,
606+
lifecycleConfiguration: {
607+
idleRuntimeSessionTimeout: Duration.minutes(10),
608+
maxLifetime: Duration.hours(4),
609+
},
610+
});
611+
```
612+
613+
#### Request header configuration
614+
615+
Custom headers let you pass contextual information from your application directly to your agent code without cluttering the main request payload. This includes authentication tokens like JWT (JSON Web Tokens, which contain user identity and authorization claims) through the Authorization header, allowing your agent to make decisions based on who is calling it. You can also pass custom metadata like user preferences, session identifiers, or trace context using headers prefixed with X-Amzn-Bedrock-AgentCore-Runtime-Custom-, giving your agent access to up to 20 pieces of runtime context that travel alongside each request. This information can be also used in downstream systems like AgentCore Memory that you can namespace based on those characteristics like user_id or aud in claims like line of business.
616+
617+
For additional information, please refer to the [documentation](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-header-allowlist.html).
618+
619+
```typescript fixture=default
620+
const repository = new ecr.Repository(this, "TestRepository", {
621+
repositoryName: "test-agent-runtime",
622+
});
623+
624+
const agentRuntimeArtifact = agentcore.AgentRuntimeArtifact.fromEcrRepository(repository, "v1.0.0");
625+
626+
new agentcore.Runtime(this, 'test-runtime', {
627+
runtimeName: 'test_runtime',
628+
agentRuntimeArtifact: agentRuntimeArtifact,
629+
requestHeaderConfiguration: {
630+
allowlistedHeaders: ['X-Amzn-Bedrock-AgentCore-Runtime-Custom-H1'],
631+
},
632+
});
633+
```
634+
547635
## Browser
548636

549637
The Amazon Bedrock AgentCore Browser provides a secure, cloud-based browser that enables AI agents to interact with websites. It includes security features such as session isolation, built-in observability through live viewing, CloudTrail logging, and session replay capabilities.
@@ -583,6 +671,7 @@ For more information on VPC connectivity for Amazon Bedrock AgentCore Browser, p
583671
| `recordingConfig` | `RecordingConfig` | No | Recording configuration for browser. Defaults to no recording |
584672
| `executionRole` | `iam.IRole` | No | The IAM role that provides permissions for the browser to access AWS services. A new role will be created if not provided |
585673
| `tags` | `{ [key: string]: string }` | No | Tags to apply to the browser resource |
674+
| `browserSigning` | BrowserSigning | No | Browser signing configuration. Defaults to DISABLED |
586675

587676
### Basic Browser Creation
588677

@@ -709,6 +798,21 @@ const browser = new agentcore.BrowserCustom(this, "MyBrowser", {
709798
// when recording is enabled, so no additional IAM configuration is needed
710799
```
711800

801+
### Browser with Browser signing
802+
803+
AI agents need to browse the web on your behalf. When your agent visits a website to gather information, complete a form, or verify data, it encounters the same defenses designed to stop unwanted bots: CAPTCHAs, rate limits, and outright blocks.
804+
805+
Amazon Bedrock AgentCore Browser supports Web Bot Auth. Web Bot Auth is a draft IETF protocol that gives agents verifiable cryptographic identities. When you enable Web Bot Auth in AgentCore Browser, the service issues cryptographic credentials that websites can verify. The agent presents these credentials with every request. The WAF may now additionally check the signature, confirm it matches a trusted directory, and allow the request through if verified bots are allowed by the domain owner and other WAF checks are clear.
806+
807+
To enable the browser to sign requests using the Web Bot Auth protocol, create a browser tool with the browserSigning configuration:
808+
809+
```typescript fixture=default
810+
const browser = new agentcore.BrowserCustom(this, 'test-browser', {
811+
browserCustomName: 'test_browser',
812+
browserSigning: agentcore.BrowserSigning.ENABLED
813+
});
814+
```
815+
712816
### Browser IAM Permissions
713817

714818
The Browser construct provides convenient methods for granting IAM permissions:

packages/@aws-cdk/aws-bedrock-agentcore-alpha/agentcore/runtime/runtime-artifact.ts

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,32 @@ import { md5hash } from 'aws-cdk-lib/core/lib/helpers-internal';
1818
import { Construct } from 'constructs';
1919
import { Runtime } from './runtime';
2020
import { ValidationError } from './validation-helpers';
21+
import { Location } from 'aws-cdk-lib/aws-s3';
22+
import { Stack, Token } from 'aws-cdk-lib';
23+
import * as s3 from 'aws-cdk-lib/aws-s3';
24+
25+
/**
26+
* Bedrock AgentCore runtime environment for code execution
27+
* Allowed values: PYTHON_3_10 | PYTHON_3_11 | PYTHON_3_12 | PYTHON_3_13
28+
*/
29+
export enum AgentCoreRuntime {
30+
/**
31+
* Python 3.10 runtime
32+
*/
33+
PYTHON_3_10 = 'PYTHON_3_10',
34+
/**
35+
* Python 3.11 runtime
36+
*/
37+
PYTHON_3_11 = 'PYTHON_3_11',
38+
/**
39+
* Python 3.12 runtime
40+
*/
41+
PYTHON_3_12 = 'PYTHON_3_12',
42+
/**
43+
* Python 3.13 runtime
44+
*/
45+
PYTHON_3_13 = 'PYTHON_3_13',
46+
}
2147

2248
/**
2349
* Abstract base class for agent runtime artifacts.
@@ -40,6 +66,16 @@ export abstract class AgentRuntimeArtifact {
4066
return new AssetImage(directory, options);
4167
}
4268

69+
/**
70+
* Reference an agent runtime artifact that's constructed directly from an S3 object
71+
* @param s3Location The source code location and configuration details.
72+
* @param runtime The runtime environment for executing the code. Allowed values: PYTHON_3_10 | PYTHON_3_11 | PYTHON_3_12 | PYTHON_3_13
73+
* @param entrypoint The entry point for the code execution, specifying the function or method that should be invoked when the code runs.
74+
*/
75+
public static fromS3(s3Location: Location, runtime: AgentCoreRuntime, entrypoint: string[]): AgentRuntimeArtifact {
76+
return new S3Image(s3Location, runtime, entrypoint);
77+
}
78+
4379
/**
4480
* Called when the image is used by a Runtime to handle side effects like permissions
4581
*/
@@ -113,3 +149,45 @@ class AssetImage extends AgentRuntimeArtifact {
113149
} as any;
114150
}
115151
}
152+
153+
class S3Image extends AgentRuntimeArtifact {
154+
private bound = false;
155+
156+
constructor(private readonly s3Location: Location, private readonly runtime: AgentCoreRuntime, private readonly entrypoint: string[]) {
157+
super();
158+
}
159+
160+
public bind(scope: Construct, runtime: Runtime): void {
161+
// Handle permissions (only once)
162+
if (!this.bound && runtime.role) {
163+
if (!Token.isUnresolved(this.s3Location.bucketName)) {
164+
Stack.of(scope).resolve(this.s3Location.bucketName);
165+
}
166+
const bucket = s3.Bucket.fromBucketName(
167+
scope,
168+
`${this.s3Location.bucketName}CodeArchive`,
169+
this.s3Location.bucketName,
170+
);
171+
// Ensure the policy is applied before the browser resource is created
172+
bucket.grantRead(runtime.role);
173+
this.bound = true;
174+
}
175+
}
176+
177+
public _render(): CfnRuntime.AgentRuntimeArtifactProperty {
178+
const s3Config: any = {
179+
bucket: this.s3Location.bucketName,
180+
prefix: this.s3Location.objectKey,
181+
};
182+
if (this.s3Location.objectVersion) {
183+
s3Config.versionId = this.s3Location.objectVersion;
184+
}
185+
return {
186+
code: {
187+
s3: s3Config,
188+
},
189+
runtime: this.runtime,
190+
entryPoint: this.entrypoint,
191+
} as any;
192+
}
193+
}

0 commit comments

Comments
 (0)