Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a good pattern for implementing access control in a GraphQL server?

Background:

I have a set of models, including a User and various other models, some of which contain references to a User. I am exposing these models for querying via a GraphQL API generated by Graffiti, backed by a Mongo database using the graffiti-mongoose adaptor. My current REST API (which I am migrating to GraphQL) uses JSON Web Tokens to authenticate users, and has some custom permission logic on the server side to handle access control.

Problem:

I'd like to restrict access to objects in GraphQL based upon the current logged-in user. Some models should be accessible for reads by unauthenticated calls. Most other models should be only accessible to the User who created them. What's the best way to manage access control to objects via the Graffiti-generated API?

In general, are there good patterns of access control for GraphQL? And in particular, are there any good examples or libraries for doing it with Graffiti?

Notes:

I understand that pre- and post- hooks have been implemented for graffiti-mongoose, and that they can be used to do basic binary checks for authentication. I'd like to see how a more detailed access-control logic could be worked into a GraphQL API. In the future, we'll want to support things like Administrators who have access to model instances created by a certain group of Users (e.g. Users whose Affiliations include that of the Administrator).

like image 568
Alec Avatar asked Jan 15 '16 22:01

Alec


People also ask

Which HTTP method is used in GraphQL?

You can also make GraphQL requests using the GET HTTP method. The rules for making GraphQL requests this way are almost the same as the POST version — there are just slight differences: Each property is provided as an HTTP query parameter (values separated by an ampersand — & )

What is authentication and authorization in GraphQL?

Your GraphQL API probably needs to control which users can see and interact with the various data it provides. Authentication is determining whether a given user is logged in, and subsequently determining which user someone is. Authorization is then determining what a given user has permission to do or see.

How do I create a role based authorization for my GraphQL server?

Setup stepsAttach permissions/scopes to your queries and mutations. You can add them to all of them, also those that should be visible for unauthenticated users. You may also add them to any types and/or fields. Create a role-based authentication scheme, specifying permissions per user.


1 Answers

Typically GraphQL does not handle access control directly, instead delegating that responsibility to whatever data system it interfaces with. In your case that sounds like Mongoose.

Since access control logic is often arbitrary logic (for example, has this user been banned from some content? did the publisher of that content restrict it with custom privacy settings? etc.), and it sounds like in your case this access control logic is in fact custom, it should live in the "resolve" function which produces a value for a GraphQL field.

For example:

var UserType = new GraphQLObjectType({
  name: 'User',
  fields: {
    name: { type: GraphQLString },
    birthday: {
      type: GraphQLString,
      resolve(user, context) {
        var auth = context.myLoggedInAuth;
        if (myCanAuthSeeBirthday(auth, user)) {
          return user.birthday;
        }
      }
    }
  }
});
like image 135
Lee Byron Avatar answered Oct 04 '22 19:10

Lee Byron