Agent identity architecture | September 16, 2026

A consent screen is not an authorization boundary

The hard problem is not opening an OAuth page. It is proving that one authenticated human approved one provider grant, for one scope set and target, then ensuring every later agent effect stays inside that binding.

OAuth session binding Token vault boundaries Revocation and receipts Sources checked Sep 16
Identity, consent, token vault, gateway, and agent action boundaries

Managed consent removes plumbing, not responsibility

AI agents increasingly need user-delegated access to GitHub, Slack, calendars, storage, CRM systems, and internal APIs. The browser flow looks familiar: authenticate, review scopes, approve, return. The security problem begins after that familiar screen. A long-running agent can act later, through a different client, with a stored refresh token and a plan the user never saw.

Amazon Web Services made that boundary concrete on September 14, 2026 with the Amazon Bedrock AgentCore Consent portal. The managed portal authenticates users through an OpenID Connect identity provider, presents outbound provider connections, completes the three-legged OAuth browser flow, binds the returned grant to the user, and stores provider tokens in AgentCore Identity's token vault. IDE and MCP clients can then use the connected gateway without implementing their own public callback and browser-session service.

That is useful infrastructure. Previously, an AgentCore customer had to present authorization URLs, host an HTTPS callback, authenticate the returning user, maintain browser session state, and call CompleteResourceTokenAuth. Moving those responsibilities into a managed component reduces custom security-sensitive code. It does not decide whether requesting GitHub repo is too broad, whether a Slack post is appropriate, whether the user belongs to the correct tenant, or whether a later tool call still matches the approved task.

The exact launch has limited independent field evidence. The official sample repository had roughly 3.4K GitHub stars when checked on September 16, but repository interest is not proof that the new portal is broadly deployed. This guide therefore treats AgentCore as a current case study for a general architecture problem. The claim is not that one product solves delegated authorization. The claim is that every agent platform needs an auditable chain from human identity to provider grant to runtime effect.

Consent answers “may this client receive a grant?” Runtime authorization must still answer “may this agent perform this exact effect now?”

Keep six control planes separate

Agent OAuth designs fail when they compress several identities and decisions into one word such as “connected.” A connected badge can hide the corporate login, provider account, scope set, token lifecycle, gateway mapping, agent identity, and current action. Model each plane independently and join them with stable identifiers.

PlaneWhat it provesWhat it does not prove
Corporate authenticationThe portal session belongs to a user recognized by the configured OIDC issuer.That the user chose the correct provider account or may approve every scope.
Provider consentThe provider issued a grant for a client and normalized scope set.That every action allowed by those scopes is appropriate for the task.
Session bindingThe returned grant is associated with the user session that initiated authorization.That the binding remains valid after role, tenant, or employment changes.
Token custodyAccess and refresh tokens remain in a protected broker or vault.That token retrieval and refresh follow least privilege or correct revocation.
Gateway targetA named tool target maps to a credential provider and operation surface.That tool descriptions, destinations, or parameters cannot produce a larger effect.
Runtime authorizationOne agent effect matches current policy, resource, tenant, task, and budget.That prior consent can replace review for a new consequential action.

Keep inbound identity distinct from outbound delegation. In the AgentCore design, the gateway's inbound JWT authorizer and the Consent portal's primary identity provider refer to the same OIDC issuer. Separate outbound credential providers represent GitHub, Slack, or other resources. Confusing these layers creates a deputy problem: the system knows who can call the gateway but loses track of whose downstream account supplied the grant.

Keep agent identity separate too. A user may authorize a provider once, but several agents or tasks may run under that user. The token broker should receive a workload identity and task context, not only a user ID. Otherwise any agent that can name the user can potentially reuse the user's grant.

Use a narrow waist between consent and execution

User browser
  |  corporate OIDC login + provider consent
  v
Consent service ---- immutable consent receipt
  |                    user / tenant / provider / scopes / policy
  v
