@auth doesn't filter on ID

Report a Dgraph Bug

It seems like @auth rules that filter a user type by a user id don’t actually do anything. I’ve seen this issue posted a few times but haven’t seen a solution. Wondering if anyone has a solution/workaround.

What version of Dgraph are you using?

v21.03.0-78-ge4ad0b113 (Dgraph Cloud)

Steps to reproduce the issue (command/config used to run Dgraph).

I have this schema

type Consumer
  @auth(
    query: {
      rule: """
      query ($USER_ID: ID!) {
        queryConsumer(filter: {id: [$USER_ID]}) {
          id
        }
      }
      """
    }
  ) {
  id: ID!
  name: String!
  ...other unrelated fields
}

and making this query

query {
  queryConsumer {
    id
    name
  }
}

with this decoded JWT

{
  "https://myapp.com/jwt/claims": {
    "USER_ID": "<A USER ID>"
  },
  "aud": "myapp"
  ...other unrelated fields
}

and this Authorization object

# Dgraph.Authorization {"VerificationKey":"...","Header":"X-myapp","Namespace":"https://myapp.com/jwt/claims","Algo":"HS256","Audience":["myapp"]}

Expected behaviour and actual result.

I’m getting back every Consumer in the database. I should just be getting back the Consumer in the USER_ID field in the JWT. I have tried pretty much every permutation I can think of for JWT structure, Dgraph.Authorization rules, @auth rules, etc. and I have only been able to get all the data or none of it.

Update: I can also mutate users that don’t match the JWT.

Hey @SHDavies,

How are you querying? Postman, etc? Or is this in an app? Can you send an example X-myapp header value that’s being sent?

Well, I found a workaround. I don’t like it, but it works:

type Consumer @auth(
    update: {
      rule: """
      query ($USER_ID: ID!) {
        queryConsumer {
          profileOwner(filter: {id: [$USER_ID]}) {
            id
          }
        }
      }
      """
    }
  ) {
  id: ID!
  ...
  profileOwner: Consumer!
}

It appears the problem is just filtering the results at the root level of the query.

I’ve used postman, in-app, and the dgraph cloud console. The header is just X-myapp: Bearer <JWT>

Shouldn’t the auth query be

queryConsumer(filter: {id: $USER_ID})

No brackets?

No, the type of ConsumerFilter has id: [ID!]. If I try that I get Variable type provided ID! is incompatible with expected type [ID!] during deployment.

Looks like it was discussed here: @auth rules filtering on id allows access to any resourse

As a workaround: if you have another edge that serves as a UID in Consumer, you can write the rule to restrict on that edge. For instance:

type Consumer @auth(
    query: {
      rule: """
      query ($NAME: String!) {
        queryConsumer(filter: {name: {eq: $NAME}}) {
          id
        }
      }
      """
    }
  ) {
  id: ID!
  name: String! @search(by: [exact])
}

I’ll have a look to see where this issue is in the backlog.

1 Like

Thanks!