Kenni
Kenni•10mo ago

Creating an API Key for Secure Data Access Between Next.js Server and Convex Backend

Hey everyone! 👋 I'm working on a project where I have a Next.js server and a Convex backend. I want my server to access specific data from Convex without needing to set up a user account or similar authentication method on the backend. Ideally, I'd like to create an API key that my Next.js server could use to access this data securely. My Goals: 1. Simplify access: I don’t want to manage an additional user account for server access. 2. Security: I want to ensure the connection is secure and properly authenticated. 3. Minimal overhead: Trying to keep this as lightweight as possible. My Questions: 1. Is there a way to create an API key for my server to use with Convex? 2. What are the best practices for securing this kind of server-to-server connection? 3. Has anyone implemented something similar with a Convex backend, or are there any known limitations I should be aware of?
17 Replies
Convex Bot
Convex Bot•10mo ago
Thanks for posting in <#1088161997662724167>. Reminder: If you have a Convex Pro account, use the Convex Dashboard to file support tickets. - Provide context: What are you trying to achieve, what is the end-user interaction, what are you seeing? (full error message, command output, etc.) - Use search.convex.dev to search Docs, Stack, and Discord all at once. - Additionally, you can post your questions in the Convex Community's <#1228095053885476985> channel to receive a response from AI. - Avoid tagging staff unless specifically instructed. Thank you!
ballingt
ballingt•10mo ago
@Kenni I'd use a simple shared secret here, you can build an API key system but e.g. an environment variable that you set on both sides (to include in requests from the Next.js backend and the Convex server to check) works well.
pensono
pensono•8mo ago
What's the best way to pass the shared secret to the API? There's no way I can find to examine the token from ctx.auth. An optional argument for a token on each function would work, but is much more clunky
ballingt
ballingt•8mo ago
I mean generate a secret, then stick that secret in an environment variable in convex deployment and stick that secret in the Nextjs server via environment variable What do you mean here, something about reading values from the identity JWT? Or using the JWT for something else?
pensono
pensono•8mo ago
I'm interested in how the secret is sent to the API. I see there's a way to look at the claims from the result of ctx.auth.getUserIdentity(), but this requires the auth provider to have a valid user set up. In my case I'm using Clerk and I'm trying to see if there's a way to avoid creating a special user within Clerk.
ballingt
ballingt•8mo ago
What API are you talking about? Yeah agree, it's only from a browser or server where you're performing actions on behalf of a user that the identity token from Clerk makes sense. This thread is about something else,
access specific data from Convex without needing to set up a user account or similar authentication method on the backend
so there's no relevant user. So instead of using ConvexHttpClient.setAuth(), I'm suggesting passing a secret value as an argument to the function. This doesn't have anything to do with Clerk, unless you wanted to use Clerk to generate these secrets somehow. I'm suggesting generating random secrets, like MY_APP_CONVEX_SECRET=THIS_IS_MY_SUPER_SECRET_TOKEN_SFKLJSQWRUSODIFUSYSDXCUVEWHFOIUSDNXLCOIWEURKLSDF (but don't just keyboard spam, to be the most secure you should generate a random secret)
pensono
pensono•8mo ago
Ah sorry, API = my convex actions/queries/mutations Got it, thanks! Not ideal but I think this should work
ballingt
ballingt•8mo ago
Great! What would be ideal here, with goals of being the most convenient and giving confidence in the security of the solution? Or maybe better, what feels bad about this solution?
Barrel Of Lube
Barrel Of Lube•3mo ago
can this be a convex helper or sm? I'd really like to use already defined internal endpoints without much modifications to handle a case when a key matches in every function
Or
Or•2mo ago
it's not considered so secure to pass the secret as parameter. is it possible to put your server behind the Convex’s authentication providers - Clerk, and have the server call the function with a backend JWT that browsers cannot mint? So the next.js server code has the api-key of Clerk and issue a JWT, and inside the public Convex mutation - enforce this JWT. is it possible? recommended?
Or
Or•2mo ago
@ballingt the secret parameter is not ideal because:
No description
ballingt
ballingt•2mo ago
Yeah that works, add another auth provider for your new JWT and check that the token is for that one and has eg a subject you trust. You can add as many auth providers as you need.
Or
Or•2mo ago
Hi @ballingt I meant using only one auth provide (Clerk), and inside the convex mutation, distinguish wether the request came from the frontend or from the Next.js backend, based on the JWT - if it contains some custom claim (e.g. role=backend) - the request was originated on the backend, otherwise - it was originated on the frontend. similar to what explain here: https://clerk.com/docs/backend-requests/custom-session-token or here: https://clerk.com/docs/backend-requests/jwt-templates
Backend Requests: Customize your session token
Learn how to customize the session token that is generated for you by Clerk.
Backend Requests: JWT templates
Learn how to create custom JWT templates to generate JSON Web Tokens with Clerk.
ballingt
ballingt•2mo ago
By provider here I mean the entries in convex/auth.config.ts; if the JWTs you use for the server auth are different (ie there aren't OIDC) you migh need another entry in that file
Or
Or•2mo ago
Do you have an example for how to do it in such secure way? I'm struggling with this. I think many folks who uses Vercel functions will benefit from this example. (of how to restrict Convex mutation to the Next.js server side, and block the frontend side) I also created a dedicated post: https://discord.com/channels/1019350475847499849/1389494809646993438
Vixie
Vixie•2mo ago
Hey! Can you share the link to this? I'm curious about this topic I feel like there needs to be a more general solution for letting convex know when a parameter needs to be secure especially considering there are plenty of other types of secrets than api keys and jwts
Or
Or•2mo ago
The dedicated post: https://discord.com/channels/1019350475847499849/1389494809646993438 Exactly, I feel the same way - there must be a better approach then sending a shared secret as parameter I think it would be ideal if Convex will supply api-key which enables accessing intenal mutation from external code

Did you find this page helpful?