To integrate Okta with Bolt.new, create a free Okta developer account, set up an OIDC Web Application, then prompt Bolt to install @okta/okta-react and configure the OktaAuth provider with your Client ID and Issuer URL. Full SSO redirect flows require a deployed URL — the OAuth callback cannot complete in Bolt's WebContainer preview. Deploy to Netlify or Vercel first, then register your deployed domain as an allowed redirect URI in Okta.
Add Enterprise SSO to Your Bolt.new App with Okta
Okta is the leading enterprise identity platform for workforce authentication — the choice for internal tools, B2B SaaS apps, and any application where users sign in through their company's identity provider. While Auth0 targets consumer-facing apps, Okta targets the enterprise: SSO across company apps, SCIM directory sync with Active Directory, adaptive MFA, and group-based access policies that your IT department can manage centrally. If you're building a tool that employees will log into, or a B2B product where your customers want their workforce managed through Okta, this is the integration you need.
Bolt.new integrates with Okta through the official @okta/okta-react SDK, which handles the entire OIDC authorization code flow. Bolt generates the OktaAuth provider configuration, a LoginCallback route to process the redirect, protected route components that enforce authentication, and hooks to access the signed-in user's profile and group memberships. Okta's free Developer Edition includes 100 monthly active users — enough to build and prototype enterprise features before your customers provision their own Okta org.
The critical constraint with Bolt and Okta is that OAuth 2.0 requires a real, publicly accessible redirect URI — Okta will POST the authorization code back to a URL you register in advance, and the WebContainer's dynamic preview URL cannot receive those callbacks. This means the SSO sign-in flow cannot be tested end-to-end in Bolt's preview. You can configure the provider and build all the UI, but the first full login test happens after deploying to Netlify or Vercel and registering your deployed URL as an allowed redirect URI in the Okta app settings.
Integration method
Okta integrates with Bolt.new through the @okta/okta-react SDK and an API route that handles the OAuth 2.0 OIDC authorization code flow. Bolt generates the OktaAuth provider configuration, protected route wrappers, and user profile access from a single prompt. Because Okta's OAuth redirect URI must be a publicly accessible URL, the full SSO login flow cannot be completed inside Bolt's WebContainer preview — you need to deploy first and register your deployed domain in the Okta app settings.
Prerequisites
- A free Okta Developer Edition account at developer.okta.com (supports 100 MAU, no credit card needed)
- An OIDC Web Application created in your Okta admin dashboard with the Sign-in redirect URI configured
- Your Okta Client ID and Issuer URL (e.g., https://dev-12345678.okta.com/oauth2/default) from the app settings
- A Bolt.new project using Next.js (required for API routes to validate tokens server-side)
- A deployed URL on Netlify or Vercel for registering the Okta redirect URI and testing the full SSO flow
Step-by-step guide
Create an Okta Developer Account and OIDC Application
Create an Okta Developer Account and OIDC Application
Start at developer.okta.com and sign up for a free Developer Edition account. Once logged in, you land in the Okta Admin Console. Navigate to Applications → Applications in the left sidebar and click 'Create App Integration'. In the dialog, select 'OIDC - OpenID Connect' as the sign-in method and 'Single-Page Application' as the application type — this is the correct type for React apps built with Bolt. Click Next. Give your app a name (e.g., 'My Bolt App'). Under 'Sign-in redirect URIs', add your deployment callback URL: `https://your-app.netlify.app/login/callback`. Also add `http://localhost:3000/login/callback` for local development. Under 'Sign-out redirect URIs', add `https://your-app.netlify.app` and `http://localhost:3000`. Under 'Assignments', choose 'Allow everyone in your organization to access' for development. Click Save. Okta creates the app and shows you the Client ID and your Okta Domain on the General tab. Copy both — you'll need them as environment variables. Your Issuer URL will be `https://{yourOktaDomain}/oauth2/default`. This is a public endpoint that identifies your Okta authorization server to the SDK.
Pro tip: Okta Developer Edition is permanently free for up to 100 monthly active users. When your enterprise customers onboard, they provision their own Okta org and you configure your app to use their issuer URL — you don't pay for their users.
Expected result: You have an Okta OIDC app with a Client ID, your Okta Domain noted, and redirect URIs configured. The app is visible under Applications → Applications in your Okta admin console.
Add Environment Variables to Your Bolt Project
Add Environment Variables to Your Bolt Project
In your Bolt project, open the .env file in the root of the project (or create one if it doesn't exist — it's already in .gitignore). Add your Okta credentials as environment variables. For a Vite-based Bolt project, you need the VITE_ prefix to make variables accessible in the browser. For a Next.js Bolt project, use NEXT_PUBLIC_ for client-side values. The Okta Client ID and Issuer URL are not secret values — they're public identifiers visible to anyone using your app — so using the public prefix is correct. The Client ID tells Okta which app is initiating the login; the Issuer URL is the base URL of your Okta authorization server. Never put these in hardcoded strings in your components — always use environment variables so you can swap between development and production Okta apps without changing code. In Bolt's file tree, click the .env file to open it and add the variables shown in the code block. After saving .env, restart the preview if needed for the variables to take effect.
I need to add Okta environment variables to my project. Update the .env file with VITE_OKTA_CLIENT_ID and VITE_OKTA_ISSUER as placeholders. Then show me where in the code these should be read using import.meta.env.VITE_OKTA_CLIENT_ID and import.meta.env.VITE_OKTA_ISSUER.
Paste this in Bolt.new chat
1# .env2# Okta Developer App credentials3# Find these in Okta Admin Console → Applications → your app → General tab4VITE_OKTA_CLIENT_ID=0oaXXXXXXXXXXXXXXXXX5VITE_OKTA_ISSUER=https://dev-12345678.okta.com/oauth2/default67# For Next.js projects, use NEXT_PUBLIC_ prefix instead:8# NEXT_PUBLIC_OKTA_CLIENT_ID=0oaXXXXXXXXXXXXXXXXX9# NEXT_PUBLIC_OKTA_ISSUER=https://dev-12345678.okta.com/oauth2/default1011# For server-side token validation only (keep this private, no VITE_ or NEXT_PUBLIC_ prefix):12# OKTA_AUDIENCE=api://defaultPro tip: The Okta Client ID and Issuer URL are safe to expose in client-side code — they're not secret keys. They identify your app to Okta's public OIDC endpoints. The actual secret (the access token) is issued by Okta and never stored in your code.
Expected result: Your .env file contains the Okta Client ID and Issuer URL. The Bolt preview reads these values without errors when you reference them via import.meta.env.
Prompt Bolt to Set Up the Okta Provider and Login Flow
Prompt Bolt to Set Up the Okta Provider and Login Flow
With environment variables in place, use the Bolt chat to generate the Okta authentication integration. Bolt installs @okta/okta-react and @okta/okta-auth-js from npm, then generates the OktaAuth configuration object, wraps your app in the Security provider, creates a /login route with a sign-in button that redirects to Okta's hosted sign-in page, creates the /login/callback route component that processes the OAuth redirect and exchanges the authorization code for tokens, and adds a useOktaAuth hook call to any component that needs the user's session. Review the generated src/main.tsx or src/App.tsx — Bolt wraps the router in the Security component from @okta/okta-react, passing the OktaAuth instance. The LoginCallback component from the SDK handles the /login/callback route automatically — it reads the authorization code from the URL, exchanges it for tokens, and redirects the user to the intended destination. The restoreOriginalUri callback tells the SDK where to send the user after login completes.
Add Okta SSO authentication to my React app. Install @okta/okta-react and @okta/okta-auth-js. Configure OktaAuth using import.meta.env.VITE_OKTA_CLIENT_ID and import.meta.env.VITE_OKTA_ISSUER. Wrap the app in the Security provider with a restoreOriginalUri callback. Create a /login page with a button that calls oktaAuth.signInWithRedirect(). Create a /login/callback route that renders the LoginCallback component from @okta/okta-react. Create a RequiredAuth component that checks useOktaAuth().authState.isAuthenticated and redirects unauthenticated users to /login. Wrap the /dashboard route with RequiredAuth.
Paste this in Bolt.new chat
1// src/auth/oktaConfig.ts2import { OktaAuth } from '@okta/okta-auth-js';34export const oktaAuth = new OktaAuth({5 issuer: import.meta.env.VITE_OKTA_ISSUER,6 clientId: import.meta.env.VITE_OKTA_CLIENT_ID,7 redirectUri: `${window.location.origin}/login/callback`,8 scopes: ['openid', 'profile', 'email', 'groups'],9 pkce: true,10});1112// src/components/RequiredAuth.tsx13import { useOktaAuth } from '@okta/okta-react';14import { useEffect } from 'react';15import { Outlet } from 'react-router-dom';1617export function RequiredAuth() {18 const { oktaAuth, authState } = useOktaAuth();1920 useEffect(() => {21 if (!authState) return;22 if (!authState.isAuthenticated) {23 oktaAuth.signInWithRedirect();24 }25 }, [authState, oktaAuth]);2627 if (!authState || !authState.isAuthenticated) {28 return <div>Loading...</div>;29 }3031 return <Outlet />;32}3334// src/App.tsx (relevant section)35import { Security, LoginCallback } from '@okta/okta-react';36import { oktaAuth } from './auth/oktaConfig';3738const restoreOriginalUri = async (_oktaAuth: OktaAuth, originalUri: string) => {39 window.location.replace(originalUri ?? '/');40};4142// Wrap your router:43// <Security oktaAuth={oktaAuth} restoreOriginalUri={restoreOriginalUri}>44// <Routes>45// <Route path="/login/callback" element={<LoginCallback />} />46// <Route element={<RequiredAuth />}>47// <Route path="/dashboard" element={<Dashboard />} />48// </Route>49// </Routes>50// </Security>Pro tip: Always include 'groups' in the scopes array if you plan to use Okta groups for RBAC. Okta only includes group claims in the ID token when the scope is requested AND the groups claim is configured in your Okta Authorization Server policy.
Expected result: Your app has an OktaAuth provider configured, a /login/callback route, and a RequiredAuth wrapper around protected routes. Visiting /dashboard while unauthenticated triggers a redirect to Okta's login page.
Access User Profile and Groups for RBAC
Access User Profile and Groups for RBAC
After a successful Okta login, the user's profile information and group memberships are available through the useOktaAuth hook. The authState object contains the idToken and accessToken — the ID token holds user profile claims (name, email, preferred_username) while the access token is used for calling protected APIs. To access group-based roles, you need to configure Okta to include the groups claim in the token. In your Okta Admin Console, navigate to Security → API → Authorization Servers → default → Claims → Add Claim. Create a claim named 'groups', include it in the 'ID Token', set the value type to 'Groups', and filter to include all groups (or specific groups by regex). After adding the claim, users' group memberships appear in idToken.claims.groups as an array of strings. In your React component, read the groups array and use it to conditionally render admin UI, gate feature access, or pass a role to your backend. For server-side enforcement, pass the access token as a Bearer header to your API routes and validate it against Okta's JWKS endpoint.
Add role-based access to my Okta-protected app. After login, read the user's groups from idToken.claims.groups using the useOktaAuth hook. If the user is in the 'Admins' group, show an 'Admin Panel' link in the navigation. If they're in 'Members', show only the 'Dashboard' link. Create a useOktaUser hook that returns { name, email, isAdmin, isMember } for easy use in components. Also show the user's name in the header from authState.idToken.claims.name.
Paste this in Bolt.new chat
1// src/hooks/useOktaUser.ts2import { useOktaAuth } from '@okta/okta-react';34interface OktaUser {5 name: string;6 email: string;7 groups: string[];8 isAdmin: boolean;9 isMember: boolean;10 accessToken: string | null;11}1213export function useOktaUser(): OktaUser | null {14 const { authState } = useOktaAuth();1516 if (!authState?.isAuthenticated || !authState.idToken) {17 return null;18 }1920 const claims = authState.idToken.claims;21 const groups: string[] = (claims.groups as string[]) ?? [];2223 return {24 name: (claims.name as string) ?? '',25 email: (claims.email as string) ?? '',26 groups,27 isAdmin: groups.includes('Admins'),28 isMember: groups.includes('Members'),29 accessToken: authState.accessToken?.accessToken ?? null,30 };31}3233// Usage in a component:34// const user = useOktaUser();35// if (!user) return <LoadingSpinner />;36// return <div>Welcome, {user.name} — {user.isAdmin ? 'Admin' : 'Member'}</div>;Pro tip: If groups is undefined in idToken.claims, the 'groups' claim hasn't been added to your Okta Authorization Server. Go to Okta Admin → Security → API → Authorization Servers → default → Claims and add a groups claim for the ID Token.
Expected result: Your components can read the signed-in user's name, email, and group memberships. Admin users see different navigation and UI elements than standard members.
Deploy and Register the Okta Redirect URI
Deploy and Register the Okta Redirect URI
The Okta SSO flow cannot be tested end-to-end inside Bolt's WebContainer preview because OAuth 2.0 requires Okta to redirect the browser to a registered callback URL after authentication. Bolt's WebContainer environment doesn't have a stable, publicly accessible URL that Okta can redirect to — this is a fundamental WebContainer limitation, not a configuration issue. To test the full login flow, deploy your Bolt app to Netlify or Vercel. In Netlify, connect your project through the Netlify dashboard and deploy. Note your deployed URL (e.g., `https://my-bolt-app.netlify.app`). Now return to your Okta Admin Console → Applications → your app → General tab → Edit. Under 'Sign-in redirect URIs', confirm your deployed callback URL is listed: `https://my-bolt-app.netlify.app/login/callback`. Under 'Sign-out redirect URIs', confirm `https://my-bolt-app.netlify.app` is listed. Save the changes. In your Netlify site configuration, add the environment variables: set `VITE_OKTA_CLIENT_ID` and `VITE_OKTA_ISSUER` to the same values from your .env file (Netlify injects these at build time for Vite apps). Trigger a new deploy. Once deployed, visit your app URL, click 'Sign in with Okta', and you'll be redirected to Okta's hosted login page — complete the sign-in and you'll be redirected back to your app with an authenticated session.
Prepare my Okta app for deployment to Netlify. Create a netlify.toml file with build command 'npm run build', publish directory 'dist', and a redirect rule so all routes serve index.html for SPA routing. Also create a comment listing the environment variables that must be set in the Netlify dashboard before deploying.
Paste this in Bolt.new chat
1# netlify.toml2[build]3 command = "npm run build"4 publish = "dist"56[[redirects]]7 from = "/*"8 to = "/index.html"9 status = 2001011# Environment variables to set in Netlify Dashboard (Site Configuration → Environment Variables):12# VITE_OKTA_CLIENT_ID = your Okta app Client ID13# VITE_OKTA_ISSUER = https://dev-XXXXXXXX.okta.com/oauth2/default14#15# After deploy, confirm in Okta Admin Console → Applications → your app → General:16# Sign-in redirect URI: https://your-app.netlify.app/login/callback17# Sign-out redirect URI: https://your-app.netlify.appPro tip: Okta will silently fail (showing a generic error page) if the redirect URI in your request doesn't exactly match one of the registered URIs. Check for trailing slashes, http vs https, and www vs non-www differences when debugging redirect_uri_mismatch errors.
Expected result: Your deployed app at the Netlify URL completes the full Okta SSO flow — clicking 'Sign in with Okta' redirects to Okta's login page, and after authentication, the user lands back in your app fully signed in.
Common use cases
Internal Tool with Company SSO Login
Build an internal dashboard or admin tool where employees sign in using their company Okta credentials — no separate passwords, automatically disabled when they leave the company. Users click 'Sign in with Okta', authenticate through their company's SSO, and land in the app with their profile and department pre-populated.
Add Okta SSO login to my app. Install @okta/okta-react and @okta/okta-auth-js. Create an OktaAuth instance configured with import.meta.env.VITE_OKTA_ISSUER and import.meta.env.VITE_OKTA_CLIENT_ID. Wrap the app in the Security provider with a restoreOriginalUri callback. Create a /login page with a 'Sign in with Okta' button, a /login/callback route to handle the OAuth redirect, and protect all routes under /dashboard so unauthenticated users are redirected to the login page. Show the signed-in user's name and email in the top navigation.
Copy this prompt to try it in Bolt.new
B2B App with Group-Based Role Access
Build a multi-tenant B2B application where Okta groups determine what each user can access. Admin group members see configuration and billing settings; regular members see only operational views. Group memberships are managed in the customer's Okta admin panel, not in your app.
Add Okta authentication to my B2B app with role-based access control. After the user logs in via Okta SSO, retrieve their Okta groups from the ID token claims. Users in the 'Admins' group can access /settings and /billing. Users in the 'Members' group can only access /dashboard. If a user tries to access a restricted page, show a 403 forbidden message. Store the user's role in app state after login.
Copy this prompt to try it in Bolt.new
Next.js API Route Protected by Okta Bearer Token
Secure a Next.js API route so it only accepts requests that include a valid Okta access token in the Authorization header. Useful for protecting API endpoints consumed by internal services, Okta-authenticated mobile apps, or third-party tools that enterprise customers integrate with.
Create a Next.js API route at /api/reports that is protected by Okta. The route should verify the Bearer token in the Authorization header against my Okta authorization server using JWKS. If the token is valid, return the report data as JSON. If the token is missing or invalid, return a 401 with an error message. Use environment variables for OKTA_ISSUER and OKTA_AUDIENCE.
Copy this prompt to try it in Bolt.new
Troubleshooting
Browser shows 'redirect_uri_mismatch' error on the Okta login page
Cause: The redirect URI your app sends to Okta does not exactly match any registered Sign-in redirect URI in your Okta app settings. Even a trailing slash difference causes this error.
Solution: Open Okta Admin Console → Applications → your app → General tab → Edit. Under 'Sign-in redirect URIs', add the exact URL shown in your browser's address bar when the error occurs. Common mismatches: http vs https, missing /login/callback path, trailing slash, www prefix. Your deployed URL must be registered separately from localhost.
authState.idToken.claims.groups is undefined even after adding the groups scope
Cause: The 'groups' claim has not been added to the Okta Authorization Server's token policy, or the claim was added to the Access Token instead of the ID Token. Adding 'groups' to the SDK scopes array alone is not enough.
Solution: In Okta Admin Console, go to Security → API → Authorization Servers → default → Claims tab → Add Claim. Set Name to 'groups', Include in to 'ID Token', Value type to 'Groups', Filter to 'Matches regex .*'. Save and sign out and back in to get a fresh token with the new claim.
Okta sign-in button redirects to a blank page or the login flow never completes in Bolt's preview
Cause: OAuth redirect flows require a publicly accessible URL for the callback, which the WebContainer preview does not have. Okta initiates the redirect but the callback cannot complete inside the browser-sandboxed WebContainer environment.
Solution: This is the expected WebContainer limitation — OAuth flows with external providers cannot complete in Bolt's preview. Deploy to Netlify or Vercel, register the deployed domain as a redirect URI in your Okta app, and test the full SSO flow on the deployed URL. Non-auth UI and components can still be previewed in Bolt.
API route returns 401 even though the user is signed in to Okta on the frontend
Cause: The Okta access token is not being included in the API request Authorization header, or the server-side validation is using the wrong issuer or audience value.
Solution: On the frontend, get the access token using authState.accessToken.accessToken from useOktaAuth() and include it as a Bearer token in fetch requests. On the API route, validate against the JWKS endpoint at {issuer}/v1/keys. Ensure the audience claim matches your OKTA_AUDIENCE env var (default is 'api://default').
1// Frontend: include the access token in API calls2const { authState } = useOktaAuth();3const token = authState?.accessToken?.accessToken;45const response = await fetch('/api/reports', {6 headers: {7 Authorization: `Bearer ${token}`,8 },9});Best practices
- Use PKCE (Proof Key for Code Exchange) — it's enabled by default in @okta/okta-auth-js for SPAs and prevents authorization code interception attacks; never disable it
- Request only the scopes your app needs — 'openid profile email' covers most cases; add 'groups' only if you're implementing RBAC and have configured the groups claim in your Authorization Server
- Store the Okta Client ID and Issuer URL as environment variables — while not secret, hardcoding them makes it impossible to swap between development and production Okta orgs without code changes
- Validate access tokens server-side using Okta's JWKS endpoint for any API route that returns sensitive data — client-side authState is sufficient for UI gating but not for backend authorization
- Register separate redirect URIs for each environment (localhost, staging, production) rather than using one URI across environments
- Handle token expiry gracefully — Okta access tokens expire after 1 hour by default; set tokenManager.autoRenew: true in the OktaAuth config to refresh tokens silently before expiry
- Test the full SSO flow on your deployed URL before sharing with users — the WebContainer preview cannot complete OAuth callbacks, so issues only surface post-deployment
Alternatives
Auth0 is better suited for consumer-facing apps where users create individual accounts; Okta is the enterprise choice when users need to sign in through their company's existing identity provider.
Duo focuses specifically on MFA enforcement and device trust rather than full identity management — use Duo as a second factor layered on top of Okta rather than as a standalone replacement.
LastPass is a password manager, not an identity provider — it stores credentials but does not provide OIDC, SSO, or programmatic authentication flows that Okta offers.
Frequently asked questions
How do I connect Bolt.new to Okta?
Create a free Okta Developer account at developer.okta.com, set up an OIDC Single-Page Application, and copy your Client ID and Issuer URL into your Bolt project's .env file. Then prompt Bolt to install @okta/okta-react and configure the Security provider with your credentials. The full SSO login flow requires a deployed URL — register your Netlify or Vercel domain as a redirect URI in Okta before testing.
Can I test Okta login in Bolt's WebContainer preview?
You can build and configure the Okta provider, protected routes, and login button in the preview without issues. However, the actual SSO redirect flow — clicking 'Sign in with Okta' and being redirected back after authentication — cannot complete inside the WebContainer because it has no publicly accessible URL for Okta's callback. Deploy to Netlify or Vercel and register your deployed URL as the redirect URI to test the full flow.
What is the difference between Okta and Auth0 for Bolt.new apps?
Okta is designed for workforce and B2B identity — employees logging into internal tools, enterprise customers using their company's existing Okta org for SSO. Auth0 is designed for customer identity — users creating individual accounts on consumer apps. For internal tools or B2B SaaS where your customers' IT departments want central control, choose Okta. For apps where end users self-register with email or social login, choose Auth0.
Is Okta free for development and small apps?
Yes. Okta's Developer Edition is permanently free and includes up to 100 monthly active users, all core SSO and OIDC features, MFA, and SCIM provisioning. It's sufficient for building and prototyping enterprise features. When you're building a B2B product, your enterprise customers typically provision their own Okta org and you configure your app to use their issuer URL — so you're not paying for their users.
How do I use Okta groups for role-based access control in my Bolt app?
First, add a 'groups' claim to your Okta Authorization Server: go to Security → API → Authorization Servers → default → Claims → Add Claim, and configure it to include all groups in the ID Token. Then add 'groups' to the scopes in your OktaAuth config. After login, read idToken.claims.groups (an array of group name strings) to determine the user's role. Use this to conditionally render UI or gate route access in your RequiredAuth component.
How do I validate Okta tokens in a Bolt Next.js API route?
Fetch Okta's public JWKS from {issuer}/v1/keys and use a JWT library (such as jose) to verify the access token signature and claims. Check that the iss claim matches your OKTA_ISSUER, the aud claim matches your OKTA_AUDIENCE (default is 'api://default'), and the token has not expired. The frontend passes the access token from authState.accessToken.accessToken as an Authorization: Bearer header with each API request.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation