AgentStack
SKILL verified MIT Self-run

Convex Workos

skill-polarcoding85-convex-agent-skillz-convex-workos-skill · by PolarCoding85

WorkOS AuthKit authentication integration for Convex. Use when setting up WorkOS AuthKit, configuring ConvexProviderWithAuthKit, handling auto-provisioning, or troubleshooting WorkOS-specific auth issues.

No reviews yet
0 installs
10 views
0.0% view→install

Install

$ agentstack add skill-polarcoding85-convex-agent-skillz-convex-workos-skill

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Convex Workos? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Convex + WorkOS AuthKit

Provider-specific patterns for integrating WorkOS AuthKit with Convex.

Required Configuration

1. auth.config.ts

// convex/auth.config.ts
const clientId = process.env.WORKOS_CLIENT_ID;

export default {
  providers: [
    {
      type: 'customJwt',
      issuer: 'https://api.workos.com/',
      algorithm: 'RS256',
      applicationID: clientId,
      jwks: `https://api.workos.com/sso/jwks/${clientId}`
    },
    {
      type: 'customJwt',
      issuer: `https://api.workos.com/user_management/${clientId}`,
      algorithm: 'RS256',
      jwks: `https://api.workos.com/sso/jwks/${clientId}`
    }
  ]
};

Note: WorkOS requires TWO provider entries for different JWT issuers.

2. Environment Variables

# .env.local (Vite/React)
VITE_WORKOS_CLIENT_ID=client_01...
VITE_WORKOS_REDIRECT_URI=http://localhost:5173/callback

# .env.local (Next.js)
WORKOS_CLIENT_ID=client_01...
WORKOS_API_KEY=sk_test_...
WORKOS_COOKIE_PASSWORD=your_32_char_minimum_password_here
NEXT_PUBLIC_WORKOS_REDIRECT_URI=http://localhost:3000/callback

# Convex Dashboard Environment Variables
WORKOS_CLIENT_ID=client_01...

Client Setup

React (Vite)

// src/main.tsx
import { AuthKitProvider, useAuth } from "@workos-inc/authkit-react";
import { ConvexProviderWithAuthKit } from "@convex-dev/workos";
import { ConvexReactClient } from "convex/react";

const convex = new ConvexReactClient(import.meta.env.VITE_CONVEX_URL);

ReactDOM.createRoot(document.getElementById("root")!).render(
  
    
      
    
  
);

Install: npm install @workos-inc/authkit-react @convex-dev/workos

Next.js App Router

// components/ConvexClientProvider.tsx
'use client';

import { ReactNode, useCallback, useRef } from 'react';
import { ConvexReactClient, ConvexProviderWithAuth } from 'convex/react';
import { AuthKitProvider, useAuth, useAccessToken } from '@workos-inc/authkit-nextjs/components';

const convex = new ConvexReactClient(process.env.NEXT_PUBLIC_CONVEX_URL!);

export function ConvexClientProvider({ children }: { children: ReactNode }) {
  return (
    
      
        {children}
      
    
  );
}

function useAuthFromAuthKit() {
  const { user, loading: isLoading } = useAuth();
  const { accessToken, loading: tokenLoading, error: tokenError } = useAccessToken();

  const loading = (isLoading ?? false) || (tokenLoading ?? false);
  const authenticated = !!user && !!accessToken && !loading;

  const stableAccessToken = useRef(null);
  if (accessToken && !tokenError) {
    stableAccessToken.current = accessToken;
  }

  const fetchAccessToken = useCallback(async () => {
    if (stableAccessToken.current && !tokenError) {
      return stableAccessToken.current;
    }
    return null;
  }, [tokenError]);

  return {
    isLoading: loading,
    isAuthenticated: authenticated,
    fetchAccessToken,
  };
}

Install: npm install @workos-inc/authkit-nextjs @convex-dev/workos

Next.js Middleware

// middleware.ts
import { authkitMiddleware } from '@workos-inc/authkit-nextjs';

export default authkitMiddleware({
  middlewareAuth: {
    enabled: true,
    unauthenticatedPaths: ['/', '/sign-in', '/sign-up']
  }
});

export const config = {
  matcher: ['/((?!.*\\..*|_next).*)', '/', '/(api|trpc)(.*)']
};

Next.js Auth Routes

// app/callback/route.ts
import { handleAuth } from '@workos-inc/authkit-nextjs';
export const GET = handleAuth();

// app/sign-in/route.ts
import { redirect } from 'next/navigation';
import { getSignInUrl } from '@workos-inc/authkit-nextjs';
export async function GET() {
  return redirect(await getSignInUrl());
}

// app/sign-up/route.ts
import { redirect } from 'next/navigation';
import { getSignUpUrl } from '@workos-inc/authkit-nextjs';
export async function GET() {
  return redirect(await getSignUpUrl());
}

CORS Configuration (React/Vite only)

For React apps, configure CORS in WorkOS Dashboard:

  1. Authentication > Sessions > Cross-Origin Resource Sharing (CORS)
  2. Click Manage
  3. Add your dev domain: http://localhost:5173
  4. Add your prod domain when deploying

UI Components

import { useAuth } from "@workos-inc/authkit-react"; // or authkit-nextjs/components
import { Authenticated, Unauthenticated } from "convex/react";

function App() {
  const { user, signIn, signOut } = useAuth();

  return (
    <>
      
         signOut()}>Sign out
        
      
      
         signIn()}>Sign in
      
    
  );
}

Auto-Provisioning (Development)

Convex can auto-create WorkOS environments for development:

  1. Run template: npm create convex@latest -- -t react-vite-authkit
  2. Follow prompts to link Convex team with WorkOS
  3. Dev deployments auto-provision WorkOS environments

Configured automatically:

  • Redirect URI
  • CORS origin
  • Local environment variables in .env.local

Limitations:

  • Only works for dev deployments
  • Production must be manually configured

Dev vs Prod Configuration

| Environment | API Key | Redirect URI | | ----------- | ------------- | ---------------------------------- | | Development | sk_test_... | http://localhost:3000/callback | | Production | sk_live_... | https://your-domain.com/callback |

Set different WORKOSCLIENTID in Convex Dashboard for dev vs prod deployments.

WorkOS-Specific Troubleshooting

| Issue | Cause | Fix | | ------------------------- | ------------------ | ------------------------------------------------------------------------- | | CORS error | Domain not added | Add domain in WorkOS Dashboard > Sessions > CORS | | Token validation fails | Wrong issuer | Check BOTH providers in auth.config.ts | | Missing aud claim | JWT config | Check WorkOS JWT configuration | | "Platform not authorized" | Workspace unlinked | Run npx convex integration workos disconnect-team then provision-team |

"Platform not authorized" Error

npx convex integration workos disconnect-team
npx convex integration workos provision-team

Note: Use a different email if creating new WorkOS workspace.

DO ✅

  • Include BOTH provider entries in auth.config.ts (different issuers)
  • Configure CORS for React/Vite apps
  • Use useConvexAuth() not WorkOS's useAuth() for auth state
  • Set WORKOSCLIENTID in Convex Dashboard
  • Use 32+ char WORKOSCOOKIEPASSWORD for Next.js

DON'T ❌

  • Forget the second provider entry (user_management issuer)
  • Skip CORS configuration for browser-based apps
  • Use WorkOS auth hooks to gate Convex queries
  • Hardcode the client ID (use env var)
  • Use same WorkOS env for dev and prod

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.