Concerns about authentication/authorization in DGraph with GraphQL endpoint

Hi Everyone,

I have been experimenting with Slash and DGraph for about a week now. Disclaimer: I am new to both. I have two major concerns so far:

  1. @auth directive

I really liked the way DGraph creating authorization using @auth directive. It feels very powerful and probably allows to accommodate very complex scenarios.

Using string rules in @auth seems like a step back, as I am not getting IDE’s intellisence support there, the way I get it with fragments, for instance. This would be also very useful in refactoring scenarios, especially in complex rules definitions.

It is also little clumsy with string rules for example "{$isAuthenticated: { eq: \"true\" } }" (two spaces after “true”) will fail to get updated, but "{$isAuthenticated: { eq: \"true\" } }" (one space after “true”) will be fine. Can you spot the difference? It took me a while to realize that.

  1. Authentication.

When creating the schema in my app, I am expecting the public accessible endpoint to my application return 401 if there is no JWT token is provided or in the case when it does not validate with the public key.

The main reason here is to avoid DOS attack (especially to protect service credits). However, the empty header curl request is still returning response from the endpoint.

It would be very nice to have an ability to configure that behavior. Or it would be even better completely protect all resources from the start if Dgraph.Authorization is set and make public only very specific resources with some designated decorator.

There is two type of auth rules: RBAC and ABAC. ABAC rules are basically GraphQL queries so you can write them independently in some GraphQL client.
Example:

type User @auth(
  delete: { and: [
    { rule: """
    query($USER: String!) {
        queryUser(filter: { username: { eq: $USER } }) {
        __typename
        }
    }
    """ },
    { rule: """
    query {
        queryUser(filter: { isPublic: true }) {
            __typename
        }
    }
    """}]
  }
){
  username: String! @id
  age: Int
  isPublic: Boolean @search
  disabled: Boolean
  tickets: [Ticket] @hasInverse(field: assignedTo)
  secrets: [UserSecret]
  issues: [Issue]
  tweets: [Tweets] @hasInverse(field: user)
}

The rule is basically a GraphQL query:

    query($USER: String!) {
        queryUser(filter: { username: { eq: $USER } }) {
        __typename
        }
    }

We use regex matching to parse RBAC rules so this should be an easy fix.

Having public key in schema doesn’t mean we would block request not having JWT. We block only those requests for types that have auth rules associated with it. Types having no auth rules would still work without the JWT token.

Thanks for the reply. Most of the points above I understand.

I realized that, hence the concern: rather than be opened by default, it is better being closed by default (as soon as you have validation public key set). This is more secure from my perspective. Then @auth rules can be set, including completely making public some resources if needed.

There is a post around here somewhere (I am on my mobile rn) about a feature request to add root auth rules that apply to the entire schema.

Yes. We will work on making it configurable. I am marking this as accepted and it will be picked up soon. We will keep you updated regrading the progress.