AMAZON BEDROCK / SERVICE DETAIL S05 IDENTITY
AGENTCORE IDENTITYPRACTICAL
CHAPTER 14 / 36
TOPIC store a login, get a token in one line
REV 2026.07
IN PLAIN WORDS
You will store a login for an outside service in a secure vault, then let your agent fetch a token for it with one line, without ever handling the raw secret. Terms: credential provider = a stored connection to a service's login; vault = the locked store; 2LO = the agent logs in as itself (no user); 3LO = the user approves once (user-delegated); scope = the exact permission asked for (for example, read-only Drive).
Concept first: see chapter 13 "Identity". Definitions: chapter 02 "Key terms".
[ 1 ] STORE A LOGIN (create a credential provider, once)
# an OAuth login for a service (shape is from the docs; name and URL are yours)
$ aws bedrock-agentcore-control create-oauth2-credential-provider \
--cli-input-json '{
"name": "google-provider",
"credentialProviderVendor": "CustomOauth2",
"oauth2ProviderConfigInput": {
"customOauth2ProviderConfig": {
"oauthDiscovery": {"discoveryUrl": "https://accounts.google.com/.well-known/openid-configuration"},
"clientId": "your-client-id",
"clientSecret": "your-client-secret",
"clientAuthenticationMethod": "CLIENT_SECRET_BASIC"
}
}
}'
# or, for a plain API key, from your AgentCore project:
$ agentcore add credential --name MyApiKey --type api-key --api-key your-api-key
[ 2 ] GET A USER TOKEN (3LO, the user approves once)
import asyncio
from bedrock_agentcore.identity.auth import requires_access_token
@requires_access_token(
provider_name="google-provider", # the provider you created
scopes=["https://www.googleapis.com/auth/drive.metadata.readonly"],
auth_flow="USER_FEDERATION", # 3LO: ask the user
on_auth_url=lambda url: print("Approve here:\n" + url),
force_authentication=False, # reuse a valid token
)
async def read_drive(*, access_token: str):
... # use access_token to call Google Drive
asyncio.run(read_drive())
WHAT HAPPENS
The first time, the agent shows the user a link to approve. After that, a stored refresh token (about 30 days) gets new tokens silently, so the user is not asked again. The access_token arrives as a function argument; your code never sees the password behind it.
[ 3 ] GET A MACHINE TOKEN (2LO) AND AN API KEY
# 2LO: the agent logs in as itself, no user
@requires_access_token(
provider_name="my-service-provider",
scopes=[],
auth_flow="M2M",
)
async def call_service(*, access_token: str):
... # use access_token
asyncio.run(call_service())
# an API key, fetched the same easy way
from bedrock_agentcore.identity.auth import requires_api_key
@requires_api_key(
provider_name="your-service-name",
)
async def call_with_key(*, api_key: str):
... # use api_key
asyncio.run(call_with_key())
A token can be revoked on the provider's side, which AgentCore cannot see. If a call fails, set force_authentication=True to force a fresh login. Runtime gives a hosted agent its workload token automatically; agents elsewhere fetch it with the AgentCore SDK.