Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
136 commits
Select commit Hold shift + click to select a range
df235a0
Fix wording typo in notebook about user consent flow
HardikThakkar94 Sep 4, 2025
e15dcf1
Add pyyaml to requirements.txt
HardikThakkar94 Sep 4, 2025
9db61a1
Add HardikThakkar94 to CONTRIBUTORS.md
HardikThakkar94 Sep 4, 2025
b3c4bee
Merge branch 'awslabs:main' into main
HardikThakkar94 Sep 8, 2025
e01623f
Merge branch 'awslabs:main' into main
HardikThakkar94 Sep 10, 2025
069804d
Updates to fix the Streamlit app access when running in sagemaker
HardikThakkar94 Sep 10, 2025
8d3b6ff
Merge branch 'awslabs:main' into main
HardikThakkar94 Sep 10, 2025
4976191
Merge branch 'awslabs:main' into main
HardikThakkar94 Sep 17, 2025
03cbebd
Merge branch 'awslabs:main' into main
HardikThakkar94 Sep 19, 2025
17a040a
Fixing Ruff errors reported by python-lint
Sep 19, 2025
5696f31
removing Ruff errors from python-lint
Sep 19, 2025
0621e91
Merge branch 'awslabs:main' into main
HardikThakkar94 Sep 19, 2025
2934c6e
passing 3.7 as the model for workshop
HardikThakkar94 Sep 19, 2025
ced9f8a
Merge branch 'awslabs:main' into main
HardikThakkar94 Sep 20, 2025
8aec5f9
Merge branch 'awslabs:main' into main
HardikThakkar94 Sep 26, 2025
5dded4c
Docs: add prerequisites (OpenAI or Azure OpenAI) cell to Outbound Aut…
HardikThakkar94 Sep 26, 2025
fbbe368
Revert "Docs: add prerequisites (OpenAI or Azure OpenAI) cell to Outb…
HardikThakkar94 Sep 26, 2025
e221e98
Add prerequisites (OpenAI or Azure OpenAI) cell to Outbound Auth note…
HardikThakkar94 Sep 26, 2025
6569939
cosmetic fix
HardikThakkar94 Sep 26, 2025
f599a96
Updating OpenAI URL
HardikThakkar94 Sep 26, 2025
2a1c202
Merge branch 'awslabs:main' into main
HardikThakkar94 Oct 17, 2025
330c4a7
Merge branch 'awslabs:main' into main
HardikThakkar94 Oct 28, 2025
fdf675e
Merge branch 'awslabs:main' into main
HardikThakkar94 Oct 28, 2025
adda909
Merge branch 'awslabs:main' into main
HardikThakkar94 Oct 31, 2025
ef410f7
Added instructions on the OAuth flow session binding and Streamlit fu…
HardikThakkar94 Oct 31, 2025
bea2f07
All imports are now properly organized at the top of the file, follow…
HardikThakkar94 Oct 31, 2025
54c3dd5
formatting fixed
HardikThakkar94 Oct 31, 2025
c7bf441
Merge branch 'awslabs:main' into main
HardikThakkar94 Nov 3, 2025
6d0bb24
Update Identity Outbound tutorial notebooks with corrections and impr…
HardikThakkar94 Nov 3, 2025
b25b5c3
Merge branch 'awslabs:main' into main
HardikThakkar94 Nov 4, 2025
c0a3357
Merge branch 'awslabs:main' into main
HardikThakkar94 Nov 5, 2025
439e6d4
Fixed Identity Sections based on SageMaker (Workshop) to handle oauth…
HardikThakkar94 Nov 5, 2025
ddebaa4
Remove unused import and added permissions for 1st time model access …
HardikThakkar94 Nov 6, 2025
b258bb0
formatting fixed.
HardikThakkar94 Nov 6, 2025
5a396ce
Merge branch 'awslabs:main' into main
HardikThakkar94 Nov 7, 2025
2ce727f
parameterize provider, update github image.
HardikThakkar94 Nov 7, 2025
c7ac6eb
Merge branch 'awslabs:main' into main
HardikThakkar94 Nov 12, 2025
ebaca12
Merge branch 'awslabs:main' into main
HardikThakkar94 Nov 12, 2025
b679188
added import boto3 and updated image for GitHub Session Binding
HardikThakkar94 Nov 12, 2025
7066596
Merge branch 'awslabs:main' into main
HardikThakkar94 Nov 18, 2025
108b149
Merge branch 'awslabs:main' into main
HardikThakkar94 Nov 19, 2025
9d99c41
Update Model and Remove Global Var
HardikThakkar94 Nov 19, 2025
33792e4
Merge branch 'awslabs:main' into main
HardikThakkar94 Dec 11, 2025
4a10e93
Merge branch 'awslabs:main' into main
HardikThakkar94 Dec 18, 2025
748de4a
Travel and Shopping concierge agents blueprints
HardikThakkar94 Dec 19, 2025
d25a54e
add missing contributors for the blueprint
HardikThakkar94 Dec 19, 2025
71eca16
fix python-lint errors
HardikThakkar94 Dec 19, 2025
9a2096c
CodeQL fixes and config
HardikThakkar94 Dec 19, 2025
f60c5eb
fix python-lint unused imports
HardikThakkar94 Dec 19, 2025
7579947
fix python-lint
HardikThakkar94 Dec 19, 2025
f238d5f
fix linter and cql issues
HardikThakkar94 Dec 19, 2025
bd527ba
run linter
HardikThakkar94 Dec 19, 2025
f6157cb
update codeql suppressions
HardikThakkar94 Dec 19, 2025
092ac27
suppress codeql
HardikThakkar94 Dec 19, 2025
69bbe77
Revert accidental changes to 01-tutorials and 03-integrations
HardikThakkar94 Dec 19, 2025
0707b80
fix formatting
HardikThakkar94 Dec 19, 2025
a034f8e
Update 05-blueprints/shopping-concierge-agent/tests/utils.py
HardikThakkar94 Dec 20, 2025
6ee15ed
removed tests folders.
HardikThakkar94 Dec 20, 2025
ea17b29
remove info logging
HardikThakkar94 Dec 20, 2025
005db9c
remove logging
HardikThakkar94 Dec 20, 2025
561418c
codeql suppressions
HardikThakkar94 Dec 20, 2025
a06e557
Update server.py
HardikThakkar94 Dec 20, 2025
8c0a08d
Updating .gitignore and adding lib folder required for the shopping a…
HardikThakkar94 Dec 22, 2025
82ff34d
Merge branch 'awslabs:main' into main
HardikThakkar94 Dec 22, 2025
b2b1a68
Merge branch 'awslabs:main' into main
HardikThakkar94 Dec 22, 2025
fb29cd8
Add Demo video for agents
HardikThakkar94 Dec 22, 2025
078add9
Update demo section in README.md
HardikThakkar94 Dec 22, 2025
068a311
Add Demo's as Gif, update LFS and add note in ReadMe
HardikThakkar94 Dec 22, 2025
d75c996
remove the .mp4 files as they are not supported
HardikThakkar94 Dec 22, 2025
f008dfb
Merge branch 'awslabs:main' into main
HardikThakkar94 Jan 6, 2026
a07d910
change to google products and remove travel specific
Jan 6, 2026
e5bb1e5
update product link
HardikThakkar94 Jan 6, 2026
e8fb478
fix url in shopping list and purchases
HardikThakkar94 Jan 6, 2026
897ee03
remove amazon
HardikThakkar94 Jan 6, 2026
7e1b8ad
Merge branch 'awslabs:main' into main
HardikThakkar94 Jan 13, 2026
3a48c45
Merge branch 'awslabs:main' into main
HardikThakkar94 Jan 14, 2026
c87dda4
Add Visa B2B Use Case
HardikThakkar94 Jan 14, 2026
87a74f1
fix pylint
HardikThakkar94 Jan 14, 2026
27e6f5c
CodeQL Fixes
HardikThakkar94 Jan 14, 2026
8a91c9e
Merge remote-tracking branch 'upstream/main'
HardikThakkar94 Jan 22, 2026
4a7eba1
Resolve Conflicts and add missing Lib
HardikThakkar94 Jan 27, 2026
a9c1a96
Merge branch 'awslabs:main' into main
HardikThakkar94 Jan 28, 2026
1200dcd
Merge branch 'awslabs:main' into main
HardikThakkar94 Feb 4, 2026
52bd5dd
Merge branch 'awslabs:main' into main
HardikThakkar94 Feb 6, 2026
af53c6e
Merge branch 'awslabs:main' into main
HardikThakkar94 Feb 11, 2026
f5c7f06
Merge branch 'awslabs:main' into main
HardikThakkar94 Feb 12, 2026
c601bce
Merge branch 'awslabs:main' into main
HardikThakkar94 Feb 16, 2026
3c18e4a
Merge branch 'awslabs:main' into main
HardikThakkar94 Feb 18, 2026
6d24292
Merge branch 'awslabs:main' into main
HardikThakkar94 Feb 26, 2026
87e51f6
Merge branch 'awslabs:main' into main
HardikThakkar94 Mar 3, 2026
e905dc3
Merge branch 'awslabs:main' into main
HardikThakkar94 Mar 16, 2026
09b3145
Consolidating IDP examples under tutorials for better organization
HardikThakkar94 Mar 16, 2026
11b390b
Merge branch 'awslabs:main' into main
HardikThakkar94 Mar 20, 2026
9687152
feat(identity): add runtime inbound and outbound auth sample using AC…
HardikThakkar94 Mar 20, 2026
65e7641
feat(identity): add gateway inbound and outbound auth sample using AC…
HardikThakkar94 Mar 20, 2026
d33c600
feat(identity): add M2M and auth code flows sample using AC CLI
HardikThakkar94 Mar 20, 2026
d64734f
fix(identity): fix invoke bearer token injection and add configure_in…
HardikThakkar94 Mar 20, 2026
30be9cd
Merge branch 'awslabs:main' into main
HardikThakkar94 Mar 24, 2026
2521639
Merge remote-tracking branch 'origin/main' into cli
HardikThakkar94 Mar 24, 2026
fca2780
feat(identity): add CLI-based samples 09-11
HardikThakkar94 Mar 24, 2026
d40661c
fix(identity): fix SDK call in sample 06 notebook
HardikThakkar94 Mar 24, 2026
1cd753a
fix(identity): show 3LO callback URLs always
HardikThakkar94 Mar 24, 2026
cff0fe3
fix(identity): strip markdown from consent URLs
HardikThakkar94 Mar 24, 2026
8e3821a
Merge branch 'awslabs:main' into main
HardikThakkar94 Mar 25, 2026
d45df55
Merge branch 'awslabs:main' into main
HardikThakkar94 Mar 26, 2026
7c8db8b
Merge branch 'awslabs:main' into main
HardikThakkar94 Mar 27, 2026
ce6da3e
Merge branch 'main' into cli
HardikThakkar94 Mar 27, 2026
e83fd53
feat(identity): update for CLI preview.9.0
HardikThakkar94 Mar 27, 2026
7326641
fix(identity): use real APIs in agent code
HardikThakkar94 Mar 27, 2026
0629e15
feat(identity): add Streamlit UIs
HardikThakkar94 Mar 27, 2026
286cebd
Merge branch 'awslabs:main' into main
HardikThakkar94 Mar 30, 2026
790a5ae
fix(identity): update for CLI 0.4.0
HardikThakkar94 Mar 30, 2026
ff1a2ae
fix(identity): add aws-targets.json setup step
HardikThakkar94 Mar 30, 2026
930ba52
fix(identity): use Google Weather API
HardikThakkar94 Mar 30, 2026
860f549
fix(identity): use deployed-state.json
HardikThakkar94 Mar 30, 2026
2d3204c
fix(identity): remove Next Steps sections
HardikThakkar94 Mar 30, 2026
65fc03b
fix(identity): use OpenWeatherMap API
HardikThakkar94 Mar 30, 2026
2d16f50
fix(identity): recursive ARN search
HardikThakkar94 Mar 30, 2026
0dc341b
docs(identity): add Streamlit UI section
HardikThakkar94 Mar 30, 2026
ff02df9
fix(identity): persist bearer token field
HardikThakkar94 Mar 30, 2026
55233a9
fix(identity): simplify gateway target step
HardikThakkar94 Mar 30, 2026
7762108
fix(identity): use OpenWeatherMap for M2M
HardikThakkar94 Mar 30, 2026
e0eb40b
fix(identity): reorder sample 11 steps
HardikThakkar94 Mar 31, 2026
6090316
Merge branch 'awslabs:main' into main
HardikThakkar94 Mar 31, 2026
e3c526c
fix(identity): sample 11 M2M uses real API
HardikThakkar94 Mar 31, 2026
9a786c7
docs(identity): link sample 09 from sample 11
HardikThakkar94 Mar 31, 2026
c32ad35
Merge branch 'awslabs:main' into main
HardikThakkar94 Apr 1, 2026
7a7ae36
docs(identity): add GitHub/Google OAuth setup steps
HardikThakkar94 Apr 1, 2026
fb20e1d
docs(identity): add GitHub OAuth screenshot
HardikThakkar94 Apr 2, 2026
3d91119
Merge branch 'awslabs:main' into main
HardikThakkar94 Apr 7, 2026
ab5bbcc
feat(identity): renumber CLI samples 10-12
HardikThakkar94 Apr 7, 2026
b785bcc
Merge remote-tracking branch 'origin/main' into cli
HardikThakkar94 Apr 7, 2026
14e499b
fix(identity): update README links to 10/11/12
HardikThakkar94 Apr 7, 2026
c0956a2
docs(identity): unified sample table with Method column
HardikThakkar94 Apr 7, 2026
70d77c2
docs(identity): move table after Architecture section
HardikThakkar94 Apr 7, 2026
deb07b3
fix(identity): resolve lint errors in samples 10-12
HardikThakkar94 Apr 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@
"source": [
"print(\"Setting up Amazon Cognito user pool...\")\n",
"cognito_config = setup_cognito_user_pool(\"Cognito_3LO_Github\")\n",
"print(\"Cognito setup completed \")"
"print(\"Cognito setup completed \u2713\")"
]
},
{
Expand Down Expand Up @@ -192,7 +192,7 @@
" - Click **New OAuth App** (or **Register a new application** if you have not created one before).\n",
" - **Fill in required details:**\n",
" - **Application Name**: Name your app.\n",
" - **Homepage URL**: URL for your app’s homepage.<br>\n",
" - **Homepage URL**: URL for your app\u2019s homepage.<br>\n",
" EXAMPLE : https://github.com/awslabs/amazon-bedrock-agentcore-samples/examplehomepage\n",
" - **Application Description** (optional): Add a description for clarity.\n",
" - **Authorization callback URL**: URL where users will be sent after authorization (used for OAuth flow in your application). <br>\n",
Expand All @@ -208,15 +208,15 @@
"\n",
"5. **Retrieve Credentials**\n",
" - Once the application is registered, you will be shown the **Client ID** right on the application summary page.\n",
" - To generate the **Client Secret**, click on the available button or link. The secret will be displayed—copy and save it securely; you’ll use it in your application.\n",
" - To generate the **Client Secret**, click on the available button or link. The secret will be displayed\u2014copy and save it securely; you\u2019ll use it in your application.\n",
" - Note: The client secret is only revealed once or only a few times for security.\n",
"\n",
"***\n",
"\n",
"### Use of Credentials\n",
"\n",
"- You will use the **client_id** and **client_secret** when configuring the Github credential provider.\n",
"- Never expose the client secret publicly or share it with users—treat it like a password.\n",
"- Never expose the client secret publicly or share it with users\u2014treat it like a password.\n",
"\n",
"***\n"
]
Expand All @@ -236,13 +236,13 @@
" <img src=\"images/identity-session-binding.png\" width=\"90%\"/>\n",
"</div>\n",
"\n",
"1. Invoke agent Your agent code invokes GetResourceOauth2Token API to retrieve an authorization URL, when an originating agent user wants to access some application or resource that he/she owns.\n",
"1. Invoke agent \u2013 Your agent code invokes GetResourceOauth2Token API to retrieve an authorization URL, when an originating agent user wants to access some application or resource that he/she owns.\n",
"\n",
"2. Generate authorization URL AgentCore Identity generates an authorization URL and session URI for the user to navigate to and consent access.\n",
"2. Generate authorization URL \u2013 AgentCore Identity generates an authorization URL and session URI for the user to navigate to and consent access.\n",
"\n",
"3. Authorize and obtain access token The user navigates to the authorization URL and grants consent for your agent to access his/her resource. After that, AgentCore Identity redirects the user's browser to your HTTPS application endpoint with information containing the originating user of the authorization request. At this point, your HTTPS application endpoint determines if the originating agent user is still the same as the currently logged in user of your application. If they match, your application endpoint invokes CompleteResourceTokenAuth so that AgentCore Identity can fetch and store the access token.\n",
"3. Authorize and obtain access token \u2013 The user navigates to the authorization URL and grants consent for your agent to access his/her resource. After that, AgentCore Identity redirects the user's browser to your HTTPS application endpoint with information containing the originating user of the authorization request. At this point, your HTTPS application endpoint determines if the originating agent user is still the same as the currently logged in user of your application. If they match, your application endpoint invokes CompleteResourceTokenAuth so that AgentCore Identity can fetch and store the access token.\n",
"\n",
"4. Re-invoke agent to obtain access token Once the application returns a valid response, your agent application will be able to retrieve the OAuth2.0 access tokens that were originally requested for the user. If the users do not match, your application simply does nothing or logs the attempt.\n",
"4. Re-invoke agent to obtain access token \u2013 Once the application returns a valid response, your agent application will be able to retrieve the OAuth2.0 access tokens that were originally requested for the user. If the users do not match, your application simply does nothing or logs the attempt.\n",
"\n",
"By allowing your application endpoint to verify the user identity, AgentCore Identity allows your agent application to ensure that it is always the same user who initiated the authorization request and the one who consented access.\n",
"\n",
Expand Down Expand Up @@ -282,12 +282,12 @@
"\n",
"#### **Local Development:**\n",
"- **External Callback URL**: `http://localhost:9090/oauth2/callback` (browser-accessible)\n",
"- **Internal Communication**: `http://localhost:9090` (notebook server)\n",
"- **Internal Communication**: `http://localhost:9090` (notebook \u2194 server)\n",
"- **Server Binding**: `127.0.0.1` (localhost only, secure)\n",
"\n",
"#### **SageMaker Workshop Studio:**\n",
"- **External Callback URL**: `https://<domain>.studio.<region>.sagemaker.aws/proxy/9090/oauth2/callback` (browser-accessible via proxy)\n",
"- **Internal Communication**: `http://localhost:9090` (notebook server in same container)\n",
"- **Internal Communication**: `http://localhost:9090` (notebook \u2194 server in same container)\n",
"- **Server Binding**: `0.0.0.0` (allows SageMaker proxy to reach server)\n",
"\n",
"The OAuth2 callback server automatically detects the environment by checking for `/opt/ml/metadata/resource-metadata.json` and configures itself accordingly.\n",
Expand Down Expand Up @@ -397,7 +397,7 @@
"\n",
"# Configure GitHub OAuth2 provider - On-Behalf-Of User\n",
"github_provider = identity_client.create_oauth2_credential_provider(\n",
" {\n",
" **{\n",
" \"name\": \"github-provider\",\n",
" \"credentialProviderVendor\": \"GithubOauth2\",\n",
" \"oauth2ProviderConfigInput\": {\n",
Expand Down Expand Up @@ -790,11 +790,11 @@
" for line in iter(process.stdout.readline, \"\"):\n",
" if line:\n",
" if \"8501\" in line:\n",
" print(\"\\n🎉 Streamlit app is ready!\")\n",
" print(\"\\n\ud83c\udf89 Streamlit app is ready!\")\n",
" streamlit_url = get_streamlit_url()\n",
" print(f\"\\n🚀 Streamlit Application URL:\\n{streamlit_url}\\n\")\n",
" print(f\"\\n\ud83d\ude80 Streamlit Application URL:\\n{streamlit_url}\\n\")\n",
" print(\n",
" \"⚠️ To stop the app, interrupt the kernel or press Ctrl+C in the terminal\"\n",
" \"\u26a0\ufe0f To stop the app, interrupt the kernel or press Ctrl+C in the terminal\"\n",
" )\n",
" break\n",
"\n",
Expand Down Expand Up @@ -904,4 +904,4 @@
},
"nbformat": 4,
"nbformat_minor": 4
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Generated by setup scripts - contain real credentials/IDs
cognito_config.json
oauth_config.json
mcp_server_config.json
.env