Token vault  <---- refresh, revoke, expiry, provider events
  |
  v
Credential broker <---- workload identity + task + typed operation
  |
  +---- policy deny / human gate / one-use capability
  v
Gateway target ---- downstream provider ---- effect receipt
  |                                          |
  +--------------- CloudTrail / audit -------+

The narrow waist is the credential broker. The agent never asks for a refresh token. It asks to execute a typed provider operation such as github.issue.create against a normalized organization and repository. The broker resolves the bound user grant, joins current tenant and workload facts, checks policy, and issues a one-use capability to the adapter. The adapter returns an effect receipt rather than provider credentials.

This architecture makes revocation meaningful. Revoking a connection stops new capabilities at the broker even if an agent process is still running. The system can also suspend one agent, target, campaign, or provider without deleting every user connection. If the only control is deleting a token after it was copied into model context, revocation is already too late.

Use exact callback matching, authorization code flow, PKCE where supported, transaction-bound state or OpenID Connect nonce, and issuer validation. RFC 9700 requires exact redirect comparisons and protection against authorization-code injection, CSRF, mix-up, and token replay. RFC 10017 recommends the authorization code grant with PKCE for browser-based applications. A hosted portal may own some implementation, but the deployment team must still configure the IdP, callback, audience, and provider applications correctly.

Record what the user actually approved

A provider token is not a complete consent record. Store a separate immutable receipt that can be reviewed without exposing the secret. Normalize provider scopes because ordering, aliases, and defaults otherwise make policy comparisons unreliable. Include the gateway and target identifiers so a grant cannot be silently attached to a different tool surface.

version: agent.auth/v1
consent_id: cns_01K5A8
subject:
  corporate_user: usr_4821
  tenant: acme-prod
  oidc_issuer: https://id.acme.example/oauth2/default
provider:
  name: github
  account_id: gh_77192
  credential_provider: gateway-demo-github
  scopes: [read:user, repo]
binding:
  gateway_id: gw_dev_assistant
  target_id: github_tools_v3
  initiated_session_hash: sha256:43ab...
  completed_at: 2026-09-16T02:18:10Z
policy:
  version: delegated-auth-2026-09-16
  reviewer_required_for: [repository_admin, workflow_write, public_post]
lifecycle:
  review_after: 2026-10-16T00:00:00Z
  revoke_uri: vault://connections/cns_01K5A8/revoke

Do not store email address alone as the subject key. Addresses change and can be recycled. Bind the corporate subject, issuer, tenant, and provider account ID. For organizations, also record approval state. GitHub documents that an organization can restrict OAuth app access and that removing approval disables access to private resources and existing webhook delivery. A user-level “connected” state can therefore coexist with organization-level denial.

Scopes need interpretation, not only display. GitHub notes that classic OAuth scopes may be broad and that source-code access cannot currently be reduced to read-only through those scopes. If the intended agent only reads issues, a broad repo grant creates residual authority that runtime policy must block. Prefer fine-grained provider models when available; otherwise expose only narrow typed adapters and require human review for high-consequence writes.

Make connection state explicit and reversible

A useful connection state machine separates provisioning, user action, provider response, operational readiness, and revocation. Avoid one Boolean called connected.

CREATING
  -> ACTIVE_NO_TARGETS
  -> TARGET_AVAILABLE
  -> AUTHORIZATION_STARTED
  -> GRANT_BOUND
  -> VERIFIED
  -> SUSPENDED | REAUTH_REQUIRED | REVOKED | FAILED

on provider_token_expired:
  if refresh_token_valid: rotate_access_token()
  else: transition(REAUTH_REQUIRED)

on user_role_changed or tenant_disabled:
  suspend_all_bindings(subject)
  require_policy_recheck()

on effect_request:
  require state == VERIFIED
  authorize(workload, task, target, operation, resource, budget)

