

# Manage credential providers with AgentCore Identity
Manage credential providers

Credential management is a core feature of Amazon Bedrock AgentCore Identity that addresses the complex challenge of securely storing, retrieving, and managing credentials across multiple trust domains and authentication systems. The service implements defense-in-depth security measures to protect sensitive authentication tokens, API keys, and certificates while providing agents with efficient access to the credentials they need for authorized operations. AgentCore Identity’s credential management architecture separates credential storage from credential access, helping to ensure that agents never have direct access to long-term secrets or refresh tokens.

The credential management system supports multiple credential types including OAuth2 access tokens, API keys, client certificates, SAML assertions, and custom authentication tokens. Each credential type has specific handling requirements for storage encryption and access patterns. All credential operations are logged and audited to provide complete visibility into credential usage and access patterns.

Integration with the Resource Credential Provider enables AgentCore Identity to support cross-capability credential vending, where agents can access resources across different cloud providers, SaaS applications, and enterprise systems using a unified credential management interface. The system maintains proper security boundaries while enabling necessary functionality, with comprehensive monitoring and alerting capabilities that detect unusual credential usage patterns or potential security threats.

**Topics**
+ [

# Supported authentication patterns
](common-use-cases.md)
+ [

# Configure credential provider
](resource-providers.md)
+ [

# Obtain credentials
](obtain-credentials.md)

# Supported authentication patterns
Supported authentication patterns

AgentCore Identity supports two primary authentication patterns that address different agent use cases. Understanding these patterns will help you choose the right approach for your specific agent implementation.

For detailed examples of how these patterns apply to specific industries and agent types, see [Example use cases](identity-use-cases.md).