# AgentCore CLI project directory (generated by agentcore create)
*Demo/
*AuthDemo/
*M2MAuthDemo/
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
# AgentCore Identity: Runtime Inbound and Outbound Auth (Cognito)

## Overview

This sample shows how to secure an **AgentCore Runtime** agent with both inbound and outbound authentication using Amazon Cognito as the Identity Provider (IdP).

- **Inbound Auth**: The runtime endpoint is protected by a Cognito JWT. Callers must present a valid bearer token or receive `AccessDeniedException`.
- **Outbound Auth**: The agent retrieves an API key from AgentCore Identity (backed by AWS Secrets Manager) at runtime. The key is never stored in environment variables or agent code.

### Architecture

```
Caller
│ Authorization: Bearer <Cognito JWT>
AgentCore Runtime ──validates JWT──▶ Cognito User Pool
│ @requires_api_key("OutboundApiKey")
AgentCore Identity ──fetches secret──▶ AWS Secrets Manager
External API (weather service, OpenAI, etc.)
```

### Tutorial Details

| Information | Details |
|:--------------------|:------------------------------------------------------|
| Tutorial type | CLI walkthrough |
| Agent type | Single |
| Agentic Framework | Strands Agents |
| LLM model | Anthropic Claude Haiku 4.5 |
| Inbound Auth | Amazon Cognito (CUSTOM_JWT) |
| Outbound Auth | AgentCore Identity - API Key credential provider |
| Example complexity | Easy |
| CLI tool | `agentcore` (npm: `@aws/agentcore`) |

