neo4j-graphql-js icon indicating copy to clipboard operation
neo4j-graphql-js copied to clipboard

Request: neo4j empowered authorizations through directives

Open emregency opened this issue 6 years ago • 6 comments

Hi all, I have decided to use neo4j extensively for fine-grained authorization rules. I would like to hear from you guys if this sounds correct.

I have the following typeDefs:

type User {
	id: ID!
	username: String
	memberOf: [Group] @relation(name: "memberOf", direction: OUT)
}

type Group {
	id: ID!
	title: String!
}

And I am constantly checking if the user is memberOf the group for mutations.

I think, it is similar to a @hasScope but in this case, the scope is coming from the dB.

Can you guys provide some insights if this makes sense? Is there any way to merge this check in my mutations' resolver cypher using some directives?

Thanks!

emregency avatar Feb 21 '19 18:02 emregency

I'm starting from a similar use-case (but with Discretionary Access Control features). I have some initial work to achieving this on my own fork. It's still very much in early stages of conception, but you're welcome to check it out.

The general approach I am taking is to inject a generator function (or simple parameters for simple implementations) into the context object that can create appropriate leading MATCH clauses, a "header" to the main MATCH clause, and any number of relational WHERE clauses.

The main reason I would advocate this approach over a custom directive is the ability to inject & pull in other Authorization information from the user through the context object; custom generator functions simply give more flexibility on what to include or not.

imkleats avatar Feb 22 '19 02:02 imkleats

Thanks @imkleats I did have a look to your fork. It makes sense to "compose" with MATCH and WHERE clauses some checks using different parameters passed through the context and enhancing the business logic query. On one hand, incorporating ACL straight to the business logic and having this level of flexibility is great.

On the other hand, I have two questions about your implementation:

  1. How do you distinguish throw new Authorization error from null in your return ?
  2. How do you make your access control functions visible at your typeDefs ?

Cheers,

emregency avatar Mar 04 '19 09:03 emregency

  1. That's part of the trade-off involved with achieving a single round trip for authorization&data. It does not seem impossible to build in an additional background field (Boolean) into the RETURN statement that matches your ACL criteria (i.e. isAuthed) that could be used to throw the Apollo error. [Edit: If you were to structure to it as an unmodified primary MATCH clause for the type you're querying along with an OPTIONAL MATCH clause with the ACL path connected to that primary type, you could verify whether 1) a node exists; and 2) whether the OPTIONAL MATCH is null (i.e. no permissions on that node). Then, when RETURN results stemming from that OPTIONAL MATCH are null, you could throw an AuthorizationError.

Most of my work thus far has been how to augment the automatically generated Cypher query (in the Translate library). This approach would also need some sort of validation call within the neo4jgraphql() function prior to when extractQueryResults is called. At first look, this doesn't seem too difficult to implement. Thanks for the ideas!]

  1. How opaque/transparent the IDL should be with respect to business logic seems like a matter of preference. I would imagine that someone could decorate their TypeDefs with directives that are purely descriptive annotations if they wanted to. There might be room to be more verbose on the TypeDef that improve functionality.

imkleats avatar Mar 04 '19 13:03 imkleats

@imkleats so much to the point. This will be a huge huge advantage! I am following closely :) thanks a lot for the detailed explanation, it makes sense and seems implementable. Cheers!

emregency avatar Mar 06 '19 15:03 emregency

Any progress on this issue? I asked a related question on neo4j forums: https://community.neo4j.com/t/saving-auth-roles-scopes-in-neo4j/19228

AdrienLemaire avatar May 27 '20 08:05 AdrienLemaire

https://github.com/neo4j-graphql/neo4j-graphql-js/issues/608

michaeldgraham avatar May 02 '21 04:05 michaeldgraham