Using @auth on individual fields?

Breaking this into it’s own topic, so here is the context:

From reading over the docs on @auth directive I understand that these directives can restrict access to the nodes themselves by using JWT properties to check for user roles, or matching graph fields against those properties.

Please correct me if I am wrong, but from how I understand it so far: Once a user has access to a node then the user also has access to all of the fields of that node. If I have a node labeled person and I want to restrict a specific property on that node such as a SSN, while allowing other properties such as the name and age, there is not a native @auth directive to do that at this time.

I am thinking that there is a way to control access to fields like this if instead of it living as a field it lives as a related node. query { person { name hasSSN { SSN } } } I could then control the hasSSN type with it’s own @auth directives.


The following statement from the docs has intrigued me.

In general, an auth rule should select a field that’s expected to exist at the inner most field, often that’s the ID or @id field. Auth rules are run in a mode that requires all fields in the rule to find a value in order to succeed. - The @auth directive

My initial thinking was that the inner fields in a rule would give access to those fields or restrict access to those fields, but that is not the case. If I understand this right this can be used to control access by looking for a field that would only exist if the user has access to the item. Not based upon a value of the field, but solely if it exists or not. If the rule in the example in the docs was changed to look for inner fields id, text and a node existed that did not have a text field then those nodes would be inaccessible. I am trying to think if this logic can somehow be used in a way to control access to fields, but I think the limitation I would run into is that this is only used for granting/restricting the whole node and not just the individual fields.

1 Like

Yeah, currently we don’t have auth to control access to individual fields.
We will try to include it in the 20.11 version.
All the fields are not required in order to succeed an auth rule, that is required only if you combined them using AND.
It depends on the rule that you have applied.

3 Likes

I’m trying to expose my backend to the wider-web, and want to disallow others from modifying the data.

type MyType @auth (
add: { rule: “{$user: { eq: “mrjn” } }”},
delete: { rule: “{$user: { eq: “mrjn” } }”},
update: { rule: “{$user: { eq: “mrjn” } }”}
){
id: String! @id
text: String! @search(by: [fulltext])
postedAt: DateTime @search @auth()
}

The 3 rules above allow the backend to be secure, so only I can modify the data. But, I also want to hide postedAt from being queried. How do I do that?

2 Likes

Any update on this?

It’s very hard to build something practical with Dgraph for me without @auth for individual fields…
E.g. imagine a user directory where some information like an email must not be visible publicly. What’s the recommended workaround currently for such usecases?

1 Like

You can add do something like;:

type User {
  privateStuff: PrivateUserInfo!
  publicStuff: PublicUserInfo!
}

type PrivateUserInfo @auth(...)  {
   email: String!
}

type PublicUserInfo {
   whatever: String!
}

This of course can become very unhandy because you have to maintain several relationships.

3 Likes

Thanks so much! It looks a bit odd, but I guess that’d do while we are waiting for the support of this feature.

1 Like

@JatinDevDG @mrjn

Is there a reasonable eta for this one? The last update was ~9 months ago :slight_smile:

Hi @CosmicPangolin1 ,this feature will be available in 21.07 release.

2 Likes

@JatinDevDG what is the estimated date for that release ? Is there a release schedule somewhere?

EDIT: Oh, I get it, I think 21.07 would be July this year right ?
I was really hoping for this to be coming out in 21.03 release.

Hi @sambhav-gore , sorry we had other priority items for 21.03 and not able to include this feature.
But that is included in our plan for 21.07 and yes,that will be released in July this year. So, you have to wait a bit more for it.

We are following calender versioning , you can read more about it here [Calender versioning] .(Why there would be no Dgraph 2.0: Goodbye Semantic Versioning - Dgraph Blog)

I’d integrate it with a “for” and “without” property like there is the “and” and “or” property in auth(…).
In there you could define all your fields you want to export or hide and then also the actual rule for those fields.

1 Like

I don’t think dgraph should be advertised as “production-ready” (at least not for publicly-facing front-end use, i.e. the types of use cases given as examples in the docs) without this feature.

We’ve tried using dgraph several times over the past 2 or 3 years for small- to medium-sized projects, and every time there has been a showstopping feature missing for even simple apps – there used to be dozens, and now there are only a couple. Major props on the progress! However, this stands out as something that should be in the MVP of any GraphQL server used to serve external apps (as opposed to internal-only uses gated by a separate authorization layer).

I’m genuinely curious – how does anyone use this in production? Between this issue and the inability to place authorization restrictions on fields post-update (so e.g. users in a blogging app can’t spoof posts as someone else), are there really use cases where security just doesn’t matter at all?

We’re starting a new, more major project and got everything set up with dgraph only to run into this. It’s a big bummer! Not just because of the wasted development time, but also because we really wanted to use dgraph – a graph database fits our data and queries extremely well.

Unfortunately, this means we’re moving back to hasura, yet again. It’s extremely clunky but at least the production-ready software has a means of restricting access to querying and mutating specific fields for different users/roles.

In general, I’d strongly suggest taking a page out of hasura’s book with the way they handle authorization (though obviously not with their nightmarish approach to overall architecture): (a) give people a GUI (this goes for the rest of the schema as well; the inability to use the schema editor GUI with interfaces is rather unfortunate), and (b) encourage role-linked authorization rules (i.e. rules equivalent to ((role === customer) AND (userId === customerId))). Just to be clear, I’m aware that the latter is very doable with the @auth directive (I just didn’t feel like typing out the verbose, backslash-escaped details), but I think guiding users/suggesting it in the docs would be helpful to people who haven’t thought of structuring authorization in that manner.

Cheers, maybe our project won’t continue as long as we’re expecting and we can try dgraph again in a year or two.

5 Likes

Hi @JatinDevDG and @mrjn, was this feature released in the latest version? I’m looking to switch over to Dgraph for production and this is a must for us.

@jerber - I think it depends on your use case.

Protecting a user from querying a certain field is not possible yet without creating a new node, and blocking the entire node with an @auth rule.

However, this should be possible for mutations when the update-after validation is hopefully released in the near future with something like this:

queryUsers(filter: { not: { has: role } }

Which would keep a user from updating their role i.e.

This should be possible now for add mutations, but they could easily get updated until this feature is added.

This is sort of a backend way of securing the field, but hopefully one day this feature will be added as a standalone security rule as well.

J

@jdgamble555 got it. Is this on the roadmap?