Amit Arora ff5fdffd42
fix(02-use-cases): Add multi-region support for SRE-Agent (#246)
* Add multi-region support for SRE-Agent

- Add AWS region configuration parameter to agent_config.yaml
- Update gateway main.py to validate region matches endpoint URL
- Modify SRE agent to read region from config and pass through function chain
- Update memory client and LLM creation to use configurable region
- Fixes hardcoded us-east-1 region dependencies

Closes #245

* Move architecture file to docs/ and improve setup instructions

- Move sre_agent_architecture.md to docs/ folder for better organization
- Update graph export code to generate architecture file in docs/ folder
- Add automatic docs directory creation if it doesn't exist
- Improve README setup instructions:
  - Fix .env.example copy path to use sre_agent folder
  - Add note that Amazon Bedrock users don't need to modify .env
  - Add START_API_BACKEND variable to conditionally start backend servers
  - Useful for workshop environments where backends are already running

* Improve gateway configuration documentation and setup instructions

- Update config.yaml.example to use REGION placeholder instead of hardcoded us-east-1
- Add gateway configuration step to README setup instructions
- Document .cognito_config file in auth.md automated setup section
- Remove duplicate credential_provider_name from config.yaml.example
- Update configuration.md to include .cognito_config in files overview
- Add clear instructions to copy and edit gateway/config.yaml before creating gateway

* Improve IAM role guidance and region handling

- Add clear guidance about IAM role options in gateway/config.yaml.example
- Explain that testing can use current EC2/notebook role
- Recommend dedicated role for production deployments
- Add aws sts get-caller-identity command to help users find their role
- Update deployment scripts to use AWS_REGION env var as fallback
- Scripts now follow: CLI arg -> AWS_REGION env var -> us-east-1 default

* Remove unnecessary individual Cognito ID files

- Remove creation of .cognito_user_pool_id file
- Remove creation of .cognito_client_id file
- Keep only .cognito_config as the single source of truth
- Simplifies configuration management

* Implement region fallback logic for SRE Agent

- Added region fallback chain: agent_config.yaml -> AWS_REGION env -> us-east-1
- Modified agent_config.yaml to comment out region parameter to enable fallback
- Updated multi_agent_langgraph.py with comprehensive fallback implementation
- Added logging to show which region source is being used
- Ensures flexible region configuration without breaking existing deployments
- Maintains backward compatibility while adding multi-region support
2025-08-13 08:32:37 -04:00

12 KiB

Authentication and Authorization Setup

This document covers the setup requirements for IAM permissions and identity provider (IDP) configuration needed for AgentCore Gateway.

IAM Permissions Setup

AWS Managed Policy

For simplified setup, AWS provides a managed policy that includes all necessary permissions for Bedrock AgentCore operations:

Policy Name: BedrockAgentCoreFullAccess

This managed policy should be attached to the IAM role used by your AgentCore runtime. It includes:

  • All bedrock-agentcore permissions
  • Required IAM:PassRole permissions
  • S3 access for schema storage
  • Other necessary service permissions

Trust Policy Requirements

The IAM role must include a trust policy that allows the Bedrock AgentCore service to assume the role:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "bedrock-agentcore.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

Core Gateway Permissions (Alternative)

If you prefer granular permissions instead of the managed policy, use this policy for invoking CRUDL operations on Gateway Target or Gateway, InvokeTool API, and ListTool:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "bedrock-agentcore:*",
                "iam:PassRole"
            ],
            "Resource": "*"
        }
    ]
}

S3 Schema Access

Policy required for creating target with API schema in S3 (attach to the same caller identity as above policy):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": "*"
        }
    ]
}

Lambda Target Permissions

If Lambda is a Gateway target type, the execution role should have permission to invoke lambda:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "lambda:InvokeFunction",
            "Resource": "arn:aws:lambda:us-west-2:<account-with-lambda>:function:TestLambda"
        }
    ]
}

Smithy Target Permissions

If the Gateway Target is of Smithy Target type:

  • Execution role must include any AWS permissions for the tools/APIs you wish to invoke
  • Example: Adding a gateway target for S3 → add relevant S3 permissions to the role

You need to trust the AgentCore service's beta account to assume the role:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "bedrock-agentcore.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        },
    ]
}

Cross-Account Lambda Access

If the Lambda is in another account, configure a resource-based policy (RBP) on the lambda function:

