Repository navigation
feat: support keyless PKCE public clients - #495
Conversation
…KEY is unset
Build the client with new WorkOS({ apiKey, clientId, ...options }) and treat
an empty WORKOS_API_KEY as absent, so the SDK runs as a PKCE public client
instead of carrying an empty-string key. Key-only features (getOrganizationAction,
validateApiKey, getFeatureFlagsRuntimeClient) now fail before any network call
with an error naming WORKOS_API_KEY.
|
⚓ Shipyard review suggestionSuggested team: authkit, based on recent contributors to the changed files (@m0tzy, @stanleyphu, @imkesin).
Links open Shipyard for confirmation. Choosing a reviewer overrides availability; “Pick for me” skips known absences. Shipyard Analysis⏳ Generating analysis... ⚓ Explore the analysis in depth in Shipyard · 🔄 Re-run analysis |
|
⚓ No verified eligible reviewer. Authors and previous assignees are excluded. |
Let @workos-inc/authkit-nextjs run as a keyless PKCE public client, bringing the experience shipped in workos/authkit-react-router#96 (workos/authkit-react-router#96, "feat: support keyless PKCE public clients", merged Oct 6) to Next.js. A Next.js app that only signs users in should work with WORKOS_CLIENT_ID, NEXT_PUBLIC_WORKOS_REDIRECT_URI (or the package's redirect setting) and WORKOS_COOKIE_PASSWORD and no WORKOS_API_KEY.
Read #96's diff first (
gh pr diff 96 --repo workos/authkit-react-router) and mirror its design and rigor, adapted to authkit-nextjs's env-variable-driven config:Construct the client keyless.
src/workos.tsbuildsnew WorkOS(WORKOS_API_KEY, options)with an empty-string fallback. Construct it asnew WorkOS({ apiKey, clientId, ...options }), omittingapiKeywhen unset, so workos-node 8.x's keyless mode applies (authenticateWithCodewith a codeVerifier andauthenticateWithRefreshTokenomit client_secret when there's no key). Check the @workos-inc/node peer range supports it and raise the minimum if needed.Model the config as a union where the package exposes config types (authkitMiddleware/handleAuth options, any
configure-style API), so TypeScript makes clear which features need a key. Discriminate the way Sign-in callback returns SyntaxError: Unexpected token 'e" is not valid JSON #96 did if it fits. Where config is purely env-driven at runtime, do the closest sound version and explain the trade-off in the hand-back.Clear errors for key-only features. Anything that needs a key must fail with a clear, actionable error naming WORKOS_API_KEY, not an opaque 401. At least:
organizations.getOrganizationinsrc/actions.tsapiKeys.createValidationinsrc/validate-api-key.tsfeatureFlags.createRuntimeClientinsrc/feature-flags.tsfetchClaimNoncepath insrc/get-authorization-url.tsif it needs a keyAudit every
getWorkOS()use and list which need a key.README: a public-client (keyless) section saying when to use it and what's unavailable without a key.
Unit tests:
authkit-callback-route.ts) and both refresh paths (session.ts) sending no client_secret in public mode (assert the request bodies)Then prove it end to end in the repo's example (
examples/next): copy it to a scratch directory outside the repo and point it at this branch's packed build (pnpm pack, then a file: or overrides dependency in the copy only). Run it with no WORKOS_API_KEY, and show that the sign-in route redirects to the AuthKit authorization URL withcode_challengeandcode_challenge_method=S256. Leave the dev server running and give Nick the URL and exact steps to sign in and see the session load and a refresh succeed. If a refresh can be shown without his login (e.g. a debug log line in the demo copy only), add it to the demo copy, not the library.Riker's check
pnpm install --frozen-lockfile >/dev/null && pnpm typecheck && pnpm lint && pnpm format:check && pnpm test && pnpm buildpassed.Opened as a draft by Riker (job 97).