Skip to content

feat(bb-agent): server-resolved tool context from verified JWT claims (4/5) - #261

Draft
pjkroker wants to merge 4 commits into
agentcore/3-docsfrom
agentcore/4-tool-context
Draft

feat(bb-agent): server-resolved tool context from verified JWT claims (4/5)#261
pjkroker wants to merge 4 commits into
agentcore/3-docsfrom
agentcore/4-tool-context

Conversation

@pjkroker

Copy link
Copy Markdown
Contributor

Problem

Browser-direct WebSocket streaming (PRs #250#252) lets the browser stream straight to the AgentCore Runtime, bypassing the app's API Gateway → Lambda. In the old Lambda world, every turn ran through the app's sendMessage method, which held the HTTP request and built tool context (auth.getCurrentUser() + DB) before calling the agent. That per-turn app hop is gone, so a toolContextSchema agent (which requires context) could only run on the buffered server-mediated path — not browser-direct, where the transport carries no context. PR #251 hardcoded one thing: inject the verified JWT sub as context.userId.

Change

Add an optional AgentConfig.resolveToolContext(claims) hook. It runs in the AgentCore container each turn against the gateway-verified JWT claims and returns the tool context. Because the runtime's JWT authorizer already validated the token, the claims are trustworthy and unforgeable by the browser. The verified sub is always overlaid as context.userId afterward, so identity stays authoritative.

This is an in-process hook (the container already co-bundles and runs the app backend) — no network callback, no API URL, no IAM execute-api, no 30s cap.

  • types.ts: new resolveToolContext?: (claims) => TContext | Promise<TContext>.
  • agentcore-entry.ts: userIdFromContextclaimsFromContext (full payload) + userIdFromContext; new buildToolContext(claims, rawContext, resolver) runs the resolver then overlays sub; wired into both /invocations and /ws.
  • agent.ts: AgentBase.toolContextResolver getter so the entry handler can read the hook.
  • Reference app: wsAgent gains toolContextSchema + resolveToolContext + a whoami tool, plus an e2e asserting a context-scoped tool runs browser-direct.
  • Docs: README "Server-resolved tool context" subsection + DESIGN.md identity section.

Scope / boundaries (by design)

  • Access-token claims only. For AuthCognito the runtime gets the access token: sub, username, cognito:groups, scopenot email/custom:* (ID-token-only; would need a pre-token-generation Lambda, future work).
  • Cognito-only today — OIDC has no getAgentCoreToken, so no token reaches the container on that path yet.
  • Identity/scoping context only. Non-identity, request-varying data belongs in the tool handler (also runs in the container) or as model input — not this hook. Matches the toAgentTools() scope((ctx)=>...) design (Chorus l3Jtq1L2LST6), which only ever uses context for identity.
  • Does not build toAgentTools/scope — this PR only produces the ctx that scope will later consume.

Backward compatibility

Tests

101 pass in packages/bb-agent (+8). New buildToolContext cases: resolver builds from claims; sub overrides resolver output and client value; no-token passthrough; async resolver; claimsFromContext decode. Comprehensive app typechecks; new sandbox e2e for the browser-direct context-scoped turn.

Stacked on #252 (agentcore/3-docs). Rebase onto main if the migration merges first.

@pjkroker
pjkroker requested a review from a team as a code owner July 24, 2026 10:00
@changeset-bot

changeset-bot Bot commented Jul 24, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: f47bc07

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@pjkroker
pjkroker force-pushed the agentcore/4-tool-context branch from 6692af5 to c78c718 Compare July 24, 2026 10:19
@pjkroker
pjkroker force-pushed the agentcore/4-tool-context branch from 0d76236 to e88d50a Compare July 24, 2026 11:14
@pjkroker
pjkroker marked this pull request as draft July 24, 2026 11:15
pjkroker added 4 commits July 24, 2026 14:38
…laims

Browser-direct streaming bypasses the app's Lambda, so there's no per-turn
hop to build tool context. Add an optional AgentConfig.resolveToolContext(claims)
hook that runs in the AgentCore container each turn against the gateway-verified
JWT claims and returns tool context (e.g. a role from cognito:groups). The
verified sub is always overlaid as context.userId afterward, so identity stays
authoritative and unspoofable.

- generalize userIdFromContext → claimsFromContext (full decoded payload)
- buildToolContext(claims, rawContext, resolver): runs resolver then overlays sub
- no resolver → identical to prior sub→userId injection; no token → passthrough
- expose AgentBase.toolContextResolver getter for the entry handler

Access-token claims only (sub/username/cognito:groups/scope); Cognito-only today.
Give the WS agent a toolContextSchema + resolveToolContext((claims) => ({
userId: sub })) and a whoami tool, plus an e2e asserting a context-scoped
tool runs browser-direct without an Invalid-tool-context error.
…text)

README: add a 'Server-resolved tool context' subsection + update Example 2 to
point at it; document the available access-token claims, Cognito-only scope, and
that non-identity dynamic data belongs in the tool handler. DESIGN.md: extend the
identity section to describe buildToolContext + the resolver hook. Regenerate API.md
for the new AgentConfig.resolveToolContext field.
Now that resolveToolContext ships, Example 2's context-scoped agent can run
browser-direct end to end. Show it self-contained: import + construct the auth
BB, set auth + resolveToolContext on the agent so context.userId comes from the
verified sub, and note db is the app's data layer. Nest the 'Server-resolved
tool context' subsection under Example 2 (#### not ###) so it doesn't read as a
third example.
@pjkroker
pjkroker force-pushed the agentcore/4-tool-context branch from e88d50a to f47bc07 Compare July 24, 2026 12:38
@pjkroker pjkroker changed the title feat(bb-agent): server-resolved tool context from verified JWT claims (4/4) feat(bb-agent): server-resolved tool context from verified JWT claims (4/5) Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant