Obtain OAuth 2.0 access token - Amazon Bedrock AgentCore

Amazon Bedrock AgentCore is in preview release and is subject to change.

Obtain OAuth 2.0 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 Getting started with Amazon Bedrock AgentCore Identity 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,)async def write_to_google_drive(*, access_token: str):     # Use the token to call Google Drive asyncio.run(write_to_google_drive(access_token= ""))

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 asyncio.run(need_token_2LO_async(access_token= ""))

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, ) 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, ) 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, ) 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.