

# Get started with AgentCore Identity
<a name="identity-getting-started"></a>

If you’re building AI agents that need to access external services like Google Drive, Slack, or GitHub, Amazon Bedrock AgentCore Identity provides the secure authentication infrastructure you need. This section offers two practical getting started tutorials that demonstrate how to implement identity features in your agents. Depending on your specific business needs, you can start with a complete end-to-end agent deployment, or focus on OAuth2 integration patterns with Google Drive to understand the core authentication flows.

**Topics**
+ [

## Primary getting started tutorial
](#primary-tutorial)
+ [

## OAuth2 integration getting started tutorial
](#additional-tutorial)
+ [

## Common prerequisites
](#common-prerequisites)
+ [

# Build your first authenticated agent
](identity-getting-started-cognito.md)
+ [

# Integrate with Google Drive using OAuth2
](identity-getting-started-google.md)

## Primary getting started tutorial
<a name="primary-tutorial"></a>

Start here for a complete end-to-end walkthrough of AgentCore Identity features:

 [Build your first authenticated agent](identity-getting-started-cognito.md)   
 **Recommended starting point** for new users  
 **What you’ll build:** A complete working agent with authentication, deployed to AgentCore Runtime  
 **What you’ll learn:** Create Cognito user pools, configure credential providers, deploy agents, set up IAM policies, and test authentication flows  
 **Outcome:** Fully deployed agent that can authenticate users and obtain access tokens

## OAuth2 integration getting started tutorial
<a name="additional-tutorial"></a>

After completing the primary tutorial, explore OAuth2 patterns with external services:

 [Integrate with Google Drive using OAuth2](identity-getting-started-google.md)   
 **Focus:** OAuth2 flows and Google Drive integration  
 **What you’ll learn:** Set up OAuth2 credential providers, obtain access tokens, and integrate with Google services  
 **Best for:** Understanding OAuth2 authentication patterns with real external services

## Common prerequisites
<a name="common-prerequisites"></a>

Both tutorials require the following:
+ An AWS account with appropriate permissions
+ Basic familiarity with Python programming
+ Understanding of OAuth2 concepts (recommended)

Each tutorial includes specific setup instructions and additional prerequisites as needed.

# Build your first authenticated agent
<a name="identity-getting-started-cognito"></a>

This getting started tutorial walks you through building a complete authenticated agent from the ground up using Amazon Bedrock AgentCore Identity and will help you get started with implementing identity features in your agent applications. You’ll learn how to set up your development environment, create authentication infrastructure with Cognito, deploy your agent to AgentCore Runtime, and test the full authentication workflow.

By the end of this tutorial, you’ll have a fully deployed agent that can authenticate users through OAuth2 flows, obtain access tokens securely, and demonstrate the complete identity management lifecycle. Your agent will be running on AgentCore Runtime with proper IAM permissions, creating a test lab environment where you can demonstrate and test the integration capabilities.

**Topics**
+ [

## Prerequisites
](#identity-quick-start-prerequisites)
+ [

## Step 1: Create a Cognito user pool (Optional)
](#identity-quick-start-cognito)
+ [

## Step 2: Create a credential provider
](#identity-quick-start-credential-provider)
+ [

## Step 2.5: Add the callback URL to your OAuth 2.0 authorization server
](#identity-update-credential-provider)
+ [

## Step 3: Create a sample agent that initiates an OAuth 2.0 flow
](#identity-quick-start-agent)
+ [

## Step 4: Deploy the agent to AgentCore Runtime
](#identity-quick-start-deploy)
+ [

## Step 5: Invoke the agent
](#identity-quick-start-invoke)
+ [

## Clean up
](#identity-quick-start-cleanup)
+ [

## Security best practices
](#identity-quick-start-security)

## Prerequisites
<a name="identity-quick-start-prerequisites"></a>

Before you begin, ensure you have:
+ An AWS account with appropriate permissions
+ Python 3.10\$1 installed
+ The latest AWS CLI and `jq` installed
+ Node.js 18\$1 installed (for the AgentCore CLI)
+  AWS credentials and region configured ( `aws configure` )

This tutorial requires that you have an OAuth 2.0 authorization server. If you do not have one, Step 1 will create one for you using Amazon Cognito user pools. If you have an OAuth 2.0 authorization server with a client id, client secret, and a user configured, you may proceed to step 2. This authorization server will act as a resource credential provider, representing the authority that grants the agent an outbound OAuth 2.0 access token.

### Install the SDK and dependencies
<a name="identity-quick-start-install"></a>

Make a folder for this guide, create a Python virtual environment, and install the AgentCore SDK and the AWS Python SDK (boto3).

```
mkdir agentcore-identity-quickstart
cd agentcore-identity-quickstart
python3 -m venv .venv
source .venv/bin/activate
pip install bedrock-agentcore boto3 strands-agents pyjwt
```

Also create the `requirements.txt` file with the following content. This will be used later by the AgentCore deployment tool.

```
bedrock-agentcore
boto3
pyjwt
strands-agents
```

## Step 1: Create a Cognito user pool (Optional)
<a name="identity-quick-start-cognito"></a>

This tutorial requires an OAuth 2.0 authorization server. If you do not have one available for testing, or if you want to keep your test separate from your authorization server, this script will use your AWS credentials to set up an Amazon Cognito instance for you to use as an authorization server. The script will create:
+ A Cognito user pool
+ An OAuth 2.0 client, and client secret for that user pool
+ A test user and password in that Cognito user pool

Deleting the Cognito user pool AgentCoreIdentityQuickStartPool will delete the associated client\$1id and user as well.

You may choose to save this script as create\$1cognito.sh and execute it from your command line, or paste the script into your command line.

```
#!/bin/bash

REGION=$(aws configure get region)

# Create user pool
USER_POOL_ID=$(aws cognito-idp create-user-pool \
  --pool-name AgentCoreIdentityQuickStartPool \
  --query 'UserPool.Id' \
  --no-cli-pager \
  --output text)

# Create user pool domain
DOMAIN_NAME="agentcore-quickstart-$(LC_ALL=C tr -dc 'a-z0-9' < /dev/urandom | head -c 5)"
aws cognito-idp create-user-pool-domain \
  --domain $DOMAIN_NAME \
  --no-cli-pager \
  --user-pool-id $USER_POOL_ID > /dev/null

# Create user pool client with secret and hosted UI settings
CLIENT_RESPONSE=$(aws cognito-idp create-user-pool-client \
  --user-pool-id $USER_POOL_ID \
  --client-name AgentCoreQuickStart \
  --generate-secret \
  --allowed-o-auth-flows "code" \
  --allowed-o-auth-scopes "openid" "profile" "email" \
  --allowed-o-auth-flows-user-pool-client \
  --supported-identity-providers "COGNITO" \
  --query 'UserPoolClient.{ClientId:ClientId,ClientSecret:ClientSecret}' \
  --output json)

CLIENT_ID=$(echo $CLIENT_RESPONSE | jq -r '.ClientId')
CLIENT_SECRET=$(echo $CLIENT_RESPONSE | jq -r '.ClientSecret')

# Generate random username and password
USERNAME="AgentCoreTestUser$(printf "%04d" $((RANDOM % 10000)))"
PASSWORD="$(LC_ALL=C tr -dc 'A-Za-z0-9!@#$%^&*()_+-=[]{}|;:,.<>?' < /dev/urandom | head -c 16)$(LC_ALL=C tr -dc '0-9' < /dev/urandom | head -c 1)"

# Create user with permanent password
aws cognito-idp admin-create-user \
  --user-pool-id $USER_POOL_ID \
  --username $USERNAME \
  --output text > /dev/null

aws cognito-idp admin-set-user-password \
  --user-pool-id $USER_POOL_ID \
  --username $USERNAME \
  --password $PASSWORD \
  --output text > /dev/null \
  --permanent

# Get region

ISSUER_URL="https://cognito-idp.$REGION.amazonaws.com/$USER_POOL_ID/.well-known/openid-configuration"
HOSTED_UI_URL="https://$DOMAIN_NAME.auth.$REGION.amazoncognito.com"

# Output results
echo "User Pool ID: $USER_POOL_ID"
echo "Client ID: $CLIENT_ID"
echo "Client Secret: $CLIENT_SECRET"
echo "Issuer URL: $ISSUER_URL"
echo "Hosted UI URL: $HOSTED_UI_URL"
echo "Test User: $USERNAME"
echo "Test Password: $PASSWORD"

echo ""
echo "# Copy and paste these exports to set environment variables for later use:"
echo "export USER_POOL_ID='$USER_POOL_ID'"
echo "export CLIENT_ID='$CLIENT_ID'"
echo "export CLIENT_SECRET='$CLIENT_SECRET'"
echo "export ISSUER_URL='$ISSUER_URL'"
echo "export HOSTED_UI_URL='$HOSTED_UI_URL'"
echo "export COGNITO_USERNAME='$USERNAME'"
echo "export COGNITO_PASSWORD='$PASSWORD'"
```

## Step 2: Create a credential provider
<a name="identity-quick-start-credential-provider"></a>

Credential providers are how your agent accesses external services. Create a credential provider and configure it with an OAuth 2.0 client for your authorization server.

If you are using your own authorization server, set the environment variables `ISSUER_URL` , `CLIENT_ID` , and `CLIENT_SECRET` with their appropriate values from your authorization server. If you are using the previous script to create an authorization server for you with Cognito, copy the EXPORT statements from the output into your terminal to set the environment variables.

This credential provider will be used by your agent’s code to get access tokens to act on behalf of your user.

**Example**  

1. If you have an AgentCore CLI project, you can add the credential provider using the CLI. The CLI will create the provider during deployment.

   ```
   agentcore add credential \
     --name AgentCoreIdentityQuickStartProvider \
     --type oauth \
     --discovery-url "$ISSUER_URL" \
     --client-id "$CLIENT_ID" \
     --client-secret "$CLIENT_SECRET"
   ```

   The credential provider will be created when you run `agentcore deploy` in Step 4. Note the callback URL from the deploy output.

1. 

   ```
   #!/bin/bash
   # please note the expected ISSUER_URL format for Bedrock AgentCore is the full url, including .well-known/openid-configuration
   OAUTH2_CREDENTIAL_PROVIDER_RESPONSE=$(aws bedrock-agentcore-control create-oauth2-credential-provider \
     --name "AgentCoreIdentityQuickStartProvider" \
     --credential-provider-vendor "CustomOauth2" \
     --oauth2-provider-config-input '{
       "customOauth2ProviderConfig": {
         "oauthDiscovery": {
           "discoveryUrl": "'$ISSUER_URL'"
         },
         "clientId": "'$CLIENT_ID'",
         "clientSecret": "'$CLIENT_SECRET'"
       }
     }' \
     --output json)
   
   OAUTH2_CALLBACK_URL=$(echo $OAUTH2_CREDENTIAL_PROVIDER_RESPONSE | jq -r '.callbackUrl')
   
   echo "OAuth2 Callback URL: $OAUTH2_CALLBACK_URL"
   ```

## Step 2.5: Add the callback URL to your OAuth 2.0 authorization server
<a name="identity-update-credential-provider"></a>

To prevent unauthorized redirects, add the callback URL retrieved from [CreateOauth2CredentialProvider](https://docs.aws.amazon.com/bedrock-agentcore-control/latest/APIReference/API_CreateOauth2CredentialProvider.html) or [GetOauth2CredentialProvider](https://docs.aws.amazon.com/bedrock-agentcore-control/latest/APIReference/API_GetOauth2CredentialProvider.html) to your OAuth 2.0 authorization server.

If you are using the previous script to create an authorization server with Cognito, copy the EXPORT statements from the output into your terminal to set the environment variables and update the Cognito user pool client with the OAuth2 credential provider callback URL.

```
#!/bin/bash
aws cognito-idp update-user-pool-client \
    --user-pool-id $USER_POOL_ID \
    --client-id $CLIENT_ID \
    --client-name AgentCoreQuickStart \
    --allowed-o-auth-flows "code" \
    --allowed-o-auth-scopes "openid" "profile" "email" \
    --allowed-o-auth-flows-user-pool-client \
    --supported-identity-providers "COGNITO" \
    --callback-urls "$OAUTH2_CALLBACK_URL"
```

## Step 3: Create a sample agent that initiates an OAuth 2.0 flow
<a name="identity-quick-start-agent"></a>

In this step, we will create an agent that initiates an OAuth 2.0 authorization flow to get tokens to act on behalf of the user. For simplicity, the agent will not make actual calls to external services on behalf of a user, but will prove to us that it has obtained consent to act on behalf of our test user.

### Agent code
<a name="identity-quick-start-agent-code"></a>

Create a file named `agentcoreidentityquickstart.py` , and save this code.

```
"""
AgentCore Identity Outbound Token Agent

This agent demonstrates the USER_FEDERATION OAuth 2.0 flow.

It handles the OAuth 2.0 user consent flow and inspects the resulting OAuth 2.0 access token.
"""

from bedrock_agentcore.runtime import BedrockAgentCoreApp
from bedrock_agentcore.identity import requires_access_token
import asyncio
import jwt
import logging

app = BedrockAgentCoreApp()

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def decode_jwt(token):
    try:
        decoded = jwt.decode(token, options={"verify_signature": False})
        return decoded
    except Exception as e:
        return {"error": f"Error decoding JWT: {str(e)}"}

class StreamingQueue:
    def __init__(self):
        self.finished = False
        self.queue = asyncio.Queue()

    async def put(self, item):
        await self.queue.put(item)

    async def finish(self):
        self.finished = True
        await self.queue.put(None)

    async def stream(self):
        while True:
            item = await self.queue.get()
            if item is None and self.finished:
                break
            yield item

queue = StreamingQueue()

async def handle_auth_url(url):
    await queue.put(f"Authorization URL, please copy to your preferred browser: {url}")

@requires_access_token(
    provider_name="AgentCoreIdentityQuickStartProvider",
    scopes=["openid"],
    auth_flow="USER_FEDERATION",
    on_auth_url=handle_auth_url, # streams authorization URL to client
    force_authentication=True,
    callback_url='insert_oauth2_callback_url_for_session_binding',
)
async def introspect_with_decorator(*, access_token: str):
    """Introspect token using decorator"""
    logger.info("Inside introspect_with_decorator - decorator succeeded")
    await queue.put({
        "message": "Successfully received an access token to act on behalf of your user!",
        "token_claims": decode_jwt(access_token),
        "token_length": len(access_token),
        "token_preview": f"{access_token[:50]}...{access_token[-10:]}"
    })
    await queue.finish()

@app.entrypoint
async def agent_invocation(payload, context):
    """Handler that uses only the decorator approach"""
    logger.info("Agent invocation started")

    # Start the agent task and immediately begin streaming
    task = asyncio.create_task(introspect_with_decorator())

    # Stream items as they come in
    async for item in queue.stream():
        yield item

    # Wait for task completion
    await task

if __name__ == "__main__":
    app.run()
```

**Note**  
For a sample local callback server implementation to handle [session binding](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/oauth2-authorization-url-session-binding.html) , refer to [oauth2\$1callback\$1server.py](https://github.com/awslabs/amazon-bedrock-agentcore-samples/blob/main/01-tutorials/03-AgentCore-identity/05-Outbound_Auth_3lo/oauth2_callback_server.py) 

## Step 4: Deploy the agent to AgentCore Runtime
<a name="identity-quick-start-deploy"></a>

We will host this agent on AgentCore Runtime. We can do this easily with the AgentCore CLI.

From your terminal, install the AgentCore CLI and create a new project:

```
npm install -g @aws/agentcore
agentcore create --name IdentityQuickstart --defaults
```

Copy your agent script into the project’s agent directory, replacing the default agent:

```
cp agentcoreidentityquickstart.py IdentityQuickstart/app/IdentityQuickstart/main.py
```

Also copy your requirements file into the agent directory to ensure all dependencies are included in the deployment:

```
cp requirements.txt IdentityQuickstart/app/IdentityQuickstart/
```

Then deploy your project:

```
cd IdentityQuickstart
agentcore deploy
```

The CLI synthesizes a AWS CDK stack and deploys your agent to AgentCore Runtime. This takes approximately 2–3 minutes.

### Update the IAM policy of the agent to be able to access the token vault, and client secret
<a name="identity-quick-start-iam-policy"></a>

The AgentCore CLI creates the agent’s execution role during deployment, but the role does not automatically include permissions for token vault access. You need to attach an additional policy to allow the agent to retrieve OAuth 2.0 tokens at runtime.

This script retrieves your account and region from the AWS CLI, finds the agent’s execution role from the CloudFormation stack, and attaches the appropriate policy. You can copy and paste this script, or save it to a file and execute it.

```
#!/bin/bash

# Get account and region from AWS CLI
AWS_ACCOUNT=$(aws sts get-caller-identity --query Account --output text)
REGION=$(aws configure get region)

# Get execution role from CloudFormation stack outputs
EXECUTION_ROLE=$(aws cloudformation describe-stack-resources \
  --stack-name AgentCore-IdentityQuickstart-prod \
  --query "StackResources[?ResourceType=='AWS::IAM::Role'].PhysicalResourceId" \
  --output text | head -1)

echo "Parsed values:"
echo "Execution Role: $EXECUTION_ROLE"
echo "Account: $AWS_ACCOUNT"
echo "Region: $REGION"

# Create the policy document with proper variable substitution
cat > agentcore-identity-policy.json << EOF
{
"Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "AccessTokenVault",
      "Effect": "Allow",
      "Action": [
        "bedrock-agentcore:GetResourceOauth2Token",
        "secretsmanager:GetSecretValue"
      ],
      "Resource": ["arn:aws:bedrock-agentcore:$REGION:$AWS_ACCOUNT:workload-identity-directory/default/workload-identity/*",
        "arn:aws:bedrock-agentcore:$REGION:$AWS_ACCOUNT:token-vault/default/oauth2credentialprovider/AgentCoreIdentityQuickStartProvider",
        "arn:aws:bedrock-agentcore:$REGION:$AWS_ACCOUNT:workload-identity-directory/default",
        "arn:aws:bedrock-agentcore:$REGION:$AWS_ACCOUNT:token-vault/default",
        "arn:aws:secretsmanager:$REGION:$AWS_ACCOUNT:secret:bedrock-agentcore-identity!default/oauth2/AgentCoreIdentityQuickStartProvider*"
      ]
    }
  ]
}
EOF

# Create the policy
POLICY_ARN=$(aws iam create-policy \
    --policy-name AgentCoreIdentityQuickStartPolicy$(LC_ALL=C tr -dc '0-9' < /dev/urandom | head -c 4) \
    --policy-document file://agentcore-identity-policy.json \
    --query 'Policy.Arn' \
    --output text)

# Extract role name from ARN and attach policy
ROLE_NAME=$(echo $EXECUTION_ROLE | awk -F'/' '{print $NF}')
aws iam attach-role-policy \
    --role-name $ROLE_NAME \
    --policy-arn $POLICY_ARN

echo "Policy created and attached: $POLICY_ARN"

# Cleanup
rm agentcore-identity-policy.json
```

## Step 5: Invoke the agent
<a name="identity-quick-start-invoke"></a>

Now that this is all set up, you can invoke the agent. For this demo, we will use the `agentcore invoke` command and our IAM credentials. We will need to pass the `--user-id` and `--session-id` arguments when using IAM authentication.

```
agentcore invoke "TestPayload" --runtime IdentityQuickstart --user-id "SampleUserID" --session-id "ALongThirtyThreeCharacterMinimumSessionIdYouCanChangeThisAsYouNeed"
```

The agent will then return a URL to your `agentcore invoke` command. Copy and paste that URL into your preferred browser, and you will then be redirected to your authorization server’s login page. The `--user-id` parameter is the user ID you are presenting to AgentCore Identity. The `--session-id` parameter is the session ID, which must be at least 33 characters long.

Enter the username and password for your user on your authorization server when prompted on your browser, or use your preferred authentication method you have configured. If you used the script from Step 1 to create a Cognito instance, you can retrieve this from your terminal history.

Your browser should redirect to your configured OAuth2 callback URL, which handles the [session binding flow](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/oauth2-authorization-url-session-binding.html) . Ensure your OAuth2 callback server provides clear success and error responses to indicate the authorization status.

**Note**  
If you interrupt an invocation without completing authorization, you may need to request a new URL using a new session ID ( `--session-id` parameter).

### Debugging
<a name="identity-quick-start-debugging"></a>

Should you encounter any errors or unexpected behaviors, the output of the agent is captured in Amazon CloudWatch logs. A log tailing command is provided after you run `agentcore deploy`.

## Clean up
<a name="identity-quick-start-cleanup"></a>

After you’re done, run `agentcore remove all` and then `agentcore deploy` from your project directory to tear down the deployed AgentCore Runtime resources. Then delete the Amazon Cognito user pool, detach and delete the IAM policy you created, and delete the credential provider.

## Security best practices
<a name="identity-quick-start-security"></a>

When working with identity information:

1.  **Never hardcode credentials** in your agent code

1.  **Use environment variables or Amazon SageMaker AI** for sensitive information

1.  **Apply least privilege principle** when configuring IAM permissions

1.  **Regularly rotate credentials** for external services

1.  **Audit access logs** to monitor agent activity

1.  **Implement proper error handling** for authentication failures

# Integrate with Google Drive using OAuth2
<a name="identity-getting-started-google"></a>

This getting started tutorial walks you through the essential steps to start using Amazon Bedrock AgentCore Identity for your AI agents. You’ll learn how to set up your development environment, install the necessary SDKs, create your first agent identity, and allow your agent to access external resources securely.

By the end of this tutorial, you’ll have a working agent that can retrieve access tokens from Google with AgentCore Identity OAuth2 Credential Provider, and read files from Google Drive using access tokens. For detailed information about OAuth2 flows, see [Manage credential providers with AgentCore Identity](identity-outbound-credential-provider.md).

**Topics**
+ [

## Prerequisites
](#identity-getting-started-prerequisites)
+ [

## Step 1: Set up an OAuth 2.0 Credential Provider
](#identity-getting-started-step1)
+ [

## Step 2: Import Identity and Auth modules
](#identity-getting-started-step2)
+ [

## Step 3: Obtain an OAuth 2.0 access token
](#identity-getting-started-step3)
+ [

## Step 4: Use OAuth2 Access Token to Invoke External Resource
](#identity-getting-started-step4)
+ [

## What’s Next?
](#identity-getting-started-whats-next)

## Prerequisites
<a name="identity-getting-started-prerequisites"></a>

Before you start, you need:
+ An AWS account with appropriate permissions (for example, `BedrockAgentCoreFullAccess` )
+ Python 3.10 or higher
+ The latest AWS CLI and `jq` installed
+  AWS credentials and region configured ( `aws configure` )
+ Basic understanding of Python programming

### Install the SDK
<a name="identity-getting-started-install-sdk"></a>

To get started, install the `bedrock-agentcore` package:

```
pip install bedrock-agentcore
```

### Obtain Google Client ID and Client Secret
<a name="identity-getting-started-google-credentials"></a>

To allow your agent to access Google Drive, you need to obtain a Google client ID and client secret for your agent. Go to the [Google Developer Console](https://console.developers.google.com/project) and follow these steps:

1. Create a Project in Google Developer Console

1. Enable Google Drive API

1. Configure OAuth consent screen

1. Create a new web application for the agent, for example, "My Agent 1"

1. Add the following OAuth 2.0 scope to your agent application: `https://www.googleapis.com/auth/drive.metadata.readonly` 

1. Create OAuth 2.0 Credentials for the new web application, and save the generated Google client ID and client secret

## Step 1: Set up an OAuth 2.0 Credential Provider
<a name="identity-getting-started-step1"></a>

Create a new OAuth 2.0 Credential Provider with the Google client ID and client secret obtained earlier using the following AWS CLI command:

```
OAUTH2_CREDENTIAL_PROVIDER_RESPONSE=$(aws bedrock-agentcore-control create-oauth2-credential-provider \
  --region us-east-1 \
  --name "google-provider" \
  --credential-provider-vendor "GoogleOauth2" \
  --oauth2-provider-config-input '{
      "googleOauth2ProviderConfig": {
        "clientId": "<your-google-client-id>",
        "clientSecret": "<your-google-client-secret>"
      }
    }' \
--output json)

OAUTH2_CALLBACK_URL=$(echo $OAUTH2_CREDENTIAL_PROVIDER_RESPONSE | jq -r '.callbackUrl')

echo "OAuth2 Callback URL: $OAUTH2_CALLBACK_URL"
```

**Note**  
Obtain the `callbackUrl` from the [CreateOauth2CredentialProvider](https://docs.aws.amazon.com/bedrock-agentcore-control/latest/APIReference/API_CreateOauth2CredentialProvider.html) response above and add the URI to your Google application’s redirect URI list. The callback URL should look like: https://bedrock-agentcore.us-east-1.amazonaws.com/identities/oauth2/callback/\$1\$1\$1\$1\$1\$1\$1\$1-\$1\$1\$1\$1-\$1\$1\$1\$1-\$1\$1\$1\$1-\$1\$1\$1\$1\$1\$1\$1\$1\$1\$1\$1\$1

## Step 2: Import Identity and Auth modules
<a name="identity-getting-started-step2"></a>

Add this import statement to your Python file:

```
from bedrock_agentcore.services.identity import IdentityClient
from bedrock_agentcore.identity.auth import requires_access_token, requires_api_key
```

## Step 3: Obtain an OAuth 2.0 access token
<a name="identity-getting-started-step3"></a>

Once you have the Google Credential Provider created in the previous step, add the `@requires_access_token` decorator to your agent code that requires a Google access token. Copy the authorization URL from your console output, then paste it in your browser and complete the consent flow with Google Drive.

The following code sample is intended to be integrated into your agent code to invoke an authorization workflow. This is not standalone code that can be copied and run independently.

```
import asyncio

# 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,
    # The callback URL to redirect to after the OAuth 2.0 token retrieval is complete
    callback_url='oauth2_callback_url_for_session_binding',
)
async def write_to_google_drive(*, access_token: str):
    # Prints the access token obtained from Google
    print(access_token)

asyncio.run(write_to_google_drive(access_token=""))
```

Behind the scenes, the `@requires_access_token` decorator runs through the following sequence:

![\[Flow diagram showing the sequence of API calls made by the @requires_access_token decorator\]](http://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/images/identity_access_token_flow.png)


1. The SDK makes API calls to `CreateWorkloadIdentity` , `GetWorkloadAccessToken` , and `GetResourceOauth2Token`.

1. When running the agent code locally, the SDK automatically generates an agent identity ID and a random user ID for local testing, and stores them in a local file called `.bedrock_agentcore.yaml`.

1. When running the agent code with AgentCore Runtime, the SDK does not generate an agent identity ID or random user ID. Instead, it uses the agent identity ID assigned, and the user ID or JWT token passed in by the agent caller.

1. Agent access token is an encrypted (opaque) token that contains the agent identity ID and user ID.

1. AgentCore Identity service stores the Google access token in the Token Vault under the agent identity ID and user ID. This creates a binding among the agent identity, user identity, and the Google access token.

1. The [session binding flow](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/oauth2-authorization-url-session-binding.html) must be completed before the Google access token is returned to the caller by AgentCore Identity.

## Step 4: Use OAuth2 Access Token to Invoke External Resource
<a name="identity-getting-started-step4"></a>

Once the agent obtains a Google access token with the steps above, it can use the access token to access Google Drive. Here is a full example that lists the names and IDs of the first 10 files that the user has access to.

First, install the Google client library for Python:

```
pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
```

Then, copy the following code:

```
import asyncio
from bedrock_agentcore.identity.auth import requires_access_token, requires_api_key
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

SCOPES = ["https://www.googleapis.com/auth/drive.metadata.readonly"]

def main(access_token):
    """Shows basic usage of the Drive v3 API.

    Prints the names and ids of the first 10 files the user has access to.
    """
    creds = Credentials(token=access_token, scopes=SCOPES)

    try:
        service = build("drive", "v3", credentials=creds)

        # Call the Drive v3 API
        results = (
            service.files()
            .list(pageSize=10, fields="nextPageToken, files(id, name)")
            .execute()
        )
        items = results.get("files", [])

        if not items:
            print("No files found.")
            return

        print("Files:")
        for item in items:
            print(f"{item['name']} ({item['id']})")

    except HttpError as error:
        # TODO(developer) - Handle errors from drive API.
        print(f"An error occurred: {error}")

if __name__ == "__main__":
    # This annotation helps agent developer to obtain access tokens from external applications
    @requires_access_token(
        provider_name="google-provider",
        # Google OAuth2 scopes
        scopes=["https://www.googleapis.com/auth/drive.metadata.readonly"],
        # 3LO flow
        auth_flow="USER_FEDERATION",
        # prints authorization URL to console
        on_auth_url=lambda x: print("Copy and paste this authorization url to your browser", x),
        force_authentication=True,
        callback_url='oauth2_callback_url_for_session_binding',
    )
    async def read_from_google_drive(*, access_token: str):
        print(access_token)  # You can see the access_token
        # Make API calls...
        main(access_token)

    asyncio.run(read_from_google_drive(access_token=""))
```

**Note**  
For a sample local callback server implementation to handle [session binding](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/oauth2-authorization-url-session-binding.html) , refer to [https://github.com/awslabs/amazon-bedrock-agentcore-samples/blob/main/01-tutorials/03-AgentCore-identity/05-Outbound_Auth_3lo/oauth2_callback_server.py](https://github.com/awslabs/amazon-bedrock-agentcore-samples/blob/main/01-tutorials/03-AgentCore-identity/05-Outbound_Auth_3lo/oauth2_callback_server.py) 

## What’s Next?
<a name="identity-getting-started-whats-next"></a>

The example in this section focuses on practical implementation patterns that you can adapt for your specific use cases. You can embed the code as part of an agent, or a Model Context Protocol (MCP) tool. If you want to host your Agent code or MCP Tool with AgentCore Runtime, follow [Host agent or tools with Amazon Bedrock AgentCore Runtime](agents-tools-runtime.md) to copy the code above to AgentCore Runtime.