The purpose of user authorization set up in the backend is for Upsolve AI to provide appropriate data access based on your user permissioning set up.In your product’s authentication flow, you register users with Upsolve using the project user registration flow. This flow separates three concerns:
Register a user — once per user account, via /register-user.
Fetch a user token — on every login / dashboard load, via /user-token.
The /user-token endpoint is a “refresh” endpoint that issues a short-lived (one-hour by default) JWT for a registered user. Call it every time you (re-)authorize the user in your app. This JWT is then used to provide your authorized users the appropriate access to the dashboard and underlying data.
To generate your API Key please go to the deploy page.
Example: Registering users with Clerk middleware
Here is an example of doing this using Clerk middleware. On every authenticated request we fetch a fresh user token, registering the user on first sign-in if /user-token reports they don’t exist yet:
middleware.ts
// This example protects all routes including api/trpc routes// Please edit this to allow other routes to be public as needed.// See https://clerk.com/docs/references/nextjs/auth-middleware for more information about configuring your Middlewareconst UPSOLVE_API = "https://api.upsolve.ai/v1/api/projects";const UPSOLVE_API_KEY = "up_admin_3...bL9"; // Make sure this begins with up_admin_const UPSOLVE_PROJECT_ID = "your-project-uuid";export default authMiddleware({async afterAuth(auth, req, evt) { console.log("Starting login"); // Handle users who aren't authenticated ... // Register users to Upsolve if (auth.userId && auth.orgId) { console.log("Starting Upsolve user token refresh"); const headers = { "Content-Type": "application/json", Authorization: `Bearer ${UPSOLVE_API_KEY}`, }; const fetchToken = () => fetch(`${UPSOLVE_API}/user-token`, { method: "POST", headers, body: JSON.stringify({ userId: auth.userId }), }); let res = await fetchToken(); // First sign-in: register the user (and their org) then retry. if (res.status === 404) { await fetch(`${UPSOLVE_API}/register-user`, { method: "POST", headers, body: JSON.stringify({ projectId: UPSOLVE_PROJECT_ID, projectOrganizationId: auth.orgId, // your internal ID — works as externalId userRoleId: "your-role-uuid", name: auth.orgSlug, userId: auth.userId, properties: { // Each key is surfaced in RLS rules as {{user.<key>}}, e.g. {{user.organization_id}} organization_id: auth.orgSlug, }, }), }); res = await fetchToken(); } const upsolveToken = await res .json() .then((data) => data?.["data"]?.["token"]); // Extract the JWT from the response // Save the JWT to the user's public metadata, to be used client side! await clerkClient.users.updateUser(auth.userId, { publicMetadata: { upsolveToken }, }); console.log(`Upsolve registration done`); } // If the user is logged in and trying to access a protected route, allow them to access route ... // Allow users visiting public routes to access them ...},});
You could inspect whether the user authorization is setup successfully. Navigate to the Deploy application using the side navigation bar.If the endpoint is successfully called, you should see your new tenants in the Deploy application: