Skip to content

Commit 2b492c6

Browse files
sundargthbSundar Raghavan
andauthored
feat(identity): Add AWS JWT federation support for M2M auth (#382)
* feat(identity): Add AWS JWT federation support for secretless M2M authentication - Add setup-aws-jwt command to enable IAM Outbound Web Identity Federation - Add list-aws-jwt command to view AWS JWT configuration - Add AwsJwtConfig schema for storing federation settings - Add ensure_aws_jwt_permissions() to provision STS:GetWebIdentityToken IAM policy - Integrate AWS JWT permission setup into launch flow (both direct and CodeBuild paths) AWS JWT federation allows agents to authenticate with external services using AWS-signed JWTs without storing client secrets. This is ideal for M2M scenarios where the external service supports OIDC token validation. * fix: unit test files * feat(identity): Add AWS IAM JWT federation support for secretless M2M authentication - Add setup-aws-jwt command to enable IAM Outbound Web Identity Federation - Add list-aws-jwt command to view AWS IAM JWT configuration - Add AwsJwtConfig schema for storing federation settings - Add ensure_aws_jwt_permissions() to provision STS:GetWebIdentityToken IAM policy - Integrate AWS IAM JWT permission setup into launch flow (both direct and CodeBuild paths) * fix: Move aws_jwt to top-level agent config and add quickstart * fix: resolve unit test issues * fix: clean up comments and docstrings --------- Co-authored-by: Sundar Raghavan <sdraghav@amazon.com>
1 parent b8fa78c commit 2b492c6

File tree

12 files changed

+2363
-256
lines changed

12 files changed

+2363
-256
lines changed

documentation/docs/api-reference/cli.md

Lines changed: 148 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,104 @@ Options:
350350

351351
## Identity Commands
352352

353-
Manage AgentCore Identity resources for OAuth authentication and external service access.
353+
Manage AgentCore Identity resources for authentication with external services.
354+
355+
AgentCore supports two authentication methods for agents to access external services:
356+
357+
| Method | Use Case | Secrets Required |
358+
|--------|----------|------------------|
359+
| **OAuth 2.0** | User-delegated access (USER_FEDERATION) or M2M with OAuth providers | Yes (client secret) |
360+
| **AWS JWT** | M2M with services that accept OIDC tokens | No |
361+
362+
### Setup AWS JWT
363+
364+
Enable AWS IAM Outbound Web Identity Federation for secretless M2M authentication.
365+
366+
```bash
367+
agentcore identity setup-aws-jwt [OPTIONS]
368+
```
369+
370+
Options:
371+
372+
- `--audience, -a TEXT`: Audience URL for the JWT - the external service that will validate the token (required)
373+
- `--signing-algorithm, -s TEXT`: Signing algorithm: ES384 (recommended) or RS256 (default: ES384)
374+
- `--duration, -d INTEGER`: Default token duration in seconds, 60-3600 (default: 300)
375+
- `--region, -r TEXT`: AWS region (defaults to configured region)
376+
377+
**What it does:**
378+
379+
1. Enables AWS IAM Outbound Web Identity Federation for your account (one-time, idempotent)
380+
2. Stores the audience configuration in `.bedrock_agentcore.yaml`
381+
3. Returns the issuer URL to configure in your external service
382+
383+
**Examples:**
384+
385+
```bash
386+
# Set up AWS JWT for an external API
387+
agentcore identity setup-aws-jwt --audience https://api.example.com
388+
389+
# Add another audience (run command again)
390+
agentcore identity setup-aws-jwt --audience https://api2.example.com
391+
392+
# Use RS256 algorithm for compatibility with legacy services
393+
agentcore identity setup-aws-jwt --audience https://legacy-api.example.com --signing-algorithm RS256
394+
395+
# Custom token duration (10 minutes)
396+
agentcore identity setup-aws-jwt --audience https://api.example.com --duration 600
397+
```
398+
399+
**Output:**
400+
401+
```
402+
╭─────────────────────────────────────────────────────────────────╮
403+
│ ✅ Success │
404+
│ │
405+
│ AWS JWT Federation Configured │
406+
│ │
407+
│ Issuer URL: https://abc123-def456.tokens.sts.global.api.aws │
408+
│ Audiences: https://api.example.com │
409+
│ Algorithm: ES384 │
410+
│ Duration: 300s │
411+
│ │
412+
│ Next Steps: │
413+
│ 1. Configure your external service to trust this issuer URL │
414+
│ 2. Run agentcore launch to deploy (IAM permissions auto-added) │
415+
│ 3. Use @requires_iam_access_token(audience=[...]) in your agent │
416+
╰─────────────────────────────────────────────────────────────────╯
417+
```
418+
419+
**External Service Configuration:**
420+
421+
After running this command, configure your external service to:
422+
423+
1. Trust the issuer URL displayed in the output
424+
2. Validate the audience claim matches your configured audience
425+
3. Fetch the JWKS from `{issuer_url}/.well-known/jwks.json`
426+
427+
### List AWS JWT
428+
429+
Display the current AWS JWT federation configuration.
430+
431+
```bash
432+
agentcore identity list-aws-jwt
433+
```
434+
435+
**Example Output:**
436+
437+
```
438+
╭──────────────────────────────────────────────────────────────────╮
439+
│ AWS JWT Federation Configuration │
440+
├─────────────────────┬────────────────────────────────────────────┤
441+
│ Property │ Value │
442+
├─────────────────────┼────────────────────────────────────────────┤
443+
│ Enabled │ ✅ Yes │
444+
│ Issuer URL │ https://abc123-def456.tokens.sts.global... │
445+
│ Signing Algorithm │ ES384 │
446+
│ Duration (seconds) │ 300 │
447+
│ Audiences │ https://api.example.com │
448+
│ │ https://api2.example.com │
449+
╰─────────────────────┴────────────────────────────────────────────╯
450+
```
354451

355452
### Setup Cognito
356453

@@ -580,7 +677,56 @@ agentcore identity cleanup --agent my-agent --force
580677

581678
## Identity Example Usage
582679

583-
### Complete Identity Setup Workflow
680+
### AWS JWT Federation Workflow
681+
682+
For M2M authentication with external services that support OIDC tokens (no secrets required):
683+
684+
```bash
685+
# 1. Configure agent
686+
agentcore configure --entrypoint agent.py --name my-agent --disable-memory
687+
688+
# 2. Set up AWS JWT federation
689+
agentcore identity setup-aws-jwt --audience https://api.example.com
690+
691+
# 3. Deploy agent (IAM permissions added automatically)
692+
agentcore launch
693+
694+
# 4. Invoke agent
695+
agentcore invoke '{"prompt": "Call the external API"}'
696+
```
697+
698+
**Agent Code:**
699+
700+
```python
701+
from strands import Agent, tool
702+
from bedrock_agentcore.runtime import BedrockAgentCoreApp
703+
from bedrock_agentcore.identity.auth import requires_iam_access_token
704+
705+
app = BedrockAgentCoreApp()
706+
707+
@tool
708+
@requires_iam_access_token(
709+
audience=["https://api.example.com"],
710+
)
711+
def call_external_api(query: str, *, access_token: str) -> str:
712+
"""Call external API with AWS IAM JWT authentication."""
713+
import requests
714+
response = requests.get(
715+
"https://api.example.com/data",
716+
headers={"Authorization": f"Bearer {access_token}"},
717+
params={"q": query},
718+
)
719+
return response.text
720+
721+
@app.entrypoint
722+
async def invoke(payload, context):
723+
agent = Agent(model="us.anthropic.claude-sonnet-4-5-20250929-v1:0", tools=[call_external_api])
724+
response = await agent.invoke_async(payload.get("prompt", ""))
725+
return {"response": str(response.message)}
726+
```
727+
728+
729+
### OAuth Identity Setup Workflow
584730

585731
```bash
586732
# 1. Create Cognito pools

0 commit comments

Comments
 (0)