-
What do you want and why?Not sure on exactly what is best, but here's one idea. The idea is that roles are groups of permissions. And you enforce permissions, not roles. So you centralize the definition of roles with something like this: const roles = {
admin: ['product:read', 'product:create', 'product:update', 'product:delete'],
manager: ['product:update'],
} And then in your code you enforce a permission. export default async function updateProduct(input, ctx) {
ctx.session.authorize('product:update')
} This allows you to add/remove/refactor your roles without also having to change a ton of other files. This will be added as an experimental authorization implementation. Another idea is use something like https://github.com/onury/accesscontrol |
Beta Was this translation helpful? Give feedback.
Replies: 6 comments 2 replies
-
Your statement about roles being permission groups is spot on. Similarly, permissions for an entity are just a group of permissions that you need per property. Field or Column level permissions are often needed, in any application. Hasura does it well, where they track that information per field in its metadata tables. |
Beta Was this translation helpful? Give feedback.
-
Here's some noodling from today on ways to integrate authorization at the prisma level. Have some builder pattern to build up authn rules. The second argument is a prisma const secureDb = new SecuredPrisma(prismaClient)
secureDb.grant('anonymous')
.read('post', {published: {equals: true}})
.grant('user')
.manage('project', ctx => ({owner: {id: ctx.userId}}))
.read('project', ctx => ({creator: {id: ctx.userId}}))
.create('task', ctx => ({project: {connect: {organization: {id: ctx.orgId}}}}))
.grant('superadmin')
.manageAll('project')
.manageAll('task')
export secureDb And then use that like this. It will automatically throw AuthenticationError or AuthorizationError based on who the current user is and what they are trying to access. No need to manually call import secureDb from "db";
export default async function getProject(args, { session }) {
const project = await secureDb
.ctx(session)
.project.findMany({ where: { id: args.id } }).one()
if (!project) throw new NotFoundError();
return project;
} The other way to do this is add authorization to Prisma Middleware instead of wrapping prisma client as shown here. We also need a way to restrict which fields can be read and modified by different roles. |
Beta Was this translation helpful? Give feedback.
-
@flybayer Really love the idea but have a different API idea, something closer to prisma itself. Also I think we should see if Prisma Team has any ideas about this @janpio @nikolasburk // anonymous users can only select certain columns
const anonymousGrant = new Grant({
roles: null,
project: {
read: {
published: { eq: true },
select: {
id: true,
title: true,
createdAt: true,
},
},
},
})
const userGrant = new Grant({
roles: ['user'],
project: {
manage: (ctx) => ({ owner: { id: ctx.userId } }),
read: (ctx) => ({ creator: { id: ctx.userId } }),
},
task: {
create: (ctx) => ({ project: { connect: { organization: { id: ctx.orgId } } } }),
},
})
// Merge admin and superadmin
const superAdminGrant = new Grant({
roles: ['admin', 'superadmin'],
project: { manage: true },
task: { manage: true },
organization: { manage: (ctx) => ctx.role === 'superadmin' }
})
const prismaClient = new PrismaClient()
const secureDB = new SecureDB(prismaClient, [anonymousGrant, userGrant, superAdminGrant])
export { secureDB, prismaClient as db } |
Beta Was this translation helpful? Give feedback.
-
What's the status on this? |
Beta Was this translation helpful? Give feedback.
-
New centralized, permission-based authorization library is now available! |
Beta Was this translation helpful? Give feedback.
-
Out of curiosity, why re-invent the wheel? Casbin is extremely mature, supports multiple styles of authorization (e.g. ACL, RBAC, ABAC), and already has a Prisma adapter |
Beta Was this translation helpful? Give feedback.
New centralized, permission-based authorization library is now available!
👉 https://github.com/ntgussoni/blitz-guard