How to write @auth incase of user role claim in JWT has a array format

Hi there,

I have the following schema in dgraph

type Todo {
    id: ID!
    text: String! @search(by: [term])
    owner: String!
}

I wanted to implement Role-Based Access control (RBAC) using the JWT token. My sample JWT token with role looks like below

{
  "http://abc.xyz.com//roles": [
    "admin",
    "superadmin"
  ],
  "nickname": "abc",
  "name": "abc@gmail.com",
  "picture": "",
  "updated_at": "2020-09-08T12:59:14.801Z",
  "email": "abc@gmail.com",
  "email_verified": false,
  "iss": "https://xxx.us.auth0.com/"
}

I know that I have use @auth directive in the schema to implement the authorization in the schema. I case if my claim contains “isAdmin”: “true” claim, I can write @auth in the below format

type Todo @auth(
    delete: { rule:  "{$isAdmin: { eq: \"true\" } }" },
) {
    id: ID!
    text: String! @search(by: [term])
    owner: String!
}

But in the given JWT sample above roles are in the array format. My requirement is to allow delete only if the user role is ‘admin’ or ‘superadmin’. My question here is how I write the @auth directive to check, in the above JWT whether the claim “http://abc.xyz.com//roles” contains ‘admin’ or ‘superadmin’. Maybe I need to write rule using “in” operator. But i don’t know how to do it. Can anybody help me to write @auth directive for my requirement? Thanks in advance.

Hi @sarankrishna, I assume you have added the # Dgraph.Authorization … line at the bottom of schema.

I don’t know how to do this. But please see if this helps. I have this JWT

"https://dgraph.io/jwt/claims": {
    "USER": "xxx@gmail.com",
    "ROLE": "ADMIN"
  },
  "given_name": "xxx",
  "family_name": "xx",
  "nickname": "xxx",
  "name": "xxx",

And I can use it in this way. Please see if you can do something similar.
Tagging @abhimanyusinghgaur if he can provide better way.

Not currently possible using arrays in Role Based Access Control.

Here was a related discussion:

That was about Booleans, but arrays are not supported either. I know I saw that somewhere here in the forum, just can’t find it right now. It might have been when @gja initially walked me through it that I picked that up.

Anyways, the only way to accomplish this right now would be to convert that array to single properties:

{
  "http://abc.xyz.com//admin": "true",
  "http://abc.xyz.com//superadmin": "true",
  "nickname": "abc",
  "name": "abc@gmail.com",
  "picture": "",
  "updated_at": "2020-09-08T12:59:14.801Z",
  "email": "abc@gmail.com",
  "email_verified": false,
  "iss": "https://xxx.us.auth0.com/"
}

Not sure though that you were not trying to use http://abc.xyz.com//roles as the claims portion of your JWT. If that was the case then it would need to look like:

{
  "http://abc.xyz.com/claims": {
    "isAdmin": "true",
    "isSuperAdmin": "true",
  },
  "nickname": "abc",
  "name": "abc@gmail.com",
  "picture": "",
  "updated_at": "2020-09-08T12:59:14.801Z",
  "email": "abc@gmail.com",
  "email_verified": false,
  "iss": "https://xxx.us.auth0.com/"
}
2 Likes

@Naman Thanks for the response. I already added # Dgraph.Authorization line in the bottom of the schema. But my question was how to write the query/add/delete/update condtion when JWT contains the arrary of roles.

@amaster507 Thanks for the response. I did exactly the same as you mentioned above(2nd way).

Currently, the only way to achieve this is to break the array into single values as @amaster507 mentioned. But we will add support for arrays in RBAC rule in the upcoming release.

1 Like

Has this landed in production yet? If not, will it come in November?

I have marked this issue as accepted. It won’t be part of the 20.11 release but we’ll take it up in the one after that.

1 Like