ian
ian•2y ago

authorization support?

@Dima Utkin : "Convex currently has an authentication framework which verifies user identities. In the future we plan to add an authorization framework which will allow developers to define what data a user can access." how far is this on the roadmap? 🙂
13 Replies
ian
ianOP•2y ago
So far we've been interested in pushing the limits of user-space solutions to this, rather than trying to build a comprehensive solution baked in. For example, defining functions that take in a user and check that they have permission to the documents retrieved. The upside of doing it in code is total flexibility, and in Convex those functions are running much closer to the DB, so you don't have to force your logic into some obtuse DSL like FaunaDB. I have a few ideas I'm interested in pursuing (as helpers you can copy for now, then maybe as npm packages if they seem useful in that format), open to your feedback on them: 1. Documenting some best practices for storing and leveraging permissions in tables. Having reference code for doing generic permission checks. 2. A wrapper around functions that wrap the db parameter to do checks on reads/ writes, based on a user-defined mapping of table -> { readValidator, writeValidator }. This is similar to the "row-level-permissions" idea. I'm a bit fuzzy on the right way to structure users & the relationships pointing to rows that might not have back-references, but open to ideas. If you were to get to pick an ideal implementation for your app, what would the interface look like? Any stacks you've been especially happy with?
Dima Utkin
Dima Utkin•2y ago
@ian tbh, i have no idea, how this should work "in general", i've never implemented sophisticated enough access controls in any app i've worked on. what i have in mind as a "perfect" solution from the developer's point of view is smth like if can(userId, resource, action)... this is the pattern from permit.io service, which looks awesome, but have a list of downsides(especially, the pricing) but it also bring up a lot of questions... what if the DB is not the only thing you want to protect with these rules? what about calling other APIs, RPC calls to other parts of your infra, using features, etc.? My point is that, it might work if the target is feature-parity with Firebase, they do have a nice and straightforward way of declaring access rules for the DB. but is it enough for everyone? is it even a good idea to limit these rules to the DB level? What's a <user> if you don't use Firebase Auth? Lots of question there. I don't know if there is a universal solution 🤷
ian
ianOP•2y ago
Yup, that's what I'm thinking as well. I have some rough ideas, but I'll update here when I get some time to work on it. Would you mind sharing (here or DM) some specific checks you'd do? I have my own idea of "a user can only modify their own user but can read other users" or "on a doc that is only shared with a few people, only the author or those people can view or edit it". The devil is in the details here, b/c for a relational DB a lot of the info is encoded in other tables, e.g. a "join" or "pivot" table, not just the document being fetched. In firestore they advise more denormalization, so you might have all that data encoded in the document. Which you can do with Convex too, but some folks prefer normalizing data.
Dima Utkin
Dima Utkin•2y ago
again, it's very "what's a <user>?" dependent issue to me. Right now, i'm working on a multi-tenant app(mostly on FE side), with rules from casl lib, and we're both empowered by this lib, but also somewhat limited by it in some of the cases, but in general, in works for us. i see this authZ system as: authN provider (with optional roles like planned in Clerk) <-> user in Convex with roles -> rules on entities in Convex db <-> optional per-user limits for working with entities in db. Like RBAC is top-level, and ABAC(?) is a nested, more granular level on top of role-based access rules. Still, i'm a rookie in this area 🙂
ian
ianOP•2y ago
That makes sense. And yes, because the user definition (and team/group/role/etc) is not a primitive in Convex, I'd be tempted to outline a pattern for using tables to represent users & roles, and some easily composable functions to define rules for each table, and have different apps define their own schemas and such, rather than start with built-in concepts of users & roles. The challenge is enforcing the application of the rules over every access / write, besides convention. 🤔
faluyiHype
faluyiHype•6mo ago
hi, any update or thoughts on this?
jamwt
jamwt•6mo ago
yeah, we're going to be releasing a "full stack" kit that includes things like auth and initial authz in the next few months. in the mean time, the convex-ents project has some support for "rules" which bake in a methdology for access control: https://labs.convex.dev/convex-ents/schema/rules
Rules - Convex Ents
Relations, default values, unique fields and more for Convex
Michal Srb
Michal Srb•6mo ago
@faluyiHype There is an example of granular permissions in https://github.com/xixixao/saas-starter
GitHub
GitHub - xixixao/saas-starter: Convex, Clerk, Next.js, Convex Ents
Convex, Clerk, Next.js, Convex Ents. Contribute to xixixao/saas-starter development by creating an account on GitHub.
faluyiHype
faluyiHype•6mo ago
A little confused by this starter kit, if we're using clerk why are we handling team and org logic?
ian
ianOP•6mo ago
It's generally a better idea to keep information that you want to be transactional and accessed quickly in your own database. If you use Clerk for team & org logic, you need to copy all of that over to your DB in order to actually use it meaningfully. This is especially apparent when you're trying to figure out the user / team / org information of other users during a request. In a Convex transaction (query/mutation) you cannot make http requests to fetch or change data on Clerk. And with any backend you shouldn't be doing http requests while you hold open a transaction.
faluyiHype
faluyiHype•6mo ago
Ok makes sense so Clerk is only used for authentication then? Might as well switch to convex auth and save some money 😎 Side note, is there a way to have a pre mutation/query hook for the purpose of fetching some 3rd party api before executing a transaction
ian
ianOP•6mo ago
not really - you can do a post-mutation http call by transactionally scheduling an action, but other things you'd need to do from the client. If you run into a concrete example / pain point let's open another support thread for it though, unless it's focused on authorization
faluyiHype
faluyiHype•6mo ago
https://docs.convex.dev/functions/actions this clearly covers it thanks.
Actions | Convex Developer Hub
Actions can call third party services to do things such as processing a payment