cancel
Showing results for 
Search instead for 
Did you mean: 

Can't apply auth directive on field level

Mreda
Node Link

Hello,

I have been trying to apply different kind of authorization rules on entity fields :

schema sample:

type User {
id: ID! @id(autogenerate: true)
fullName: String!
createdEvents: [Event!]! @relationship(type: "CREATED_EVENT", direction: OUT)
savedEvents: [Event!]! @relationship(type: "SAVED_EVENT", direction: OUT)
}

type Category {
name: String! @id(autogenerate: false)
interests: [Interest!]! @relationship(type: "INTEREST_OF", direction: IN)
}

type Interest{
name: String! @id(autogenerate: false)
category: Category! @relationship(type: "INTEREST_OF", direction: OUT)
}

type Event {
id: ID! @id(autogenerate: true)
name: String!
startDate: DateTime!
endDate: DateTime!
createdBy: User! @relationship(type: "CREATED_EVENT", direction: IN)
usersSaved: [User!]! @relationship(type: "SAVED_EVENT", direction: IN)
interests: [Interest!]! @relationship(type: "INTEREST_IN", direction: OUT)
}

As shown above, What i want to do is that,

  • createdBy field of the the entity Event must be immutable and must not be modified after it has been set on creation time.

  • usersSaved field of the entity Event can be modified by any user i.e any user can connect to the event through this field.

  • interests and Other fields left of the entity Event can only be modified by the creator user (the one the createdBy field refers to).

I have attempted to apply auth rules on each field but @relationship and @auth can’t be used together. Where as Entity/Object level @auth directive can’t be specific enough to protect the interests field not to be modified by other users other than the creator and allow usersSaved to be modified by anyone(any user).

I have also attempted to use @readonly directive on the createdBy field but the same issue gets raised as the above.

I would really appreciate any help, workaround or ideas regarding this. Thank you.

1 REPLY 1

Hey @Mreda, tricky problem you have here!

As a general rule, most directives cannot be combined with the `@relationship`  directive as it stands.

You can achieve some of what you want using an `@auth`  directive on the `Event`  type itself.

  • createdBy field of the the entity Event must be immutable and must not be modified after it has been set on creation time.

`bind`  could be useful here - a simple rule on `Event`  should work:

```@auth(rules: [{ bind: { createdBy: { id: "$jwt.sub" } } }])`

  • usersSaved field of the entity Event can be modified by any user i.e any user can connect to the event through this field.

By not protecting this at all, you will pretty much get this behaviour.

  • interests and Other fields left of the entity Event can only be modified by the creator user (the one the createdBy field refers to).


You should be able to add the `@auth`  directive to any scalar fields, but the interests field will be a struggle.

All in all, I don't think off the top of my head that the library will be able to fully help you, but it's hard for me to say as I don't have a deep understanding of your business logic. I recommend fully reading the documentation on auth, even if it is a little light touch: https://neo4j.com/docs/graphql-manual/current/auth/

Sorry, I realise this won't be the answer you were hoping for! We are going to be revisiting the `@auth`  directive soon, and we will keep your use cases in mind.