**Topics**
+ [

## User-delegated access (OAuth 2.0 authorization code grant)
](#user-delegated-access)
+ [

## Machine-to-machine authentication (OAuth 2.0 client credentials grant)
](#machine-to-machine-auth)
+ [

## Choosing the right authentication pattern
](#choosing-auth-pattern)

## User-delegated access (OAuth 2.0 authorization code grant)


The OAuth 2.0 authorization code grant flow enables agents to access user-specific data with explicit user consent. This pattern is essential when agents need to access personal data or perform actions on behalf of specific users. The flow includes a user consent step where the resource owner (user) explicitly authorizes the agent to access their data within specific scopes.

 **Key characteristics** 
+ Requires explicit user consent through an authorization prompt
+ Provides access to user-specific data and resources
+ Maintains clear separation between agent identity and user authorization
+ Supports fine-grained scopes that limit what data the agent can access

 **Example scenario** – A productivity agent needs to access a user’s Google Calendar to schedule meetings, their Gmail to send emails, and their Google Drive to store documents. The agent uses the OAuth 2.0 authorization code grant to obtain user consent for each service, with specific scopes that limit access to only the necessary data. The user explicitly authorizes the agent through Google’s consent screen, and AgentCore Identity securely stores the resulting credentials for future use.

This pattern is ideal for personal assistant agents, customer service agents, and any scenario where agents need access to user-specific data across multiple services. For detailed industry-specific examples, see [Personal assistant agents](identity-use-cases.md#personal-assistant-agents) and [Customer service agents](identity-use-cases.md#customer-service-agents).

## Machine-to-machine authentication (OAuth 2.0 client credentials grant)


The OAuth 2.0 client credentials grant flow enables direct authentication between systems without user interaction. This pattern is appropriate when agents need to access resources that aren’t user-specific or when agents act themselves with pre-authorized user consent.

 **Key characteristics** 
+ No user interaction or consent required
+ Agent authenticates directly with resource servers using its own credentials
+ Suitable for background processes, scheduled tasks, and system-level operations
+ Permissions are defined at the agent level rather than per-user

 **Example scenario** – An enterprise data processing agent needs to collect data from multiple internal systems, process it, and store the results in a data warehouse. The agent uses the OAuth 2.0 client credentials grant to authenticate directly with each system using its own identity and pre-configured permissions. No user interaction is required, and the agent can operate when agents act themselves with pre-authorized user consent on scheduled intervals.

This pattern is ideal for enterprise automation agents, data processing workflows, and DevOps automation. For detailed industry-specific examples, see [Enterprise automation agents](identity-use-cases.md#enterprise-automation-agents) , [Data processing and analytics agents](identity-use-cases.md#data-processing-and-analytics-agents) , and [Development and DevOps agents](identity-use-cases.md#development-and-devops-agents).

## Choosing the right authentication pattern


When designing your agent authentication strategy, consider these factors to determine which pattern is most appropriate:


| Factor | User-delegated access (OAuth 2.0 authorization code grant) | Machine-to-machine authentication (OAuth 2.0 client credentials grant) | 
| --- | --- | --- | 
|  Data ownership  |  User-specific data (emails, documents, personal calendars)  |  System or organization-owned data (analytics, logs, shared resources)  | 
|  User interaction  |  User is present and can provide consent  |  No user interaction required or available  | 
|  Operation timing  |  Interactive, real-time operations  |  Background, scheduled, or batch operations  | 
|  Permission scope  |  Permissions vary by user and their consent choices  |  Consistent permissions defined at the agent level  | 

Many agent implementations will require both patterns for different aspects of their functionality. For example, a customer service agent might use user-delegated access to retrieve a specific customer’s data while using machine-to-machine authentication to access company knowledge bases and internal systems. AgentCore Identity supports both patterns simultaneously, allowing agents to use the most appropriate authentication mechanism for each resource they need to access.

Both authentication patterns benefit from AgentCore Identity’s core capabilities:
+ Secure credential storage without exposing secrets to agent code
+ Consistent authentication interfaces across multiple resource types
+ Comprehensive audit logging for security and compliance
+ Fine-grained access controls based on identity and context
+ Simplified integration through the AgentCore SDK

# Configure credential provider
Configure credential provider

Resource credential providers in AgentCore Identity act as intelligent intermediaries that manage the complex relationships between agents, identity providers, and resource servers. Each provider encapsulates the specific endpoint configuration required for a particular service or identity system. The service provides built-in providers for popular services including Google, GitHub, Slack, and Salesforce, with authorization server endpoints and provider-specific parameters pre-configured to reduce development effort. AgentCore Identity supports custom configurations through configurable OAuth2 credential providers that can be tailored to work with any OAuth2-compatible resource server. For information about OAuth2 credential provider limits, see [AgentCore Identity Service Quotas](bedrock-agentcore-limits.md#identity-service-limits).

Resource credential providers integrate deeply with the token vault to provide seamless credential lifecycle management. When an agent requests access to a resource, the provider handles the authentication flow, stores the resulting credentials in the token vault, and provides the agent with the necessary access tokens.

## Creating an OAuth 2.0 credential provider


Provider configurations in AgentCore Identity define the basic parameters needed for credential management with different resources and authentication systems.

If you are using the AgentCore CLI, you can create an OAuth 2.0 credential provider with the `agentcore add credential` command:

```
agentcore add credential --type oauth \
  --name github-provider \
  --discovery-url https://your-idp/.well-known/openid-configuration \
  --client-id your-github-client-id \
  --client-secret your-github-client-secret \
  --scopes repo,user
```

The CLI stores the credential configuration in `agentcore/agentcore.json` and saves sensitive values (client ID and client secret) to `agentcore/.env.local`.

Alternatively, you can use the AgentCore SDK to configure an OAuth 2.0 credential provider programmatically. The following example configures a provider for GitHub.

```
from bedrock_agentcore.services.identity import IdentityClient
identity_client = IdentityClient("us-east-1")
github_provider = identity_client.create_oauth2_credential_provider({
        "name": "github-provider",
        "credentialProviderVendor": "GithubOauth2",
        "oauth2ProviderConfigInput": {
            "githubOauth2ProviderConfig": {
                "clientId": "your-github-client-id",
                "clientSecret": "your-github-client-secret"
            }
        }
    })
```

## Creating an API key credential provider


For services that use API keys for authentication rather than OAuth, AgentCore Identity will securely store and retrieve keys for your agents. For information about API key credential provider limits, see [AgentCore Identity Service Quotas](bedrock-agentcore-limits.md#identity-service-limits).

If you are using the AgentCore CLI, you can store an API key with a single command:

```
agentcore add credential --name your-service-name --api-key your-api-key
```

Alternatively, you can use the AgentCore SDK to store an API key programmatically:

```
from bedrock_agentcore.services.identity import IdentityClient
identity_client= IdentityClient("us-east-1")
apikey_provider= identity_client.create_api_key_credential_provider({
        "name": "your-service-name",
        "apiKey": "your-api-key"
    })
```

# Obtain credentials
Obtain credentials

AgentCore Identity uses a workload access token to authorize agent access to credentials stored in the vault, and this token contains both the identity of the agent and the identity of the end user on whose behalf the agent is working. AgentCore Runtime will automatically provide a token when invoking an agent that it is hosting. Agents hosted on other systems can retrieve their agent token using the AgentCore SDK.

**Topics**
+ [

# Get workload access token
](get-workload-access-token.md)
+ [

# Obtain OAuth 2.0 access token
](identity-authentication.md)
+ [

# OAuth 2.0 authorization URL session binding
](oauth2-authorization-url-session-binding.md)
+ [

# Scope down access to credential providers by workload identity
](scope-credential-provider-access.md)
+ [

# Obtain API key
](obtain-api-key.md)

# Get workload access token
Get workload access token

Understanding what workload access tokens are, how to obtain them, and the security aspects of working with them is essential for building secure agent applications. This section covers the key concepts and implementation patterns you need to know.

**Topics**
+ [

## What is a workload access token?
](#workload-access-token-overview)
+ [

## How Runtime and Gateway automatically obtain tokens
](#how-runtime-gateway-obtain-tokens)
+ [

## How to manually retrieve workload access tokens
](#manual-token-retrieval-patterns)
+ [

## Security controls for `GetWorkloadAccessTokenForUserId` API
](#security-controls-getuserid-api)

## What is a workload access token?


A workload access token is an AWS-signed opaque access token that enables agents to access first-party AgentCore services, such as outbound credential providers. Runtime automatically delivers workload access tokens to agent execution instances as payload headers, eliminating the need for manual token management in most scenarios.

 **Key characteristics** 
+  **First-party services only** – Workload access tokens are exclusively for accessing AWS first-party AgentCore services and cannot be used for external services
+  **Automatic delivery** – Runtime and Gateway automatically provide these tokens to agents during execution
+  **Security by design** – Runtime-managed agent identities cannot retrieve workload access tokens directly, preventing token extraction and misuse
+  **User and agent identity binding** – Tokens contain both user identity and agent identity information for secure credential access

## How Runtime and Gateway automatically obtain tokens


When an agent is invoked through AgentCore Runtime or Gateway with inbound authentication, the service automatically handles workload access token generation:

1. Runtime validates the inbound identity provider OAuth token (issuer, signature)

1. Runtime extracts issuer and sub claims from the OAuth token representing user identity

1. Runtime fetches the associated workload identity of the agent

1. Runtime invokes `GetWorkloadAccessTokenForJWT` with both user identity and agent workload identity

1. Runtime passes the workload access token to agent code as part of the invocation payload header

This automatic process ensures agents receive properly scoped tokens without manual intervention.

## How to manually retrieve workload access tokens


There are two patterns to use to retrieve the workload access token depending on how you are able to identify the end user of the agent:
+ If the agent’s caller has a JWT identifying the end user, request a workload access token based on the agent’s identity and the end-user JWT. When you provide a JWT, AgentCore Identity will validate the JWT to ensure it is correctly signed and unexpired, and it will use its “iss” and “sub” claims to uniquely identify the user. Credentials stored by the agent on behalf of the user will be associated with this information, and future retrievals by the agent will require a valid workload access token containing the same information.
+ If the agent’s caller does not have a JWT identifying the end user, request a workload access token based on the agent’s identity and a unique string identifying the user.

The examples below illustrate using the AgentCore SDK to retrieve a workload access token using these two methods:

```
from bedrock_agentcore.services.identity import IdentityClient

identity_client= IdentityClient("us-east-1")# Obtain a token using the IAM identity of the caller to authenticate the agent and providing a JWT containing the identity of the end user.
# This is the recommended pattern whenever a JWT is available for the user.
workload_access_token= identity_client.get_workload_access_token(workload_name= "my-demo-agent", user_token= "insert-jwt-here")# Obtain a token using the IAM identity of the caller to authenticate the agent and providing a string representing the identity of the end user.
# Use this pattern when a JWT is not available for the user.
workload_access_token= identity_client.get_workload_access_token(workload_name= "my-demo-agent", user_id= "insert-user-name-or-identifier")
```

## Security controls for `GetWorkloadAccessTokenForUserId` API


The `GetWorkloadAccessTokenForUserId` API implements several security controls to prevent unauthorized access:
+  **Workload identity validation** – The API verifies that the requesting identity has permission to act on behalf of the specified workload identity
+  **Service-managed identity restriction** – Runtime-managed and Gateway-managed workload identities cannot retrieve tokens directly. This prevents agents from extracting tokens for misuse
+  **IAM permission requirements** – Callers must have appropriate IAM permissions including `GetWorkloadAccessToken` , `GetWorkloadAccessTokenForUserId` , and `GetWorkloadAccessTokenForJWT` 
+  **Token scoping** – Tokens are scoped to the specific user-agent pair, ensuring credentials stored under one user cannot be accessed by another
+  **User ID partitioning for multiple identity providers** – When using multiple identity providers, partition your user IDs using the pattern `provider_id+user_id` to prevent user collisions between different providers. For example, use `cognito+user123` and `auth0+user123` to distinguish users with the same identifier across different identity providers

If you encounter the error "WorkloadIdentity is linked to a service and cannot retrieve an access token by the caller," this indicates the workload identity is managed by Runtime or Gateway and cannot retrieve tokens directly. This restriction helps maintain security boundaries and prevents unauthorized token access.

For additional security controls, you can implement fine-grained access policies to restrict which workload identities can access specific credential providers. For more information, see [Scope down access to credential providers by workload identity](scope-credential-provider-access.md).

# Obtain OAuth 2.0 access token
Obtain access token

AgentCore Identity enables developers to obtain OAuth tokens for either user-delegated access or machine-to-machine authentication based on the configured OAuth 2.0 credential providers. The service will orchestrate the authentication process between the user or application to the downstream authorization server, and it will retrieve and store the resulting token. Once the token is available in the AgentCore Identity vault, authorized agents can retrieve it and use it to authorize calls to resource servers. For example, the sample code below will retrieve a token to interact with Google Drive on behalf of an end user. For more information, see [Integrate with Google Drive using OAuth2](identity-getting-started-google.md) for the complete example.

```
# Injects Google Access Token
@requires_access_token(
    # Uses the same credential provider name created above
    provider_name= "google-provider",
    # Requires Google OAuth2 scope to access Google Drive
    scopes= ["https://www.googleapis.com/auth/drive.metadata.readonly"],
    # Sets to OAuth 2.0 Authorization Code flow
    auth_flow= "USER_FEDERATION",
    # Prints authorization URL to console
    on_auth_url= lambda x: print("\nPlease copy and paste this URL in your browser:\n" + x),
    # If false, caches obtained access token
    force_authentication= False,
    callback_url='insert_oauth2_callback_url_for_session_binding',
)
async def write_to_google_drive(*, access_token: str):
    # Use the token to call Google Drive
    pass

# To invoke:
# asyncio.run(write_to_google_drive())
```

The process is similar to obtain a token for machine-to-machine calls, as shown in the following example:

```
import asyncio
from bedrock_agentcore.identity.auth import requires_access_token, requires_api_key

@requires_access_token(
    provider_name= "my-api-key-provider", # replace with your own credential provider name
    scopes= [],
    auth_flow= 'M2M',
)
async def need_token_2LO_async(*, access_token: str):
    # Use the access token
    pass

# To invoke:
# asyncio.run(need_token_2LO_async())
```

**Topics**
+ [

## Automatic refresh token storage and usage
](#automatic-refresh-token-storage)
+ [

## Streaming authorization URLs to application callers
](#authorization-url-streaming)
+ [

## Resource indicators in AgentCore OAuth2 flows
](#resource-indicators-cognito)

## Automatic refresh token storage and usage


AgentCore automatically stores and uses refresh tokens when available from OAuth2 providers, reducing the frequency of user reauthorization prompts. When users initially grant consent through a standard OAuth2 authorization code flow, the system stores both access tokens and refresh tokens (if provided) in the secure token vault. This enables agents to obtain fresh access tokens automatically when the original tokens expire, improving user experience by minimizing repeated consent requests.

**Important**  
Access tokens returned by AgentCore are not guaranteed to be valid. Tokens can be revoked by customers on the federated provider side, which AgentCore cannot detect. If a token is invalid, use `forceAuthentication: true` to force a new authentication flow and obtain a valid access token.

Refresh tokens typically have longer lifespans than access tokens, with a default validity period of approximately 30 days compared to the shorter lifespan of access tokens (often 1-2 hours). When an access token expires, AgentCore automatically uses the stored refresh token to request a new access token from the provider. **If a valid refresh token is stored, AgentCore skips the user federation flow and directly returns a new access token** . If the refresh token is also expired or invalid, the system falls back to prompting the user for full reauthorization.

This feature requires no configuration within AgentCore - it operates automatically when refresh tokens are present in the OAuth2 provider’s token response. However, you must configure your OAuth2 provider to include refresh tokens in the authorization flow. The specific configuration depends on your provider:


| Provider | Configuration Required | 
| --- | --- | 
|   **Google**   |  Include `access_type=offline` in `customParameters` when calling `GetResourceOauth2Token`  <pre>"customParameters": { "access_type": "offline" }</pre>  | 
|   **Microsoft**   |  Include `offline_access` in `scopes` parameter when calling `GetResourceOauth2Token`  <pre>"scopes": ["openid", "profile", "offline_access"]</pre>  | 
|   **Salesforce**   |  Include `refresh_token` in `scopes` parameter when calling `GetResourceOauth2Token`  <pre>"scopes": ["api", "refresh_token"]</pre>  | 
|   **Atlassian**   |  Include `offline_access` in `scopes` parameter when calling `GetResourceOauth2Token`  <pre>"scopes": ["read:jira-user", "offline_access"]</pre>  | 
|   **GitHub**   |  No extra AgentCore configuration required. Enable User-to-server token expiration feature in your GitHub app settings. Refresh tokens are stored automatically when this feature is enabled.  | 
|   **Slack**   |  No extra AgentCore configuration required. Enable "token rotation" feature in your Slack app settings. Refresh tokens are returned automatically when this feature is enabled.  | 
|   **LinkedIn**   |  No extra AgentCore configuration required. Enable refresh token settings in your LinkedIn app configuration.  | 
|   **Other providers**   |  Some providers require configuration in their provider settings rather than API parameters. Consult your provider’s documentation for refresh token requirements.  | 

If your provider supports refresh tokens and is properly configured, AgentCore will automatically store and manage them without additional setup. To clear stored refresh tokens and force users to reauthenticate, set `forceAuthentication=true` when calling GetResourceOauth2Token. This clears the refresh token and forces a complete federation flow. For information about configuring OAuth2 providers, see [Provider setup and configuration](identity-idps.md).

## Streaming authorization URLs to application callers


For three-legged OAuth (3LO) flows, your agent needs to provide the authorization URL to the calling application so users can complete the consent flow. While the examples above show printing the URL to the console, production applications require streaming the URL back to the caller through your application’s response mechanism.

 **Common implementation patterns** 

 **Streaming response pattern** – For applications that support streaming responses, you can send the authorization URL as part of the response stream:

```
import asyncio
from bedrock_agentcore.identity.auth import requires_access_token

@requires_access_token(
    provider_name="google-provider",
    scopes=["https://www.googleapis.com/auth/drive.metadata.readonly"],
    auth_flow="USER_FEDERATION",
    # Stream URL back to caller instead of printing
    on_auth_url=lambda url: stream_to_caller({
        "type": "authorization_required",
        "authorization_url": url,
        "message": "Please visit this URL to authorize access"
    }),
    force_authentication=False,
    callback_url='insert_oauth2_callback_url_for_session_binding'
)
async def agent_with_streaming_auth(*, access_token: str):
    # Agent logic continues after user completes authorization
    return {"status": "success", "token_received": True}

def stream_to_caller(data):
    # Implementation depends on your streaming mechanism
    # Examples: WebSocket, Server-Sent Events, HTTP chunked response
    response_stream.send(json.dumps(data))
```

 **Callback pattern** – For applications using callbacks or webhooks, store the authorization URL and notify the caller:

```
import asyncio
from bedrock_agentcore.identity.auth import requires_access_token

@requires_access_token(
    provider_name="google-provider",
    scopes=["https://www.googleapis.com/auth/drive.metadata.readonly"],
    auth_flow="USER_FEDERATION",
    # Store URL and trigger callback
    on_auth_url=lambda url: handle_auth_callback(url),
    force_authentication=False,
    callback_url='insert_oauth2_callback_url_for_session_binding'
)
async def agent_with_callback_auth(*, access_token: str):
    return {"status": "success", "data": "processed"}

def handle_auth_callback(authorization_url):
    # Store the URL associated with the request
    auth_store.save(request_id, {
        "authorization_url": authorization_url,
        "status": "pending_authorization"
    })

    # Notify the calling application
    callback_service.notify(callback_url, {
        "request_id": request_id,
        "authorization_url": authorization_url,
        "action_required": "user_authorization"
    })
```

 **Polling pattern** – For applications that prefer polling, store the authorization URL in a retrievable location:

```
import asyncio
from bedrock_agentcore.identity.auth import requires_access_token

@requires_access_token(
    provider_name="google-provider",
    scopes=["https://www.googleapis.com/auth/drive.metadata.readonly"],
    auth_flow="USER_FEDERATION",
    # Store URL for polling retrieval
    on_auth_url=lambda url: store_auth_url_for_polling(url),
    force_authentication=False,
    callback_url='insert_oauth2_callback_url_for_session_binding'
)
async def agent_with_polling_auth(*, access_token: str):
    return {"status": "success", "data": "processed"}

def store_auth_url_for_polling(authorization_url):
    # Store in database, cache, or session store
    session_store.set(f"auth_url:{session_id}", {
        "authorization_url": authorization_url,
        "created_at": datetime.utcnow(),
        "status": "pending"
    }, ttl=300)  # 5 minute expiration
```

Choose the pattern that best fits your application architecture. Streaming responses provide the best user experience for real-time applications, while callback and polling patterns work well for asynchronous or batch processing scenarios.

## Resource indicators in AgentCore OAuth2 flows


Resource indicators provide a standardized way to specify which resource server should accept an OAuth2 access token. AgentCore uses Cognito as its authentication provider, which supports RFC 8707-compliant resource indicators that allow you to specify the intended resource server during token requests. To use resource indicators, you must first configure the authorization server to recognize specific resource servers using Cognito’s CreateResourceServer API. Once configured, when you specify a resource indicator in your token request, Cognito includes the corresponding resource server identifier in the aud claim of the resulting token, enabling the resource server to verify that the token is intended for its specific use. This provides several important benefits: resource servers can validate that tokens are specifically intended for them (principle of least privilege), improved auditability by clearly identifying which resource server each token targets, and reduced risk of token misuse across different services within your application environment.

Through Cognito’s [RFC 8707](https://www.rfc-editor.org/rfc/rfc8707.html) implementation, AgentCore enables clients to specify a resource server directly in authorization and token requests, overriding the default audience parameter. In Cognito, the 'resource indicator' referred to in the RFC corresponds to the [ResourceServer’s](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_CreateResourceServer.html) 'identifier' value. Resource indicators are particularly important for Model Context Protocol (MCP) implementations, where they help mitigate specific security risks outlined in the MCP authorization specification. The resource indicator corresponds to the RFC 9728 resource parameter, ensuring proper token scoping for MCP server interactions. Note that the current implementation supports single-resource binding, meaning you can specify one resource server per token request.

Use resource indicators when your agents need to access resource servers with specific security requirements, or when you need fine-grained control over token audience validation. Resource indicators are particularly useful for multi-tenant applications where tokens should be restricted to specific customer resources.

# OAuth 2.0 authorization URL session binding
OAuth 2.0 authorization URL session binding

AgentCore Identity provides OAuth 2.0 access token retrievals for your agent applications to access third-party application vendors or resources protected by identity providers / authorization servers. If an application or a resource requires a user to authorize explicitly with an OAuth authorization code flow, AgentCore Identity generates an authorization URL for the user to navigate to and consent access. Then, upon user giving consent, AgentCore Identity fetches the access token from the application or resource on behalf of users, and stores it in the AgentCore Identity Token Vault.

However, since a user may accidentally send the authorization URL to another user and gain access to that user’s application or resource, your application must verify that the user who initiates an authorization request is still the same as the user who has granted consent to the application or resource. To do that, you need to register a publicly available HTTPS application endpoint with AgentCore Identity that handles user verification.

## How session binding works


The following flow diagram and corresponding steps show the OAuth 2.0 authorization URL session binding process:

![\[OAuth 2.0 authorization URL session binding flow diagram\]](http://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/images/identity-session-binding.png)


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.

1.  **Generate authorization URL** – AgentCore Identity generates an authorization URL and session URI for the user to navigate to and consent access.

1.  **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.

1.  **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.

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.

## Implementation details


The following steps walk you through setting up the workload identity, the OAuth 2.0 credential provider, and the OAuth 2.0 application client from the resource provider for retrieving an OAuth 2.0 access token for your agent application.

You can refer to sample code as an example of a working application: [OAuth 2.0 callback server implementation](https://github.com/awslabs/amazon-bedrock-agentcore-samples/blob/main/01-tutorials/03-AgentCore-identity/05-Outbound_Auth_3lo/oauth2_callback_server.py).

**Important**  
When you are using the AgentCore CLI with `agentcore dev` in a local environment, to simplify your local development and testing, the CLI hosts the callback endpoint and calls the `CompleteResourceTokenAuth` API on your behalf to verify the user session to get OAuth 2.0 access tokens so you can skip steps 1, 2 and 4 in the following setup. However, when deploying your agent code to AgentCore Runtime, your web application that connects to the agent runtime must host a publicly accessible HTTPS callback endpoint itself, the callback endpoint must be registered against the workload identity as an `AllowedResourceOAuth2ReturnUrl` by calling `UpdateWorkloadIdentity` using the agent ID provided by AgentCore Runtime, and then call the `CompleteResourceTokenAuth` API after verifying the current user’s browser session to secure your OAuth 2.0 authorization flows.

 **To implement OAuth 2.0 authorization URL session binding** 

1.  **Create an application URL** – For your user-facing browser application, create and host a new URL that is accessible from the user browser and can accept requests from browser redirects. This page should either redirect to an application page that your user can continue with their agent session OR render some basic web page instructing your users to return their currently active agent session. In later parts of the implementation, this page is used for validation of the current user’s active session, so this page should also be able to access and maintain your application user session data.

   As an example, your application may have its users interact with an agent at a primary application page like `https://myagentapp.com/assistant` . You’ll want to expose a new URL like `https://myagentapp.com/callback` that for now will redirect to the primary application page. The actual code logic in your `/callback` endpoint will be updated later when following this guide.

1.  **Update workload identity with application URL** – (Can be skipped if testing locally via AgentCore CLI) Once you have created and hosted an application URL for AgentCore Identity to redirect to, update your workload identity so that the application URL is registered as an `AllowedResourceOauth2ReturnUrl` . Make sure that the IAM credentials used have permissions to call `CreateWorkloadIdentity` or `UpdateWorkloadIdentity` depending on whether you’re creating a new workload identity or updating an existing one.
**Note**  
For workload identities created on your behalf by AgentCore Runtime or Gateway, the workload identity name will correspond to the runtime ID or gateway ID that is issued by the services.

   Sample `UpdateWorkloadIdentity` API call:

   ```
   aws bedrock-agentcore-control update-workload-identity --name GoogleCalendarAgent \
   --allowed-resource-oauth2-return-urls https://myagentapp.com/callback
   ```

1.  **Create OAuth 2.0 credential provider in AgentCore Identity** – To register the OAuth 2.0 credential provider fully, you need permissions to call `CreateOauth2CredentialProvider` and `UpdateOauth2CredentialProvider` . Follow these steps:
   + Call `CreateOauth2CredentialProvider` with placeholders for client ID and client secret.
   + API response will contain an OAuth callback (redirect) URL like: `https://bedrock-agentcore.amazonaws.com/identities/callback/123-456-7890` 

     Record this value as it’s specific for each provider that is created and will be needed later by the OAuth 2.0 resource provider.
   + Go to your resource provider (for example, Google or GitHub) and create an OAuth 2.0 application client. Provide the callback URL issued by the service from the `CreateOauth2CredentialProvider` call to the resource provider as an allowed OAuth 2.0 callback URL.
   + Once the OAuth 2.0 application client has been created, record the client ID and client secret assigned to your app client as you need to update the OAuth 2.0 Credential Provider with these values.
   + Call `UpdateOauth2CredentialProvider` and provide the client ID and client secret provided by the resource provider, replacing the placeholder values that were provided when creating the credential provider.

1.  **Add code handler for calling CompleteResourceTokenAuth** – Once you have created your OAuth 2.0 credential provider, add code and the IAM permissions to call the `CompleteResourceTokenAuth` API in your application URL handler. When calling the `CompleteResourceTokenAuth` API, your application must present the original inbound identity provider OAuth token or `user_id` String that was used to generate the workload access token to represent the user and the agent application involved in the OAuth 2.0 authorization flow. This information should be fetched from the active application session on the user’s browser (typically through a browser cookie or in browser local storage) and should NOT be pulled from any remote session cache.

   Additionally, each authorization URL that gets generated by AgentCore Identity is uniquely identified with its own session URI. This session URI must also be presented alongside the user identifier to bind the session with the intended user.
**Important**  
Prior to your application calling the `CompleteResourceTokenAuth` API, your application must verify that the current user has an active, valid session with your application. By doing so your application can associate the intended user with the Authorization session. Furthermore, if you have a backend service that your application depends on, you can move the code that calls `CompleteResourceTokenAuth` API to your backend, and have your application forward the inbound identity provider OAuth token or `user_id` to your backend.

   Sample application code:

   ```
   def _handle_3lo_callback(self, request: Request) -> JSONResponse:
       session_id = request.query_params.get("session_id")
   
       if not session_id:
           console.print("Missing session_id in OAuth2 3LO callback")
           return JSONResponse(status_code=400, content={"message": "missing session_id query parameter"})
   
       session_details = validate_session_cookies(request.cookies.get('my-application-cookie'))
   
       user_id = None
       if oauth2_config:
           user_id = session_details.get(USER_ID)
   
       if not user_id:
           console.print(f"Missing {USER_ID} in session_details")
           return JSONResponse(status_code=500, content={"message": "Internal Server Error"})
   
       console.print(f"Handling 3LO callback for workload_user_id={user_id} | session_id={session_id}", soft_wrap=True)
   
       region = agent_config.aws.region
       if not region:
           console.print("AWS Region not configured")
           return JSONResponse(status_code=500, content={"message": "Internal Server Error"})
   
       identity_client = IdentityClient(region)
       identity_client.complete_resource_token_auth(
           session_uri=session_id, user_identifier=UserIdIdentifier(user_id=user_id)
       )
   
       return JSONResponse(status_code=200, content={"message": "OAuth2 3LO flow completed successfully"})
   ```

1.  **Test** – Once you have completed the setup, you are ready to test the integration. Start by calling `GetResourceOauth2Token` and in your browser go to the Authorization URL that is returned. After completing the authorization at the OAuth 2.0 resource provider, you should see the browser redirect back to your application URL and invoke the `CompleteResourceTokenAuth` API. Once the application returns a valid response, your agent application will be able to retrieve the OAuth 2.0 access tokens that were originally requested for the user. These tokens can be fetched by calling the `GetResourceOauth2Token` API.

## Additional considerations


When implementing OAuth 2.0 authorization URL session binding, keep the following considerations in mind:
+ Each authorization URL and its corresponding session identifier are only valid for 10 minutes.
+ To secure your application callback endpoint against CSRF attacks, we highly recommend that you generate an opaque state to include in your API call to `GetResourceOAuth2Token` . Your application should be able to parse this value to ensure it’s serving requests that were initiated by your agent application.

# Scope down access to credential providers by workload identity
Scope credential access

You can use IAM policies to control which workload identities have access to specific credential providers. This enables fine-grained access control, ensuring that only authorized agents can retrieve credentials for particular services.

 **Access control mechanisms** 
+  **Workload identity-based restrictions** – Limit credential provider access to specific workload identities
+  **Resource-level permissions** – Control access to individual credential providers using ARN-based policies
+  **Directory-level controls** – Manage access at the workload identity directory level

**Topics**
+ [

## IAM policy examples
](#iam-policy-examples)
+ [

## Implementation steps
](#policy-implementation-steps)

## IAM policy examples


The following examples demonstrate how to create IAM policies that restrict credential provider access based on workload identity:

 **Restrict API key provider access** 

```
{
"Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "GetResourceApiKey",
      "Effect": "Allow",
      "Action": [
        "bedrock-agentcore:GetResourceApiKey"
      ],
      "Resource": [
        "arn:aws:bedrock-agentcore:us-east-1:<account_id>:workload-identity-directory/default",
        "arn:aws:bedrock-agentcore:us-east-1:<account_id>:workload-identity-directory/default/workload-identity/<workload-identity-name>",
        "arn:aws:bedrock-agentcore:us-east-1:<account_id>:token-vault/default"
      ]
    }
  ]
}
```

 **Restrict OAuth2 credential provider access** 

```
{
"Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "GetResourceOauth2Token",
      "Effect": "Allow",
      "Action": [
        "bedrock-agentcore:GetResourceOauth2Token"
      ],
      "Resource": [
        "arn:aws:bedrock-agentcore:us-east-1:<account_id>:workload-identity-directory/default",
        "arn:aws:bedrock-agentcore:us-east-1:<account_id>:workload-identity-directory/default/workload-identity/<workload-identity-name>",
        "arn:aws:bedrock-agentcore:us-east-1:<account_id>:token-vault/default"
      ]
    }
  ]
}
```

 **Allow multiple workload identities access to a credential provider** 

```
{
"Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "GetResourceApiKeyMultipleIdentities",
      "Effect": "Allow",
      "Action": [
        "bedrock-agentcore:GetResourceApiKey"
      ],
      "Resource": [
        "arn:aws:bedrock-agentcore:us-east-1:<account_id>:workload-identity-directory/default",
        "arn:aws:bedrock-agentcore:us-east-1:<account_id>:workload-identity-directory/default/workload-identity/agent-1",
        "arn:aws:bedrock-agentcore:us-east-1:<account_id>:workload-identity-directory/default/workload-identity/agent-2",
        "arn:aws:bedrock-agentcore:us-east-1:<account_id>:workload-identity-directory/default/workload-identity/agent-3",
        "arn:aws:bedrock-agentcore:us-east-1:<account_id>:token-vault/default"
      ]
    }
  ]
}
```

## Implementation steps


To implement workload identity-based access control for credential providers:

1.  **Identify your workload identities** – Use `aws bedrock-agentcore-control list-workload-identities` to list all workload identities in your account. For information about creating and managing workload identities, see [Manage workload identities with AgentCore Identity](identity-manage-agent-ids.md).

1.  **Determine credential provider ARNs** – Identify the specific credential providers you want to control access to

1.  **Create IAM policies** – Write IAM policies that specify which workload identities can access which credential providers

1.  **Attach policies to roles** – Attach the policies to the IAM roles used by your agents or applications

1.  **Test access controls** – Verify that only authorized workload identities can access the specified credential providers

 **Best practices** 
+ Use descriptive names for workload identities to make policy management easier
+ Regularly audit and review access policies to ensure they align with your security requirements
+ Consider using IAM policy conditions for additional access controls based on time, IP address, or other factors
+ Test policies in a development environment before applying them to production workloads

# Obtain API key
Obtain API key

Once you have stored your API keys in the AgentCore Identity vault, you can retrieve them directly in your agent using the AgentCore SDK and the `@requires_api_key` annotation. For example, the code below will retrieve the API key from the “your-service-name” API key provider so that you can use it in the `need_api_key` function.

```
import asyncio
from bedrock_agentcore.identity.auth import requires_api_key

@requires_api_key(
    provider_name= "your-service-name" # replace with your own credential provider name
)
async def need_api_key(*, api_key: str):
    # Use the API key
    pass

# To invoke:
# asyncio.run(need_api_key())
```