Skip to content

feat: runtime inbound auth (Custom JWT) for agents#657

Open
tejaskash wants to merge 28 commits intomainfrom
refactor/shared-auth-modules
Open

feat: runtime inbound auth (Custom JWT) for agents#657
tejaskash wants to merge 28 commits intomainfrom
refactor/shared-auth-modules

Conversation

@tejaskash
Copy link
Contributor

Summary

Adds Custom JWT Authorizer support for Runtime/Agent resources, bringing feature parity with the existing gateway JWT auth. This enables OIDC-based token validation for inbound requests to AgentCore Runtime agents.

Schema and shared infrastructure:

  • Extract shared auth schemas, JWT config components, validation logic, and credential utilities from gateway-specific code into reusable modules
  • Add authorizerType and authorizerConfiguration to AgentEnvSpec

CLI and TUI agent paths:

  • Wire inbound auth to agentcore add agent CLI flags (--authorizer-type, --discovery-url, --allowed-clients, etc.)
  • Add auth type selection step to all TUI agent flows (generate wizard, BYO, import) behind the advanced config gate
  • Create managed OAuth credential ({name}-oauth) when client credentials are provided

Bearer token invoke:

  • Thin HTTP client (invokeWithBearerToken) bypasses SigV4 when a JWT is provided
  • --bearer-token CLI flag and dedicated token screen in TUI with auto-populate from OAuth credentials
  • Auto-fetch via OIDC discovery + client_credentials grant, with silent skip when no credentials are configured

Fetch access for agents:

  • Extend agentcore fetch access to support agents (--type agent) alongside gateways
  • TUI fetch access screen lists both gateways and agents with resource type labels
  • AWS_IAM agents show auth guidance; CUSTOM_JWT agents fetch tokens directly

Test plan

  • Unit tests pass (npx vitest run --exclude 'e2e-tests/**' --exclude 'integ-tests/**')
  • agentcore add agent --authorizer-type CUSTOM_JWT --discovery-url <url> --allowed-clients <id> creates agent with auth config
  • agentcore invoke --bearer-token <token> sends JWT via Authorization header
  • TUI invoke auto-fetches token for CUSTOM_JWT agents with configured OAuth credentials
  • TUI invoke shows token input screen for CUSTOM_JWT agents without credentials
  • agentcore fetch access --type agent --name <name> fetches token for CUSTOM_JWT agents
  • TUI fetch access lists both gateways and agents

@tejaskash tejaskash requested a review from a team March 25, 2026 22:43
@github-actions github-actions bot added the size/xl PR size: XL label Mar 25, 2026
@github-actions github-actions bot added size/xl PR size: XL and removed size/xl PR size: XL labels Mar 25, 2026
@tejaskash tejaskash changed the title feat: Runtime inbound auth (Custom JWT) for agents feat: runtime inbound auth (Custom JWT) for agents Mar 25, 2026
Hweinstock and others added 14 commits March 25, 2026 18:52
Move JWT authorizer schemas (GatewayAuthorizerTypeSchema,
CustomJwtAuthorizerConfigSchema, etc.) from mcp.ts into a dedicated
auth.ts module. Add RuntimeAuthorizerTypeSchema (AWS_IAM | CUSTOM_JWT)
for Runtime resources. The resource-agnostic AuthorizerConfigSchema
replaces GatewayAuthorizerConfigSchema (kept as deprecated alias).
Move JWT authorizer TUI components from AddGatewayScreen into
src/cli/tui/components/jwt-config/:
- types.ts: shared types and constants
- CustomClaimForm.tsx: single claim tab-field form
- CustomClaimsManager.tsx: CRUD for custom claims
- JwtConfigInput.tsx: main JWT config component
- useJwtConfigFlow.ts: hook for JWT wizard state management

AddGatewayScreen now uses the shared useJwtConfigFlow hook and
JwtConfigInput component.
…tive

Extract buildAuthorizerConfigFromJwtConfig and createManagedOAuthCredential
into auth-utils.ts so they can be reused by AgentPrimitive for Runtime
inbound auth. GatewayPrimitive now imports these shared functions instead
of defining them as private methods.
Extract JWT validation logic from validateAddGatewayOptions into a
reusable validateJwtAuthorizerOptions function in auth-options.ts.
This enables reuse by the agent command for Runtime inbound auth.
…EnvSpec

Add Runtime inbound auth fields to the agent schema. Supports AWS_IAM
(default) and CUSTOM_JWT authorizer types with cross-field validation
ensuring authorizerConfiguration is required for CUSTOM_JWT.
Add authorizerType selection and JWT config flow to the BYO agent
creation wizard. Users can choose between AWS_IAM (default) and
CUSTOM_JWT with full OIDC configuration including discovery URL,
audience/client/scope constraints, and custom claims.
Add --authorizer-type, --discovery-url, --allowed-audience, --allowed-clients,
--allowed-scopes, --custom-claims, --client-id, and --client-secret CLI flags
to `agentcore add agent`. Wire auth options through to the BYO path for
authorizer configuration building and OAuth credential auto-creation.

Add validation for agent auth options reusing shared validateJwtAuthorizerOptions.
The TUI BYO path silently discarded OAuth client credentials when
CUSTOM_JWT was selected. Now calls createManagedOAuthCredential to
persist the credential and write secrets to .env, matching the CLI path.
Tests adding BYO agents with CUSTOM_JWT authorizer via CLI, including:
- Audience constraints, client/scope constraints, custom claims
- OAuth credential auto-creation with .env secrets
- Default AWS_IAM behavior
- Validation of missing discovery URL, missing constraints, misplaced client credentials
Add authorizerType and jwtConfig steps to the GenerateWizard (create/template
path) and import path, matching existing BYO path support. Auth config is
persisted to agentcore.json via schema-mapper. OAuth credential is auto-created
for CUSTOM_JWT in all three paths.

Also fix request header allowlist TextInput to allow empty submission (skip),
and add E2E test for BYO custom JWT auth flow with real Cognito.
The create command's useCreateFlow.ts duplicates agent creation logic
from useAddAgent.ts but was missing authorizerType/jwtConfig in the
GenerateConfig, import params, and OAuth credential creation for all
three sub-paths (create, import, BYO).
Add thin HTTP invoke client that bypasses SigV4 when a bearer token is
provided, supporting agents configured with CUSTOM_JWT authorizers.

- Add --bearer-token CLI flag to invoke command
- Add bearer token input to invoke TUI (auto-prompts for CUSTOM_JWT agents,
  press T to set/change token in chat mode)
- Build invokeWithBearerToken and invokeWithBearerTokenStreaming HTTP clients
  with SSE parsing matching the SDK streaming pattern
- Wire bearerToken through InvokeOptions, useInvokeFlow, and InvokeScreen
- Expose authorizerType in invoke flow config for agent auth detection
Being handled separately by another agent.
Extract shared OAuth client_credentials flow from fetchGatewayToken into
oauth-token.ts (fetchOAuthToken), then add fetchRuntimeToken for agents.

TUI: auto-fetches token on agent selection for CUSTOM_JWT agents. Shows
fetch status in header (fetching/fetched/error). Press R to refresh, T
for manual entry. Falls back to manual input on fetch failure.

CLI: auto-fetches token when --bearer-token is not provided and agent
has CUSTOM_JWT auth. Surfaces clear error with manual fallback hint.
…exists

Add canFetchRuntimeToken pre-check that verifies the managed OAuth
credential and client secret exist before attempting the fetch. When
credentials aren't configured, the TUI shows the manual token prompt
(T key) without an error, and the CLI proceeds without a token.
Plain T/R conflict with typing those characters in chat mode.
Instead of Ctrl+T/Ctrl+R shortcuts in chat mode (which conflict with
terminal input), show a dedicated bearer token screen before chat when
a CUSTOM_JWT agent is selected. The screen auto-populates with a
fetched token if OAuth credentials are configured, otherwise shows an
empty field for the user to paste into. Enter confirms, Esc skips.
Add --type flag to agentcore fetch access (gateway | agent). When
--type agent is used, performs OAuth client_credentials flow for the
agent's CUSTOM_JWT credential instead of a gateway.

Usage: agentcore fetch access --type agent --name MyAgent [--json]
…ents

The TUI fetch access screen previously only listed gateways. Now it loads
both gateways and agents, shows the resource type in the picker, and
dispatches to the correct token fetcher based on resource type.
For agents, use canFetchRuntimeToken pre-check before attempting token
fetch. AWS_IAM agents show auth guidance without fetching. CUSTOM_JWT
agents without managed credentials show a message instead of erroring.
Auth type selection (CUSTOM_JWT vs AWS_IAM) now only appears when the
user selects advanced config in the generate wizard and BYO agent paths.
Skipping advanced goes directly to confirm with default AWS_IAM auth.

Also fixes 4 lint errors: unused import, optional chain preferences,
and unsafe argument type cast.
…cess

The canFetchRuntimeToken pre-check swallows all errors and returns false,
which incorrectly showed "no managed OAuth credential" even when one was
configured. For the fetch access screen (explicit user action), call
fetchRuntimeToken directly and let real errors surface in the error phase.
The pre-check remains in the invoke flow where silent skip is desired.
The write path stores secrets as AGENTCORE_CREDENTIAL_{NAME}_CLIENT_SECRET
but the read path was looking for AGENTCORE_CREDENTIAL_{NAME} without the
suffix, causing token fetch to always fail with "Client secret not found".
@tejaskash tejaskash force-pushed the refactor/shared-auth-modules branch from 7d37805 to 1151b72 Compare March 25, 2026 22:58
@github-actions github-actions bot added size/xl PR size: XL and removed size/xl PR size: XL labels Mar 25, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 25, 2026

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 44.72% 5977 / 13364
🔵 Statements 44.32% 6350 / 14325
🔵 Functions 44.06% 1117 / 2535
🔵 Branches 44.79% 3924 / 8759
Generated in workflow #1328 for commit 7bb2f73 by the Vitest Coverage Report Action

The e2e test for BYO custom JWT imports this SDK but it wasn't in package.json,
causing typecheck to fail in CI.
@github-actions github-actions bot added size/xl PR size: XL and removed size/xl PR size: XL labels Mar 25, 2026
@github-actions github-actions bot added size/xl PR size: XL and removed size/xl PR size: XL labels Mar 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/xl PR size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants