Auth / RBAC and graphql-shield
See original GitHub issue@liberatiluca In https://github.com/redwoodjs/redwood/issues/806#issuecomment-656238898_ brings up graphql-shield which “helps you create a permission layer for your application”.
While Redwood services would want to protect each with the requireAuth()
or requireAuth({role: 'admin'}
it would be useful to protect at the GraphQL-layer as well.
He proposes an approach and looking to see if the community thinks the idea should move forward and get ideas for rolling it into RW api.
This video from Ryan Chenkie at Prisma (at ~50-51min mark) shows an example fo graphql-shield used with Auth0.
https://youtu.be/DoR7h88Xlvg?t=3051
Hello everyone!
I have successfully used graphql-shield in Redwood and I would really like to have this baked in Redwood.
To give you an example:
in the graphql sdl export an object to define the permissions too:
export const permissions = {
Query: {
users: isAdmin, // isAdmin returns a boolean by checking the authenticated user roles
},
Mutation: {},
};
new file lib/permissions.js:
import _merge from "lodash.merge";
import { deny, shield } from "graphql-shield";
import importAll from "@redwoodjs/api/importAll.macro";
const schemas = importAll("api", "graphql");
let allPermissions = {
Query: {
"*": deny,
},
Mutation: {
"*": deny,
},
};
Object.entries(schemas).forEach(([_, value]) => {
if (value.permissions) {
_merge(allPermissions, value.permissions);
}
});
export const permissions = shield(allPermissions, {
fallbackError: (thrownThing, parent, args, context, info) => {
console.log(thrownThing);
console.log(args);
throw new Error("Not authorized!");
},
});
in functions/graphql.js:
import { applyMiddleware } from "graphql-middleware";
import { permissions } from "src/lib/permissions";
const schema = makeMergedSchema({
schemas,
services: makeServices({ services }),
});
export const handler = createGraphQLHandler({
schema: applyMiddleware(schema, permissions),
db,
});
That’s it!
I think that this is perfect with the role-based authorization suggested here.
Would you like to have this in Redwood?
_Originally posted by @liberatiluca in https://github.com/redwoodjs/redwood/issues/806#issuecomment-656238898_
Issue Analytics
- State:
- Created 3 years ago
- Comments:8 (8 by maintainers)
Had a quick read through https://the-guild.dev/blog/graphql-modules-auth and will likely read several more time.
The section
The Future of Authentication with GraphQL-Modules and GraphQL @directives
and that approach seems most appealing.Where
@auth
and@protect
could call auth’srequireAuth()
such that the method to protect a service/function would be the very same one used to protect the graphql.What i did not see though – which graphql-shield can provide very quickly – is a
deny *
to lock down all graphql, open up the resolvers you want, and then let requireAuth() (if needed) take over from there.Now that I have used graphql-shield a but, I understand more what @liberatiluca suggests:
permissions
with query and mutation rules (by allowing certain resolvers or something that can check auth or roles)The
import services from 'src/services/**/*.{js,ts}'
has replacedimport importAll from "@redwoodjs/api/importAll.macro";
should should be easier to iterate the schemas and fetch eachpermissions
permissions
could be added to the sdl generatorI will try to test to see if the same
requireAuth()
can be used here – or not. Because it relies oncontext.currentUser
I hope it can.Closing in favor of https://github.com/redwoodjs/redwood/issues/2148