---

## Prerequisites

- **Node.js** 20.x or later
- **Python** 3.10+
- **uv** ([install](https://docs.astral.sh/uv/getting-started/installation/))
- **AWS credentials** configured (`aws configure` or environment variables)
- **AgentCore CLI** installed:

```bash
npm install -g @aws/agentcore
```

- **Amazon Bedrock model access**: Enable `claude-haiku-4-5` in the [Bedrock console](https://console.aws.amazon.com/bedrock/home#/models)

---

## Step 1: Install Setup Dependencies

```bash
pip install -r requirements.txt
```

---

## Step 2: Set Up Cognito (Inbound IdP)

```bash
python setup_cognito.py
```

This creates:
- A Cognito User Pool with one test user (`testuser` / `AgentCoreTest1!`)
- An App Client with `USER_PASSWORD_AUTH` enabled
- Saves pool ID, client ID, and discovery URL to `cognito_config.json`

Take note of the two values printed at the end — you will need them in Step 4:

```
--discovery-url https://cognito-idp.<region>.amazonaws.com/<pool_id>/.well-known/openid-configuration
--allowed-clients <client_id>
```

---

## Step 3: Create the AgentCore Project

```bash
agentcore create --name RuntimeAuthDemo --defaults --no-agent
cd RuntimeAuthDemo
```

Set your deployment target (the CLI creates an empty `aws-targets.json`):

```bash
cat > agentcore/aws-targets.json << 'EOF'
[{"name":"default","description":"Default deployment target","account":"YOUR_AWS_ACCOUNT_ID","region":"us-east-1"}]
EOF
```

> Replace `YOUR_AWS_ACCOUNT_ID` with your 12-digit AWS account ID. Find it with `aws sts get-caller-identity --query Account --output text`.

---

## Step 4: Add the Agent (Bring Your Own Code)

Use the `--authorizer-type CUSTOM_JWT` flags to configure inbound JWT auth at deploy time. Replace the placeholder values with the discovery URL and client ID from Step 2:

```bash
agentcore add agent \
--name MyAgent \
--type byo \
--code-location ../app/MyAgent \
--entrypoint main.py \
--language Python \
--framework Strands \
--model-provider Bedrock \
--authorizer-type CUSTOM_JWT \
--discovery-url YOUR_COGNITO_DISCOVERY_URL \
--allowed-clients YOUR_COGNITO_CLIENT_ID
```

---

## Step 5: Add Outbound Identity Credential

The agent calls the [OpenWeatherMap API](https://openweathermap.org/api) which requires an API key. Get a free one:

1. Sign up at [openweathermap.org](https://home.openweathermap.org/users/sign_up) (free tier)
2. Go to [API keys](https://home.openweathermap.org/api_keys) and copy your key

Store it securely in AgentCore Identity:

```bash
agentcore add credential \
--name OutboundApiKey \
--api-key YOUR_OPENWEATHERMAP_API_KEY
```

> The CLI stores the key in AWS Secrets Manager via AgentCore Identity. At runtime, the agent retrieves it with `@requires_api_key("OutboundApiKey")`. The key never appears in code or environment variables.

---

## Step 6: Deploy

```bash
agentcore deploy -y
```

Deployment takes a few minutes. Monitor progress:

```bash
agentcore status
```

---

## Step 7: Test Inbound and Outbound Auth

Go back to the sample root directory and run the invoke script:

```bash
cd ..
python invoke.py "What is the weather in Seattle?"
```

The script runs two tests:

1. **Without bearer token** — expects `AccessDeniedException`
2. **With valid Cognito bearer token** — expects a successful agent response

Expected output:

```
[Test 1] Invoking WITHOUT bearer token (expect AccessDeniedException)...
Correctly rejected: An error occurred (AccessDeniedException) ...

[Test 2] Invoking WITH valid Cognito bearer token...
Token obtained (first 20 chars): eyJraWQiOiJxT...

Agent response:
The weather in Seattle is currently Sunny, 72F.
```

---

## Streamlit UI (Optional)

For an interactive browser-based experience instead of the CLI:

```bash
pip install streamlit
cd ..
streamlit run streamlit_app.py
```

Log in, then use the chat interface to test weather queries. Clear the Bearer Token field in the sidebar to test 403 rejection.

---

## Step 8: Cleanup

```bash
cd RuntimeAuthDemo
agentcore remove agent --name MyAgent --force
agentcore remove credential --name OutboundApiKey --force
```

Delete Cognito resources:

```python
import boto3, json

with open("../cognito_config.json") as f:
config = json.load(f)

boto3.client("cognito-idp", region_name=config["region"]).delete_user_pool(
UserPoolId=config["pool_id"]
)
print("Cognito User Pool deleted.")
```

---

## Key Concepts

| Concept | How it works in this sample |
|:--------|:---------------------------|
| **Inbound JWT validation** | AgentCore Runtime checks `Authorization: Bearer <token>` against the Cognito JWKS endpoint before executing the agent |
| **Outbound API key** | `@requires_api_key(provider_name="OutboundApiKey")` calls `bedrock-agentcore:GetResourceApiKey` + `secretsmanager:GetSecretValue` at runtime |
| **Zero-secret agent code** | API keys live in Secrets Manager; agent code only sees them in-memory via the decorator |
Loading
Loading