{
    "Version": "2012-10-17",
    "Id": "default",
    "Statement": [
        {
            "Sid": "cross-account-access",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<gateway-account>:role/AgentCoreBetaLambdaExecuteRole"
            },
            "Action": "lambda:InvokeFunction",
            "Resource": "arn:aws:lambda:us-west-2:<account-with-lambda>:function:TestLambda"
        }
    ]
}

Identity Provider Configuration

Important: Cognito vs Auth0/Okta Authentication Differences

Critical Distinction for AgentCore Gateway Configuration:

Provider JWT Claim Used Gateway Configuration Token Contains
Amazon Cognito client_id allowedClients: ["client-id"] No aud claim
Auth0 aud allowedAudience: ["audience"] Has aud claim
Okta aud allowedAudience: ["audience"] Has aud claim

Why this matters:

  • Cognito client credentials tokens do NOT include an aud (audience) claim
  • AgentCore Gateway with allowedAudience will reject Cognito tokens (401 error)
  • For Cognito, you MUST use allowedClients with your app client ID
  • For Auth0/Okta, you MUST use allowedAudience with your API identifier

1. Amazon Cognito Setup

For a complete end-to-end Cognito setup, use the automation script:

cd deployment
./setup_cognito.sh

This script will:

  • Create user pool and domain
  • Create resource server with scopes
  • Create app client with credentials
  • Generate .env file with all required variables
  • Save all Cognito configuration to deployment/.cognito_config file
  • Provide configuration details for gateway setup

Important Files Created:

  • deployment/.cognito_config - Contains USER_POOL_ID, CLIENT_ID, CLIENT_SECRET, and other Cognito settings
  • gateway/.env - Environment variables for authentication

You can reference the values in .cognito_config when configuring gateway/config.yaml

Option B: Manual Setup

If you prefer to set up Cognito manually, follow these steps:

Create User Pool

Create a machine-to-machine user pool:

# Create user pool
aws cognito-idp create-user-pool \
    --region us-west-2 \
    --pool-name "test-agentcore-user-pool"

# List user pools to get the pool ID
aws cognito-idp list-user-pools \
    --region us-west-2 \
    --max-results 60

Discovery URL Format

https://cognito-idp.us-west-2.amazonaws.com/<UserPoolId>/.well-known/openid-configuration

Create Resource Server

aws cognito-idp create-resource-server \
    --region us-west-2 \
    --user-pool-id <UserPoolId> \
    --identifier "test-agentcore-server" \
    --name "TestAgentCoreServer" \
    --scopes '[{"ScopeName":"read","ScopeDescription":"Read access"}, {"ScopeName":"write","ScopeDescription":"Write access"}]'

Create User Pool Domain

Important: You must create a domain before you can get access tokens.

# Create user pool domain (required for token endpoint)
aws cognito-idp create-user-pool-domain \
    --region us-west-2 \
    --user-pool-id <UserPoolId> \
    --domain "your-unique-domain-name"

# Note: Domain name must be globally unique across all AWS accounts
# Example: "sre-agent-demo-12345" or "mycompany-sre-agent"

Create Client

aws cognito-idp create-user-pool-client \
    --region us-west-2 \
    --user-pool-id <UserPoolId> \
    --client-name "test-agentcore-client" \
    --generate-secret \
    --allowed-o-auth-flows client_credentials \
    --allowed-o-auth-scopes "test-agentcore-server/read" "test-agentcore-server/write" \
    --allowed-o-auth-flows-user-pool-client \
    --supported-identity-providers "COGNITO"

Get Access Token

# Use your domain name (not UserPoolId) in the URL
curl --http1.1 -X POST https://<your-domain-name>.auth.us-west-2.amazoncognito.com/oauth2/token \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -d "grant_type=client_credentials&client_id=<ClientId>&client_secret=<ClientSecret>"

Note: Use the domain name you created in the previous step, NOT the UserPoolId. The URL format is: https://<domain-name>.auth.<region>.amazoncognito.com/oauth2/token

Sample Cognito Token Claims

{
    "sub": "<>",
    "token_use": "access",
    "scope": "default-m2m-resource-server-<>/read",
    "auth_time": 1749679004,
    "iss": "https://cognito-idp.us-west-2.amazonaws.com/us-west-<>",
    "exp": 1749682604,
    "iat": 1749679004,
    "version": 2,
    "jti": "<>",
    "client_id": "<>"
}

Cognito Authorizer Configuration

{
    "authorizerConfiguration": {
        "customJWTAuthorizer": {
            "allowedClients": ["<ClientId>"],
            "discoveryUrl": "https://cognito-idp.us-west-2.amazonaws.com/<UserPoolId>/.well-known/openid-configuration"
        }
    }
}

2. Auth0 Setup

Setup Steps

  1. Create an API (1:1 mapping to a resource server)
  2. Create an Application (Acts as client to the resource server)
  3. Configure the API Identifier in API > Settings (added to audience claim)
  4. Configure scopes in API > Scopes section

Discovery URL Format

https://<your-domain>/.well-known/openid-configuration

Get Access Token

curl --request POST \
    --url https://dev-<your-domain>.us.auth0.com/oauth/token \
    --header 'content-type: application/json' \
    --data '{
        "client_id":"YOUR_CLIENT_ID",
        "client_secret":"YOUR_CLIENT_SECRET",
        "audience":"gateway123",
        "grant_type":"client_credentials",
        "scope": "invoke:gateway"
    }'

Sample Auth0 Token Claims

{
    "iss": "https://dev-<>.us.auth0.com/",
    "sub": "<>",
    "aud": "gateway123",
    "iat": 1749741913,
    "exp": 1749828313,
    "scope": "invoke:gateway read:gateway",
    "jti": "<>",
    "client_id": "<>",
    "permissions": [
        "invoke:gateway",
        "read:gateway"
    ]
}

Auth0 Authorizer Configuration

{
    "authorizerConfiguration": {
        "customJWTAuthorizer": {
            "allowedAudience": ["gateway123"],
            "discoveryUrl": "https://dev-<your-domain>.us.auth0.com/.well-known/openid-configuration"
        }
    }
}

3. Okta Setup

Setup Steps

  1. Create Application with Client credentials grant type

  2. Configure Application

    • Go to Admin → Applications → Create a client with secret
    • Disable "Require Demonstrating Proof of Possession (DPoP) header in token requests"
  3. Configure Authorization Server

    • Go to Admin → Security → API
    • Use default Authorization Server
    • Add additional scopes (e.g., "InvokeGateway")
    • Optionally add Access policies and claims
  4. Get Configuration

    • Obtain Metadata URI for default Authorization Server (Discovery URI)
    • Get ClientID/Secret for JWT Authorizer configuration

Token Validation

Use jwt.io to decode and validate bearer tokens during debugging.

Environment Variables

After setting up your identity provider, configure these environment variables in your .env file:

# For Cognito
COGNITO_DOMAIN=https://your-domain-name.auth.us-west-2.amazoncognito.com
COGNITO_CLIENT_ID=your-client-id
COGNITO_CLIENT_SECRET=your-client-secret

# Where 'your-domain-name' is the domain you created with:
# aws cognito-idp create-user-pool-domain --domain "your-domain-name"

# For Auth0
COGNITO_DOMAIN=https://dev-yourdomain.us.auth0.com
COGNITO_CLIENT_ID=your-client-id
COGNITO_CLIENT_SECRET=your-client-secret

Troubleshooting

Common 401 "Invalid Bearer token" Error

Problem: Gateway returns HTTP 401 with "Invalid Bearer token" message.

Root Cause: Mismatch between token claims and gateway configuration.

Solution Steps:

  1. Decode your JWT token using jwt.io to inspect claims
  2. Check your token claims:
    • Cognito tokens: Look for client_id claim (no aud claim)
    • Auth0/Okta tokens: Look for aud claim
  3. Verify gateway configuration matches your token:
    # If your token has client_id but no aud claim (Cognito)
    python main.py "Gateway" --allowed-clients "your-client-id" ...
    
    # If your token has aud claim (Auth0/Okta)
    python main.py "Gateway" --allowed-audience "your-audience" ...
    
  4. Common fixes:
    • Cognito users: Use --allowed-clients not --allowed-audience
    • Auth0 users: Use --allowed-audience not --allowed-clients
    • Check client ID: Must match exactly (case-sensitive)
    • Check audience: Must match your API identifier exactly

Other Common Issues

  • If token endpoint doesn't work, check the discovery URL in your browser to find the correct token_endpoint
  • Ensure audience values match between token request and gateway configuration
  • Verify scopes are properly configured in your IDP
  • Check that the discovery URL is accessible and returns valid OpenID configuration
  • For Cognito: Ensure your app client has client_credentials grant type enabled