Skip to content

feat(gateway): add custom claims validation and TUI wizard for JWT auth#599

Merged
tejaskash merged 7 commits into
aws:mainfrom
aidandaly24:feat/custom-claims-wizard
Mar 24, 2026
Merged

feat(gateway): add custom claims validation and TUI wizard for JWT auth#599
tejaskash merged 7 commits into
aws:mainfrom
aidandaly24:feat/custom-claims-wizard

Conversation

@aidandaly24

@aidandaly24 aidandaly24 commented Mar 23, 2026

Copy link
Copy Markdown
Contributor

Description

Adds custom JWT claims validation and a full TUI wizard flow for configuring Custom JWT gateway authorization.

Stacked PR: This PR includes changes from #598 (inbound auth hardening). Merge #598 first, then rebase this onto main — the diff will shrink to only the custom claims feature.

TUI Wizard Screenshots

1. Authorizer Type Selection
Authorizer Selection

2. JWT Constraint Picker
Constraint Picker

3. Constraints Selected (Allowed Clients + Custom Claims)
Constraints Selected

4. Custom Claims Form
Custom Claims Form

Custom Claims Schema

  • ClaimMatchOperatorSchema — operators: Equals, StartsWith, Contains, NotEquals
  • ClaimMatchValueSchema — string value with 1-256 char limit
  • InboundTokenClaimValueTypeSchemaString, Number, Boolean, Array
  • CustomClaimValidationSchema — strict object with claimName, operator, matchValue, valueType
  • Wired into CustomJwtAuthorizerConfigSchema as optional customClaims array
  • Added to deployed-state.ts for deployment state tracking

CLI Support

  • Added --custom-claims flag accepting JSON array (e.g., --custom-claims '[{"claimName":"dept","operator":"Equals","matchValue":"engineering","valueType":"String"}]')
  • Validation: JSON parse, array check, per-claim field validation
  • GatewayPrimitive passes custom claims through to authorizer configuration

TUI Wizard

  • Expanded JWT config flow with custom claims manager:
    • Add claim sub-flow: claim name → operator → match value → value type
    • Edit/delete existing claims
    • Done to proceed
  • Client credentials made optional (skip with empty Enter)
  • Human-readable claim summary in confirm review screen
  • Step counter updated dynamically

Testing (comprehensive)

  • AddGatewayJwtConfig.test.tsx — TUI component tests covering the full JWT wizard flow
  • finishJwtConfig.test.ts — unit tests for config assembly helper
  • useAddGatewayWizard.test.tsx — extended with JWT + custom claims wizard flows
  • GatewayPrimitive.test.ts — custom claims round-trip through primitive
  • validate.test.ts — custom claims CLI validation cases
  • mcp.test.ts — schema-level custom claims tests
  • add-gateway-jwt.test.ts — TUI integration test via harness

Related Issue

Extracted from #596 (replaces it together with #597 and #598)

Documentation PR

N/A

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Other (please describe):

Testing

How have you tested the change?

  • I ran npm run test:unit and npm run test:integ
  • I ran npm run typecheck
  • I ran npm run lint
  • If I modified src/assets/, I ran npm run test:update-snapshots and committed the updated snapshots

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the
terms of your choice.

@aidandaly24 aidandaly24 requested a review from a team March 23, 2026 03:11
@github-actions github-actions Bot added the size/xl PR size: XL label Mar 23, 2026
@github-actions github-actions Bot added size/xl PR size: XL and removed size/xl PR size: XL labels Mar 23, 2026
@aidandaly24 aidandaly24 changed the base branch from main to fix/inbound-auth-hardening March 23, 2026 03:48
@aidandaly24 aidandaly24 force-pushed the feat/custom-claims-wizard branch 2 times, most recently from 077b557 to af1ddac Compare March 23, 2026 19:49
@tejaskash

tejaskash commented Mar 23, 2026

Copy link
Copy Markdown
Contributor

Code review

Found 2 issues:

  1. createManagedOAuthCredential only writes CLIENT_SECRET to .env, but the current main branch (from PR feat: add policy engine and policy support #579) writes both CLIENT_ID and CLIENT_SECRET. When this PR lands, the CLIENT_ID env var will be lost, causing runtime failures for managed OAuth credentials.

// Write client secret to .env
const envVarName = computeDefaultCredentialEnvVarName(credentialName);
await setEnvVar(envVarName, jwtConfig.clientSecret!);
}

  1. Inline dynamic import in a React component violates AGENTS.md ("Never use inline imports. Imports must always go at the top of the file."). Should be a top-level static import.

// policyEngineId is needed; get it from deployed state
const { policyEnginePrimitive } = await import('../../../primitives/registry');
const policyEngineId = await policyEnginePrimitive.getDeployedEngineId(wizard.config.engine);

tejaskash
tejaskash previously approved these changes Mar 23, 2026

@tejaskash tejaskash left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review comments addressed: CLIENT_ID env var restored, inline import moved to top-level.

@tejaskash tejaskash changed the base branch from fix/inbound-auth-hardening to main March 23, 2026 20:15
@tejaskash tejaskash dismissed their stale review March 23, 2026 20:15

The base branch was changed.

@aidandaly24 aidandaly24 force-pushed the feat/custom-claims-wizard branch from d932c77 to 1cf5cdb Compare March 23, 2026 20:19
@github-actions github-actions Bot added size/xl PR size: XL and removed size/xl PR size: XL labels Mar 23, 2026
@aidandaly24 aidandaly24 force-pushed the feat/custom-claims-wizard branch from 1cf5cdb to 7b62c1a Compare March 23, 2026 20:23
@github-actions github-actions Bot added size/xl PR size: XL and removed size/xl PR size: XL labels Mar 23, 2026
@aidandaly24 aidandaly24 force-pushed the feat/custom-claims-wizard branch from 7b62c1a to 0e288c9 Compare March 23, 2026 20:30
@github-actions github-actions Bot added size/xl PR size: XL and removed size/xl PR size: XL labels Mar 23, 2026
@aidandaly24 aidandaly24 force-pushed the feat/custom-claims-wizard branch from 0e288c9 to 25ead06 Compare March 23, 2026 20:34
@github-actions github-actions Bot added size/xl PR size: XL and removed size/xl PR size: XL labels Mar 23, 2026
@aidandaly24 aidandaly24 force-pushed the feat/custom-claims-wizard branch from 25ead06 to 6a43e44 Compare March 24, 2026 15:11
@github-actions github-actions Bot added size/xl PR size: XL and removed size/xl PR size: XL labels Mar 24, 2026
@aidandaly24 aidandaly24 force-pushed the feat/custom-claims-wizard branch from 6a43e44 to 78221f7 Compare March 24, 2026 16:13
@github-actions github-actions Bot added size/xl PR size: XL and removed size/xl PR size: XL labels Mar 24, 2026
Add custom JWT claims validation support and a full TUI wizard flow
for configuring Custom JWT gateway authorization.

Schema:
- Add ClaimMatchOperator, ClaimMatchValue, InboundTokenClaimValueType,
  and CustomClaimValidation schemas with strict validation
- Add customClaims to CustomJwtAuthorizerConfigSchema and deployed-state
- Add --custom-claims CLI flag with JSON parsing and validation

TUI Wizard:
- Expand JWT config flow with custom claims manager (add/edit/done)
- Add claim name, operator, value, and value type sub-steps
- Show human-readable claim summary in confirm review
- Make client credentials optional (skip with empty Enter)

Testing:
- Add AddGatewayJwtConfig.test.tsx — full TUI component tests
- Add finishJwtConfig.test.ts — unit tests for config assembly
- Extend useAddGatewayWizard.test.tsx with JWT + custom claims flows
- Add GatewayPrimitive.test.ts for custom claims round-trip
- Extend validate.test.ts with custom claims validation cases
- Add TUI integration test (add-gateway-jwt.test.ts)

Constraint: Stacked on fix/inbound-auth-hardening (aws#598)
Confidence: high
Scope-risk: moderate
Enter now advances to the next field instead of immediately submitting,
and up/down arrow keys navigate between fields for a more intuitive form
experience.
When a text field is empty, the cursor now appears before the placeholder
hint instead of after it, matching expected input behavior.
The test expected Enter to immediately submit and show a validation error,
but Enter now advances to the next field. Updated the test to press Enter
through all fields before expecting the submission validation error.
Restore writing both CLIENT_ID and CLIENT_SECRET to .env in
createManagedOAuthCredential, matching main branch behavior.
Move dynamic import of policyEnginePrimitive to a static top-level
import per AGENTS.md conventions.
Run prettier on 3 files and add missing existingPolicyEngines
prop to AddGatewayJwtConfig test defaults.
@tejaskash tejaskash merged commit b1c8a50 into aws:main Mar 24, 2026
17 of 23 checks passed
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