bedrock-agentcore-starter-toolkit 0.1.24__py3-none-any.whl → 0.1.26__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,6 +4,7 @@ import json
4
4
  import logging
5
5
  import os
6
6
  from pathlib import Path
7
+ from threading import Thread
7
8
  from typing import List, Optional
8
9
 
9
10
  import typer
@@ -12,6 +13,7 @@ from prompt_toolkit.completion import PathCompleter
12
13
  from rich.panel import Panel
13
14
  from rich.syntax import Syntax
14
15
 
16
+ from ...operations.identity.oauth2_callback_server import start_oauth2_callback_server
15
17
  from ...operations.runtime import (
16
18
  configure_bedrock_agentcore,
17
19
  destroy_bedrock_agentcore,
@@ -575,12 +577,23 @@ def launch(
575
577
  _print_success(f"Docker image built: {result.tag}")
576
578
  _print_success("Ready to run locally")
577
579
  console.print("Starting server at http://localhost:8080")
580
+ console.print("Starting OAuth2 3LO callback server at http://localhost:8081")
578
581
  console.print("[yellow]Press Ctrl+C to stop[/yellow]\n")
579
582
 
580
583
  if result.runtime is None or result.port is None:
581
584
  _handle_error("Unable to launch locally")
582
585
 
583
586
  try:
587
+ oauth2_callback_endpoint = Thread(
588
+ target=start_oauth2_callback_server,
589
+ args=(
590
+ config_path,
591
+ agent,
592
+ ),
593
+ name="OAuth2 3LO Callback Server",
594
+ daemon=True,
595
+ )
596
+ oauth2_callback_endpoint.start()
584
597
  result.runtime.run_local(result.tag, result.port, result.env_vars)
585
598
  except KeyboardInterrupt:
586
599
  console.print("\n[yellow]Stopped[/yellow]")
@@ -0,0 +1,5 @@
1
+ """Bedrock AgentCore Identity operations."""
2
+
3
+ from .oauth2_callback_server import WORKLOAD_USER_ID, start_oauth2_callback_server
4
+
5
+ __all__ = ["start_oauth2_callback_server", "WORKLOAD_USER_ID"]
@@ -0,0 +1,86 @@
1
+ """Provides a Starlette-based web server that handles OAuth2 3LO callbacks."""
2
+
3
+ from pathlib import Path
4
+
5
+ import uvicorn
6
+ from bedrock_agentcore.services.identity import IdentityClient, UserIdIdentifier
7
+ from starlette.applications import Starlette
8
+ from starlette.requests import Request
9
+ from starlette.responses import JSONResponse
10
+ from starlette.routing import Route
11
+
12
+ from ...cli.common import console
13
+ from ...utils.runtime.config import BedrockAgentCoreAgentSchema, load_config
14
+
15
+ OAUTH2_CALLBACK_SERVER_PORT = 8081
16
+ OAUTH2_CALLBACK_ENDPOINT = "/oauth2/callback"
17
+ WORKLOAD_USER_ID = "userId"
18
+
19
+
20
+ def start_oauth2_callback_server(config_path: Path, agent_name: str, debug: bool = False):
21
+ """Starts a server to complete the OAuth2 3LO flow with AgentCore Identity."""
22
+ callback_server = BedrockAgentCoreIdentity3loCallback(config_path=config_path, agent_name=agent_name, debug=debug)
23
+ callback_server.run()
24
+
25
+
26
+ class BedrockAgentCoreIdentity3loCallback(Starlette):
27
+ """Bedrock AgentCore application class that extends Starlette for OAuth2 3LO callback flow."""
28
+
29
+ def __init__(self, config_path: Path, agent_name: str, debug: bool = False):
30
+ """Initialize Bedrock AgentCore Identity callback server."""
31
+ self.config_path = config_path
32
+ self.agent_name = agent_name
33
+ routes = [
34
+ Route(OAUTH2_CALLBACK_ENDPOINT, self._handle_3lo_callback, methods=["GET"]),
35
+ ]
36
+ super().__init__(routes=routes, debug=debug)
37
+
38
+ def run(self, **kwargs):
39
+ """Start the Bedrock AgentCore Identity OAuth2 callback server."""
40
+ uvicorn_params = {
41
+ "host": "127.0.0.1",
42
+ "port": OAUTH2_CALLBACK_SERVER_PORT,
43
+ "access_log": self.debug,
44
+ "log_level": "info" if self.debug else "warning",
45
+ }
46
+ uvicorn_params.update(kwargs)
47
+
48
+ uvicorn.run(self, **uvicorn_params)
49
+
50
+ def _handle_3lo_callback(self, request: Request) -> JSONResponse:
51
+ """Handle OAuth2 3LO callbacks with AgentCore Identity."""
52
+ session_id = request.query_params.get("session_id")
53
+ if not session_id:
54
+ console.print("Missing session_id in OAuth2 3LO callback")
55
+ return JSONResponse(status_code=400, content={"message": "missing session_id query parameter"})
56
+
57
+ project_config = load_config(self.config_path)
58
+ agent_config: BedrockAgentCoreAgentSchema = project_config.get_agent_config(self.agent_name)
59
+ oauth2_config = agent_config.oauth_configuration
60
+
61
+ user_id = None
62
+ if oauth2_config:
63
+ user_id = oauth2_config.get(WORKLOAD_USER_ID)
64
+
65
+ if not user_id:
66
+ console.print(f"Missing {WORKLOAD_USER_ID} in Agent OAuth2 Config")
67
+ return JSONResponse(status_code=500, content={"message": "Internal Server Error"})
68
+
69
+ console.print(f"Handling 3LO callback for workload_user_id={user_id} | session_id={session_id}", soft_wrap=True)
70
+
71
+ region = agent_config.aws.region
72
+ if not region:
73
+ console.print("AWS Region not configured")
74
+ return JSONResponse(status_code=500, content={"message": "Internal Server Error"})
75
+
76
+ identity_client = IdentityClient(region)
77
+ identity_client.complete_resource_token_auth(
78
+ session_uri=session_id, user_identifier=UserIdIdentifier(user_id=user_id)
79
+ )
80
+
81
+ return JSONResponse(status_code=200, content={"message": "OAuth2 3LO flow completed successfully"})
82
+
83
+ @classmethod
84
+ def get_oauth2_callback_endpoint(cls) -> str:
85
+ """Returns the url for the local OAuth2 callback server."""
86
+ return f"http://localhost:{OAUTH2_CALLBACK_SERVER_PORT}{OAUTH2_CALLBACK_ENDPOINT}"
@@ -7,6 +7,7 @@ from typing import Any, Optional
7
7
 
8
8
  from bedrock_agentcore.services.identity import IdentityClient
9
9
 
10
+ from ...operations.identity.oauth2_callback_server import WORKLOAD_USER_ID, BedrockAgentCoreIdentity3loCallback
10
11
  from ...services.runtime import BedrockAgentCoreClient, generate_session_id
11
12
  from ...utils.runtime.config import load_config, save_config
12
13
  from ...utils.runtime.schema import BedrockAgentCoreConfigSchema
@@ -121,9 +122,19 @@ def invoke_bedrock_agentcore(
121
122
  workload_name=workload_name, user_token=bearer_token, user_id=user_id
122
123
  )["workloadAccessToken"]
123
124
 
125
+ agent_config.oauth_configuration[WORKLOAD_USER_ID] = user_id # type: ignore : populated by _get_workload_name(...)
126
+ save_config(project_config, config_path)
127
+
128
+ oauth2_callback_url = BedrockAgentCoreIdentity3loCallback.get_oauth2_callback_endpoint()
129
+ _update_workload_identity_with_oauth2_callback_url(
130
+ identity_client, workload_name=workload_name, oauth2_callback_url=oauth2_callback_url
131
+ )
132
+
124
133
  # TODO: store and read port config of local running container
125
134
  client = LocalBedrockAgentCoreClient("http://127.0.0.1:8080")
126
- response = client.invoke_endpoint(session_id, payload_str, workload_access_token, custom_headers)
135
+ response = client.invoke_endpoint(
136
+ session_id, payload_str, workload_access_token, oauth2_callback_url, custom_headers
137
+ )
127
138
 
128
139
  else:
129
140
  if not agent_arn:
@@ -163,6 +174,24 @@ def invoke_bedrock_agentcore(
163
174
  )
164
175
 
165
176
 
177
+ def _update_workload_identity_with_oauth2_callback_url(
178
+ identity_client: IdentityClient,
179
+ workload_name: str,
180
+ oauth2_callback_url: str,
181
+ ) -> None:
182
+ workload_identity = identity_client.get_workload_identity(name=workload_name)
183
+ allowed_resource_oauth_2_return_urls = workload_identity.get("allowedResourceOauth2ReturnUrls") or []
184
+ if oauth2_callback_url in allowed_resource_oauth_2_return_urls:
185
+ return
186
+
187
+ log.info("Updating workload %s with callback url %s", workload_name, oauth2_callback_url)
188
+
189
+ identity_client.update_workload_identity(
190
+ name=workload_name,
191
+ allowed_resource_oauth_2_return_urls=[*allowed_resource_oauth_2_return_urls, oauth2_callback_url],
192
+ )
193
+
194
+
166
195
  def _get_workload_name(
167
196
  project_config: BedrockAgentCoreConfigSchema,
168
197
  project_config_path: Path,
@@ -576,10 +576,11 @@ class LocalBedrockAgentCoreClient:
576
576
  session_id: str,
577
577
  payload: str,
578
578
  workload_access_token: str,
579
+ oauth2_callback_url: str,
579
580
  custom_headers: Optional[dict] = None,
580
581
  ):
581
582
  """Invoke the endpoint with the given parameters."""
582
- from bedrock_agentcore.runtime.models import ACCESS_TOKEN_HEADER, SESSION_HEADER
583
+ from bedrock_agentcore.runtime.models import ACCESS_TOKEN_HEADER, OAUTH2_CALLBACK_URL_HEADER, SESSION_HEADER
583
584
 
584
585
  url = f"{self.endpoint}/invocations"
585
586
 
@@ -587,6 +588,7 @@ class LocalBedrockAgentCoreClient:
587
588
  "Content-Type": "application/json",
588
589
  ACCESS_TOKEN_HEADER: workload_access_token,
589
590
  SESSION_HEADER: session_id,
591
+ OAUTH2_CALLBACK_URL_HEADER: oauth2_callback_url,
590
592
  }
591
593
 
592
594
  # Merge custom headers if provided
@@ -73,7 +73,8 @@
73
73
  "Sid": "BedrockAgentCoreRuntime",
74
74
  "Effect": "Allow",
75
75
  "Action": [
76
- "bedrock-agentcore:InvokeAgentRuntime"
76
+ "bedrock-agentcore:InvokeAgentRuntime",
77
+ "bedrock-agentcore:InvokeAgentRuntimeForUser"
77
78
  ],
78
79
  "Resource": [
79
80
  "arn:aws:bedrock-agentcore:{{ region }}:{{ account_id }}:runtime/*"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bedrock-agentcore-starter-toolkit
3
- Version: 0.1.24
3
+ Version: 0.1.26
4
4
  Summary: A starter toolkit for using Bedrock AgentCore
5
5
  Project-URL: Homepage, https://github.com/aws/bedrock-agentcore-starter-toolkit
6
6
  Project-URL: Bug Tracker, https://github.com/aws/bedrock-agentcore-starter-toolkit/issues
@@ -22,9 +22,9 @@ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
22
22
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
23
  Requires-Python: >=3.10
24
24
  Requires-Dist: autopep8>=2.3.2
25
- Requires-Dist: bedrock-agentcore>=0.1.7
26
- Requires-Dist: boto3>=1.40.35
27
- Requires-Dist: botocore>=1.40.35
25
+ Requires-Dist: bedrock-agentcore>=1.0.3
26
+ Requires-Dist: boto3>=1.40.51
27
+ Requires-Dist: botocore>=1.40.51
28
28
  Requires-Dist: docstring-parser<1.0,>=0.15
29
29
  Requires-Dist: httpx>=0.28.1
30
30
  Requires-Dist: jinja2>=3.1.6
@@ -32,12 +32,13 @@ Requires-Dist: openapi-spec-validator>=0.7.2
32
32
  Requires-Dist: prance>=25.4.8.0
33
33
  Requires-Dist: prompt-toolkit>=3.0.51
34
34
  Requires-Dist: py-openapi-schema-to-json-schema>=0.0.3
35
- Requires-Dist: pydantic<3.0.0,>=2.0.0
35
+ Requires-Dist: pydantic<2.41.3,>=2.0.0
36
36
  Requires-Dist: pyyaml>=6.0.2
37
37
  Requires-Dist: questionary>=2.1.0
38
38
  Requires-Dist: requests>=2.25.0
39
39
  Requires-Dist: rich>=13.0.0
40
40
  Requires-Dist: ruamel-yaml>=0.18.14
41
+ Requires-Dist: starlette>=0.46.2
41
42
  Requires-Dist: toml>=0.10.2
42
43
  Requires-Dist: typer>=0.16.0
43
44
  Requires-Dist: typing-extensions<5.0.0,>=4.13.2
@@ -121,10 +122,6 @@ AgentCore Import-Agent enables seamless migration of existing Amazon Bedrock Age
121
122
  **[Import Agent Quick Start](https://aws.github.io/bedrock-agentcore-starter-toolkit/user-guide/import-agent/quickstart.html)**
122
123
 
123
124
 
124
- ## ⚠️ Preview Status
125
-
126
- Bedrock AgentCore is currently in public preview.
127
-
128
125
  ## Installation
129
126
 
130
127
  ### Quick Start
@@ -9,7 +9,7 @@ bedrock_agentcore_starter_toolkit/cli/import_agent/__init__.py,sha256=tyM3dXM3Tc
9
9
  bedrock_agentcore_starter_toolkit/cli/import_agent/agent_info.py,sha256=CcPXbKNnI9fc7NyFmZBjB3PkB0wAz2Q_kBGoUVcnngA,9736
10
10
  bedrock_agentcore_starter_toolkit/cli/import_agent/commands.py,sha256=vpA66fGwKf6cxBelT3Yb_Af5Ow3AMquGLIDe-tBLjmc,22419
11
11
  bedrock_agentcore_starter_toolkit/cli/runtime/__init__.py,sha256=0zKPPoYThoDIr3DZhIQJavq5nVTKRsgcE1s9--wx118,60
12
- bedrock_agentcore_starter_toolkit/cli/runtime/commands.py,sha256=NntVm0PQshWxrB-AJ-pQVo8UAIgxOt5Y3I_DfF4bOlM,55971
12
+ bedrock_agentcore_starter_toolkit/cli/runtime/commands.py,sha256=CLRynotRlQST9gsbbmDg4_Y7JXTZFt_G-sh11OgH7O4,56558
13
13
  bedrock_agentcore_starter_toolkit/cli/runtime/configuration_manager.py,sha256=aRHo8tWrx4IBJPfRMQxUe3eZsoOQn1qUYJ_ZI6MAPSo,15832
14
14
  bedrock_agentcore_starter_toolkit/notebook/__init__.py,sha256=wH1ZzIVKsKT_P0qX2kIIoyVxeHj8K40odfR1YI3McHw,129
15
15
  bedrock_agentcore_starter_toolkit/notebook/runtime/__init__.py,sha256=DoGfB_uGFLANJVE9rSZtTH3ymw76WBWmD9vORvBIdXs,66
@@ -21,6 +21,8 @@ bedrock_agentcore_starter_toolkit/operations/gateway/constants.py,sha256=0_4J6BN
21
21
  bedrock_agentcore_starter_toolkit/operations/gateway/create_lambda.py,sha256=mAzXvi5hetzN2iv0ITfx6PDbOgeLOjqt71zzaDpKHnw,2876
22
22
  bedrock_agentcore_starter_toolkit/operations/gateway/create_role.py,sha256=Oma9s6K4T9EFgwPAUDungDL9fGa3W0LsHBknIXUmSpI,4474
23
23
  bedrock_agentcore_starter_toolkit/operations/gateway/exceptions.py,sha256=WjsrE7lT2708CJniM_ISMzkfNX4IUteGgvOxleD9JZY,272
24
+ bedrock_agentcore_starter_toolkit/operations/identity/__init__.py,sha256=8gMJRmRmHy1_MJs4oJnM3RlkMgfx204EcvyIxRoP3oQ,193
25
+ bedrock_agentcore_starter_toolkit/operations/identity/oauth2_callback_server.py,sha256=2FlCvjxbNOP6d0ciRZ7QIXHmyJIEIN8FSSGBONEYaZc,3669
24
26
  bedrock_agentcore_starter_toolkit/operations/memory/README.md,sha256=VHmdCoZImRVsiDvCnKbnt4btO5fOkfeKmoludgSbKwM,31139
25
27
  bedrock_agentcore_starter_toolkit/operations/memory/__init__.py,sha256=PAj25QAlnlvjaQIgfIpfxXXVXu5BTOXy-xDMDh6_HIc,59
26
28
  bedrock_agentcore_starter_toolkit/operations/memory/constants.py,sha256=0HWpxJZXmnmekIEW5TJjn9KmEqVi_REJzUN1l68ohYQ,3226
@@ -42,14 +44,14 @@ bedrock_agentcore_starter_toolkit/operations/runtime/configure.py,sha256=b226Wg2
42
44
  bedrock_agentcore_starter_toolkit/operations/runtime/create_role.py,sha256=1-b_wBvkOXNh-HJsxATwHfXQqj0dpdETds0FNSTY0BE,16116
43
45
  bedrock_agentcore_starter_toolkit/operations/runtime/destroy.py,sha256=iyAH1-D734cmiluASGMcp3wwXZ10IlhKi-acsGEQ8Yk,26204
44
46
  bedrock_agentcore_starter_toolkit/operations/runtime/exceptions.py,sha256=7iZNVbsz5XyvnpMM4paJb5_LT6DYdEI3nHhM9f3BERE,869
45
- bedrock_agentcore_starter_toolkit/operations/runtime/invoke.py,sha256=ENrJd6DP30DuXe94_kjrMM3njUUbQMsX7O4rM6hFL5g,7162
47
+ bedrock_agentcore_starter_toolkit/operations/runtime/invoke.py,sha256=t8Uv9E9IVWedspQ3ezx0Sz95LfGVweY7diJ315loGlE,8471
46
48
  bedrock_agentcore_starter_toolkit/operations/runtime/launch.py,sha256=oVTLxDdAL2bG-oG4S-KIuUntSODIftit7nGslzjsslg,30100
47
49
  bedrock_agentcore_starter_toolkit/operations/runtime/models.py,sha256=TdUS-O1crCGmigKb_N3WaLBeubsuFiUczyZktzcAHjY,4894
48
50
  bedrock_agentcore_starter_toolkit/operations/runtime/status.py,sha256=yQR0dOjPeA3jyWg9EcezsTi6OVlp_9tbURe3clQNBaY,5340
49
51
  bedrock_agentcore_starter_toolkit/services/__init__.py,sha256=s7QtYYFCCX2ff0gZHUdDxCDI3zhUq0fPsjevZbF9xdA,66
50
52
  bedrock_agentcore_starter_toolkit/services/codebuild.py,sha256=CA4OgkMiZPbV6KBFswBLlSuaWgcH1wnTmRnvSEmHxpc,15925
51
53
  bedrock_agentcore_starter_toolkit/services/ecr.py,sha256=a9VpxIzYohPvAiAsl9jPp5vZcalCxt9LpqW4S7CdFPo,3991
52
- bedrock_agentcore_starter_toolkit/services/runtime.py,sha256=lqBB-4uJuxNKbnPHpRskQ7bajiZ2MpjnbqPnKnvTinY,22408
54
+ bedrock_agentcore_starter_toolkit/services/runtime.py,sha256=Ec7l7hj4gRxzSfVJJ2rOwUr3IvuMyDU-u81ueJqF-kI,22531
53
55
  bedrock_agentcore_starter_toolkit/services/xray.py,sha256=CRlcfVXpghVy7PvZqLUC4rp49Sw5DQ98rUU61HAluRM,6363
54
56
  bedrock_agentcore_starter_toolkit/services/import_agent/__init__.py,sha256=ig-xanZqA3oJdRTucYz9xF9_2yi31ADRVIKFsnIw_l4,68
55
57
  bedrock_agentcore_starter_toolkit/services/import_agent/utils.py,sha256=yCnzqv3S8sbQi6ArTz3MeR4ggRcojbAgMbBb7KAf0sA,16077
@@ -71,11 +73,11 @@ bedrock_agentcore_starter_toolkit/utils/runtime/policy_template.py,sha256=CgER7Y
71
73
  bedrock_agentcore_starter_toolkit/utils/runtime/schema.py,sha256=wkEckV7Fo64i1tFY60n8L6HE6gjJmfNl1gB5BkVyRRg,9724
72
74
  bedrock_agentcore_starter_toolkit/utils/runtime/templates/Dockerfile.j2,sha256=7vu1Mbo5m1M7gE0SQZ6iFkZppTho8w4BoOe0yYyJjug,1487
73
75
  bedrock_agentcore_starter_toolkit/utils/runtime/templates/dockerignore.template,sha256=IDKPnAiCdMLjuvLdItzQiybCW--SEvHAN2yr-B5Mxj4,711
74
- bedrock_agentcore_starter_toolkit/utils/runtime/templates/execution_role_policy.json.j2,sha256=YZua4Zx3huYqNrROpGVeHOs52Tci3RiNOBCLPmbgQgU,5612
76
+ bedrock_agentcore_starter_toolkit/utils/runtime/templates/execution_role_policy.json.j2,sha256=BnVE3ofq2PCrl56VFjilG1RkJEiZ2L3MM2wFok7XTaU,5667
75
77
  bedrock_agentcore_starter_toolkit/utils/runtime/templates/execution_role_trust_policy.json.j2,sha256=PPJF6Ofq70W5DUE0NlbmnZjw5RkgepPgkskxEgEG28o,473
76
- bedrock_agentcore_starter_toolkit-0.1.24.dist-info/METADATA,sha256=BmOStUgmXEeqUgt_6ZgtVaI7KxSiFQNPd96WVFJYhK4,9999
77
- bedrock_agentcore_starter_toolkit-0.1.24.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
78
- bedrock_agentcore_starter_toolkit-0.1.24.dist-info/entry_points.txt,sha256=Tf94DkUf2Tp8P7p8MEXLxre7A7Pp_XNukteiz0wHnk8,77
79
- bedrock_agentcore_starter_toolkit-0.1.24.dist-info/licenses/LICENSE.txt,sha256=nNPOMinitYdtfbhdQgsPgz1UowBznU6QVN3Xs0pSTKU,10768
80
- bedrock_agentcore_starter_toolkit-0.1.24.dist-info/licenses/NOTICE.txt,sha256=rkBsg8DbKqfIoQbveqX9foR4uJPUVAokbkr02pRPilE,8674
81
- bedrock_agentcore_starter_toolkit-0.1.24.dist-info/RECORD,,
78
+ bedrock_agentcore_starter_toolkit-0.1.26.dist-info/METADATA,sha256=RtwR5mxnOFEtLJdPIExD1aoVhudoFvyxwawep7lgPDw,9956
79
+ bedrock_agentcore_starter_toolkit-0.1.26.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
80
+ bedrock_agentcore_starter_toolkit-0.1.26.dist-info/entry_points.txt,sha256=Tf94DkUf2Tp8P7p8MEXLxre7A7Pp_XNukteiz0wHnk8,77
81
+ bedrock_agentcore_starter_toolkit-0.1.26.dist-info/licenses/LICENSE.txt,sha256=nNPOMinitYdtfbhdQgsPgz1UowBznU6QVN3Xs0pSTKU,10768
82
+ bedrock_agentcore_starter_toolkit-0.1.26.dist-info/licenses/NOTICE.txt,sha256=rkBsg8DbKqfIoQbveqX9foR4uJPUVAokbkr02pRPilE,8674
83
+ bedrock_agentcore_starter_toolkit-0.1.26.dist-info/RECORD,,