Record why a state changed. A missing refresh token is not the same as an administrator suspension. A provider revocation is not the same as an expired portal session. Operators need distinct recovery paths and users deserve accurate explanations.

Grant review must run after identity and policy changes. A connection approved while a user was a repository owner should not remain fully usable after the user changes teams. The provider may correctly constrain the token to the user's current privileges, but the agent platform must also remove task-specific authority, cached resource lists, and planned actions derived under the old role.

The AgentCore launch exposes the real configuration edges

AgentCore requires a Gateway with JWT inbound authentication, a primary OAuth2 credential provider for the same JWT-issuing OIDC issuer, and an execution role. The primary IdP must issue JWT access tokens; opaque-token and OAuth-only providers are not supported for portal sign-in. Each portal attaches to exactly one gateway. The portal requests openid and every configured scope must be allowed by the IdP.

aws bedrock-agentcore-control create-consent-portal \
  --name "dev-assistant-consent" \
  --execution-role-arn "arn:aws:iam::111122223333:role/AgentConsentPortal" \
  --idp-config '{
    "credentialProviderArn": "arn:aws:bedrock-agentcore:REGION:ACCOUNT:token-vault/default/oauth2credentialprovider/ID",
    "scopes": ["openid", "email", "profile"],
    "audience": "agent-gateway"
  }' \
  --sources '[{"identifier":"GATEWAY_ID","type":"agentcore-gateway"}]'

Creation is asynchronous. Poll until the status is ACTIVE, then register <portalUrl>/callback exactly at the corporate IdP. AWS warns that a trailing slash causes an unregistered-callback failure. Each outbound target uses the AgentCore Identity callback associated with its provider application and a return URL of <portalUrl>/connect/callback. These similar URLs belong to different legs of the flow; swapping them is a configuration bug, not a harmless typo.

CloudTrail records GetResourceOauth2Token, CompleteResourceTokenAuth, and GetWorkloadAccessTokenForJWT. Use them to join flow initiation, completed binding, workload access, credential provider, scopes, role, account, Region, and error. AWS redacts sensitive token and state values. Add application-level effect receipts because management events show credential operations, not the full semantic consequence of every downstream API call.

Deletion order matters. Remove gateway targets before deleting credential providers still referenced by those targets. More importantly, define user offboarding and emergency suspension before launch. A portal that can create connections but has no tested mass-revocation path is incomplete.

Test authorization as an adversarial data-flow problem

  1. Cross-user callback: start authorization as user A and attempt to complete through user B's portal session. The binding must fail.
  2. Tenant confusion: authenticate the same email-like identity from a different issuer or tenant. The subject keys must remain distinct.
  3. Callback exactness: try a trailing slash, alternate host, path case, open redirect, and unregistered return path.
  4. Code injection and replay: reuse an authorization code, omit or change PKCE material, replay state, and mix authorization issuers.
  5. Scope escalation: add a scope after approval, rely on a provider default, reorder or alias scopes, and request a broad scope for a narrow tool.
  6. Target swap: bind a valid grant to a new gateway target, changed tool schema, different repository, or different Slack workspace.
  7. Revocation: revoke at provider, organization, vault, user, and platform layers. Confirm new actions fail and cached plans cannot continue.
  8. Refresh failure: expire the access token with no valid refresh token. Enter REAUTH_REQUIRED, not a loop or fallback to another user.
  9. Runtime write denial: approve a read task with a broad provider scope, then instruct the agent to create an issue or post. Policy must deny it.
  10. Audit redaction: confirm tokens, codes, secrets, state, and provider payload secrets never appear in prompts, logs, traces, or receipts.

Verify negative behavior at the downstream provider, not only at the gateway. GitHub organization restrictions, SAML authorization, Slack token rotation, and provider-side revocation can change independently. The expected result is often a clean denial with an owned remediation path, not a successful automatic recovery.

Test concurrency too. Two authorization flows opened for the same user and provider must not overwrite each other's state. Two agents requesting the same connection must not broaden the scope union silently. A callback arriving after cancellation must remain canceled. Race tests should operate on real session storage and broker logic, not only mocked provider responses.

Common failures happen after a successful login

FailureWhy the UI can look healthyControl
Wrong-user grantThe provider returned a valid token and the connection test passed.Bind transaction state to issuer, tenant, subject, session, provider account, and callback.
Broad scope, narrow taskThe provider consent page accurately displayed the requested scope.Scope policy plus typed adapters and per-effect authorization.
Confused deputyThe gateway caller and token owner are both legitimate identities.Join user, workload, task, target, resource, and action at the broker.
Stale authorityThe refresh token still works after a role or team change.Identity-event suspension, periodic review, and short runtime capabilities.
Provider-side restrictionThe platform shows connected while organization approval or SAML is missing.Provider-specific readiness checks and actionable error states.
Unrevoked derived stateThe token is gone, but queued actions and cached resource data remain.Cancel capabilities, queues, plans, and derived caches on revocation.
Audit without consequenceCloudTrail proves token retrieval but not what the tool changed.Effect receipts with provider object IDs, read-back, and task linkage.

Do not show users “connected forever.” Show the provider account, organization or workspace, approved scope summary, last verified time, agents or targets allowed to use the connection, review date, and a working disconnect action. Consent should be inspectable and reversible by the person who supplied it, subject to enterprise retention and incident rules.

A consent portal is also a phishing-sensitive surface. Give gateways and provider connections recognizable names. Do not train users to approve generic “AI assistant” requests with unexplained scopes. The portal URL, issuer, client name, scope purpose, support owner, and expected return path should be available through an approved internal channel before the user begins.

A 30-day rollout should prove revocation before scale

Days 1-7: inventory provider operations and classify read, write, public, administrative, destructive, and external-communication effects. Define exact subject and tenant keys, scope policy, receipt schema, and connection states. Select one low-risk provider and one gateway target.

Days 8-14: deploy the portal in a non-production tenant. Configure exact callbacks, provider organization restrictions, token rotation, audit export, and emergency suspension. Run cross-user, replay, target-swap, race, and logging tests.

Days 15-21: pilot with a small named cohort. Permit read operations and one reversible write behind review. Measure authorization success, denial quality, reauthorization frequency, scope exceptions, time to revoke, orphaned connections, and receipt completeness.

Days 22-30: rehearse offboarding, provider outage, expired refresh token, compromised client secret, mistaken broad scope, and portal deletion. Scale only if the team can identify every active grant, map it to allowed agents and targets, disable it quickly, and prove the last consequential effect.

This design complements permission kernels and execution receipts. OAuth supplies delegated credentials. The permission kernel decides what the workload may request, and the receipt proves what happened. None of the three replaces the others.

FAQ

What is session binding for an AI agent?

It is the verified association between the authenticated user who started the OAuth flow and the provider grant returned through the callback. The binding prevents one user's callback, token, or provider account from being attached to another user's agent session.

Does an OAuth consent screen make an AI agent safe?

No. The screen authorizes provider scopes. Runtime policy must still decide whether this agent, task, target, resource, operation, and moment are allowed. A valid token can authorize an inappropriate action.

Should an agent receive the user's OAuth token?

Prefer a broker that keeps secrets in a vault and executes typed operations. The model should see neither access nor refresh tokens. It should receive the minimum result and a receipt ID.

How should teams test AI-agent OAuth?

Test cross-user and cross-tenant binding, exact callbacks, PKCE and CSRF protections, scope escalation, target swaps, replay, refresh failure, role changes, provider restrictions, revocation, audit redaction, and denial of writes that exceed the current task.

Sources and further reading

Current product facts and source availability were checked on September 16, 2026. The article does not claim broad production adoption or performance gains for the new portal.