feat(bb-agent): server-resolved tool context from verified JWT claims (4/5) - #261
Draft
pjkroker wants to merge 4 commits into
Draft
feat(bb-agent): server-resolved tool context from verified JWT claims (4/5)#261pjkroker wants to merge 4 commits into
pjkroker wants to merge 4 commits into
Conversation
|
pjkroker
force-pushed
the
agentcore/3-docs
branch
from
July 24, 2026 10:19
686ebe2 to
2c4a726
Compare
pjkroker
force-pushed
the
agentcore/4-tool-context
branch
from
July 24, 2026 10:19
6692af5 to
c78c718
Compare
pjkroker
force-pushed
the
agentcore/4-tool-context
branch
from
July 24, 2026 11:14
0d76236 to
e88d50a
Compare
pjkroker
marked this pull request as draft
July 24, 2026 11:15
…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
force-pushed
the
agentcore/3-docs
branch
from
July 24, 2026 12:38
d6030e1 to
58b4919
Compare
pjkroker
force-pushed
the
agentcore/4-tool-context
branch
from
July 24, 2026 12:38
e88d50a to
f47bc07
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
sendMessagemethod, which held the HTTP request and built toolcontext(auth.getCurrentUser()+ DB) before calling the agent. That per-turn app hop is gone, so atoolContextSchemaagent (which requirescontext) could only run on the buffered server-mediated path — not browser-direct, where the transport carries nocontext. PR #251 hardcoded one thing: inject the verified JWTsubascontext.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 toolcontext. Because the runtime's JWT authorizer already validated the token, the claims are trustworthy and unforgeable by the browser. The verifiedsubis always overlaid ascontext.userIdafterward, 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: newresolveToolContext?: (claims) => TContext | Promise<TContext>.agentcore-entry.ts:userIdFromContext→claimsFromContext(full payload) +userIdFromContext; newbuildToolContext(claims, rawContext, resolver)runs the resolver then overlayssub; wired into both/invocationsand/ws.agent.ts:AgentBase.toolContextResolvergetter so the entry handler can read the hook.wsAgentgainstoolContextSchema+resolveToolContext+ awhoamitool, plus an e2e asserting a context-scoped tool runs browser-direct.Scope / boundaries (by design)
sub,username,cognito:groups,scope— notemail/custom:*(ID-token-only; would need a pre-token-generation Lambda, future work).getAgentCoreToken, so no token reaches the container on that path yet.input— not this hook. Matches thetoAgentTools()scope((ctx)=>...)design (Chorus l3Jtq1L2LST6), which only ever usescontextfor identity.toAgentTools/scope— this PR only produces thectxthat scope will later consume.Backward compatibility
sub→userIdinjection).contextpasses through unchanged.suboverrides any resolver- or client-supplieduserId(no spoofing).Tests
101 pass in
packages/bb-agent(+8). NewbuildToolContextcases: resolver builds from claims;suboverrides resolver output and client value; no-token passthrough; async resolver;claimsFromContextdecode. Comprehensive app typechecks; new sandbox e2e for the browser-direct context-scoped turn.Stacked on #252 (
agentcore/3-docs). Rebase ontomainif the migration merges first.