Skip to content

Support authorization check in Consumer authenticateJwtLocal#155

Draft
jlai-stytch wants to merge 4 commits into
mainfrom
jlai/support_authz_check_local
Draft

Support authorization check in Consumer authenticateJwtLocal#155
jlai-stytch wants to merge 4 commits into
mainfrom
jlai/support_authz_check_local

Conversation

@jlai-stytch

@jlai-stytch jlai-stytch commented Jul 17, 2026

Copy link
Copy Markdown

Description

Adds support for the authorizationCheck param for the Consumer (B2C) authenticateJwtLocal() method. Currently only the B2B method supports it:

authorizationCheck: AuthorizationCheck? = null,

but not the B2C one:

Since the RBAC helper in this repo only exists for B2B today, this PR also generalizes the existing PolicyCache. It extracts a consumer-flavored authorization check that skips the tenancy check and org-policy merge, operating only on the global policy's roles.

I tried to keep the implementation in line with Node SDK's shared-base + thin-wrapper structure, since that SDK supports the authZ check for both B2C and B2B.

Since this touches some codegen'd files and not just the manual/hand-written methods, this also requires a small PR there: https://github.com/stytchauth/sdk-codegen/pull/388

None of the B2B-specific files were modified.

New files

  • common/BasePolicyCache.kt — shared base holding the cache/refresh machinery (getPolicy, lazy + background refresh, cancelBackgroundRefresh), a normalized RoleView/PermissionView, the shared hasRolePermission matcher, and PermissionException (moved here, retyped to Any so it works for both verticals' AuthorizationCheck)
  • common/ConsumerPolicyCache.kt — thin B2C wrapper over the consumer RBAC client. No org policy, no tenancy check — evaluates purely against the project policy's roles
  • common/ConsumerPolicyCacheTest.kt — consumer analogue of the B2B tests (matching resource/action, wildcard, permission denied, fetch-once/caching, cancel)

Modified files

  • common/PolicyCache.kt — B2B cache keeps its name (so zero B2B call-site churn) but now extends BasePolicyCache<Policy>; retains org-policy cache + TenancyException, and maps its roles into the shared matcher
  • consumer/api/sessions/Sessions.kt — added authorizationCheck: AuthorizationCheck? = null (before leeway) to all three authenticateJwtLocal overloads; the suspend impl throws MissingRolesClaim if roles are absent, else calls policyCache.performAuthorizationCheck; SessionsImpl gained a policyCache constructor param; imports + ADDIMPORT hints added
  • consumer/StytchClient.kt — constructs ConsumerPolicyCache, injects it into SessionsImpl, cancels it in close(). Pass policyCache to IDPImpl.
  • consumer/api/sessions/SessionsTest.kt — passes a relaxed policyCache mock to the updated constructor
  • consumer/api/idp/IDP.kt — added policyCache: ConsumerPolicyCache param + import

Motivation

Contracted customer feature request, see https://twilio-engineering.atlassian.net/browse/STDS-347

Testing

  • Added unit tests
  • Manually tested passing in authZ check in local JWT validation

@jlai-stytch
jlai-stytch requested a review from a team as a code owner July 17, 2026 00:57
@jlai-stytch
jlai-stytch requested review from logan-twilio and removed request for a team July 17, 2026 00:57
@jlai-stytch
jlai-stytch marked this pull request as draft July 17, 2026 00:57
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