graphql-engine icon indicating copy to clipboard operation
graphql-engine copied to clipboard

support arrays in custom JWT claims

Open litchfield opened this issue 5 years ago • 29 comments

Support for custom claims is great! But it chokes when we try to use an array --

code: “jwt-invalid-claims”
path: “$”
message: “x-hasura-* claims: expected Text, encountered Array”

Use case here is user "groups" (multiple). Not essential but including in the JWT would simplify our permission rules and save us some joins.

litchfield avatar Mar 29 '19 03:03 litchfield

Hi @litchfield, we already have a PR in the works which adds support for arrays in session variables. I am guessing that would cover this case too.

@nizar-m @ecthiender Will https://github.com/hasura/graphql-engine/pull/1799 cover this use case too?

shahidhk avatar Mar 29 '19 08:03 shahidhk

It should. Related issue #1333 .

@shahidhk @nizar-m

ecthiender avatar Mar 29 '19 09:03 ecthiender

Closing this issue now. @litchfield feel free to re-open, should the related issue not solve your problem 🙂

marionschleifer avatar Jul 09 '19 14:07 marionschleifer

Reopening, as this was never implemented. This was closed by mistake, I am guessing.

PS: It was implemented in #1799 but that never got merged. Instead #2475 got merged which did not add support for this.

ecthiender avatar Oct 25 '19 11:10 ecthiender

Is there any workaround at least for this feature? I'm using v1.0.0-beta.8 and I I need to filter by allowed organizations too and getting the same message:

{"errors":[{"extensions":{"path":"$","code":"jwt-invalid-claims"},"message":"x-hasura-* claims: expected Text, encountered Array"}]}

:'(

celvin avatar Oct 29 '19 01:10 celvin

@celvin This might be of help https://docs.hasura.io/1.0/graphql/manual/auth/authorization/roles-variables.html#format-of-session-variables

rikinsk avatar Oct 29 '19 06:10 rikinsk

+1 — Need this functionality as well.

I have sessioned users who need access to team data in multiple teams. A x-hasura-team-ids array of team.id strings would make this doable. Currently no way of allowing access to multiple team data without this functionality.

@rikinsk That section mentions use of arrays, but it is not doable in beta.9.

CC @ecthiender Any ETA?


Edit: I managed to get around with a public view, but concerned I may hit another snag without session arrays.

simpleshadow avatar Dec 22 '19 00:12 simpleshadow

@0x777 Any updates here?

tirumaraiselvan avatar Jan 15 '20 10:01 tirumaraiselvan

FYI, the array value can be sent as Postgres array literal which looks like "x-hasura-array-val": "{t1,t2,t3}". This issue is for supporting the format [t1,t2,t3].

tirumaraiselvan avatar Apr 13 '20 07:04 tirumaraiselvan

Need this feature,

otherwise, for a multi-tenant app, you might need to write Hasura Action for every query/mutation out there...

Any update on this?

In the documentation:

You can find this is allowed for x-hasura-allowed-roles:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true,
  "iat": 1516239022,
  "https://hasura.io/jwt/claims": {
    "x-hasura-allowed-roles": ["editor","user", "mod"],
    "x-hasura-default-role": "user",
    "x-hasura-user-id": "1234567890",
    "x-hasura-org-id": "123",
    "x-hasura-custom": "custom-value"
  }
}

So why we can not use it for the other claims?

Furthermore, the Postgres Array type is not a valid JSON format, one needs to manipulate JSON string to get it work. Not to mention, when work with AWS, which does not support JSON typed claims, so you have to pass a JSON string, and in that JSON string, we can only put a stringfied array there, like "{1,2,3}", because otherwise, JSON.stringfy won't even work., will this stringfied array still work?

Albert-Gao avatar May 23 '20 13:05 Albert-Gao

Not sure if this helps I use something like this with nodejs , it will only works for the strings tho

function toPgArray(arr) {
  const m = arr.map(e=> `"${e}"`).join(",")
  return `{${m}}`
}

const ids = ["e63baafd-a10f-4d88-8828-0d423d698522"];
toPgArray(ids) 

results in

{
  "https://hasura.io/jwt/claims": {
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true,
  "iat": 1516239022,
    "x-hasura-allowed-organisations": "{\"e63baafd-a10f-4d88-8828-0d423d698524\"}"
  }
}

the other solution would be to make proxy service that can convert arrays in claim to pg array format

patrykwegrzyn avatar Jun 22 '20 18:06 patrykwegrzyn

Is this expected to be resolved?

Jrodseth avatar Jan 03 '21 21:01 Jrodseth

This feature would greatly simplify how we set permissions on our data. We currently have to load roles from a central auth provider into a local table just so we can then setup relationships to this table from all of our resources. When having a JWT that includes and array of roles would save us from having to keep a local copy of these roles for each user.

As stated by others - it seems like it would be possible since it already allows arrays for the x-hasura-allowed-roles property.

brettpappas avatar Mar 20 '21 01:03 brettpappas

I am also looking forward to this feature. Our users who belong in multiple organizations need permissions for all of them, and currently we are doing what @brettpappas is. Having it integrated would be extremely convenient.

pmazumder3927 avatar Mar 24 '21 20:03 pmazumder3927

From @tirumaraiselvan's answer:

FYI, the array value can be sent as Postgres array literal which looks like "x-hasura-array-val": "{t1,t2,t3}". This issue is for supporting the format [t1,t2,t3].

Formatting the array like this in the JWT worked for me!

vancy-pants avatar Jun 18 '21 18:06 vancy-pants

Also looking forward to this feature. Thanks for a great product!

etegan avatar Aug 27 '21 13:08 etegan

Is this solved yet?

miradnan avatar Jan 27 '22 21:01 miradnan

Is this solved yet?

With Keycloak i am still facing issues. Can't map x-hasura-allowed-roles. Getting Your requested role is not in allowed roles and invalid x-hasura-allowed-roles; should be a list of roles: parsing [] failed, expected Array, but encountered String

ghost avatar Jan 31 '22 13:01 ghost

are there any updates? I am trying to put all keycloak groups of user into a x-hasura-allowed-groups array for easy permission handling on the tables in hasura. otherwise I would need to add custom checks to various queries and also change code in the backend.

an update on this would help us a lot

EDIT: I found a solution - a workaround mentioned in this documentation https://hasura.io/docs/latest/graphql/core/auth/authorization/roles-variables/#format-of-session-variables just format the array like this {test1, test2, test3} (postgres array format). This way, if you are working with hasura, it is handled as array and you add a permission like this. {"group":{"_in":"X-Hasura-Allowed-Groups"}}.

for people who work with keycloak as well: using the oidc-group-membership-mapper wont work because it'll try to put an array claim to the hasura claims which wont work. therefore add a script mapper and format your claim as needed (this is only available with certain keycloak preferences and also this feature will be removed from future keycloak releases, but for me it was the only workaround that fitted)

magdastone avatar Mar 28 '22 12:03 magdastone

just format the array like this {test1, test2, test3} (postgres array format)

What would that look like in the JWT, would that be a string with that syntax {test1, test2, test3}?

jasonmccallister avatar Apr 22 '22 21:04 jasonmccallister

@jasonmccallister

yes, in the claim itself it is formatted as string. like this "x-hasura-allowed-groups": "{test1,test2,test3}" I am not quite sure about the spaces. Remove them just to be safe. In hasura permissions you can check the groups "array" like this: {"Team":{"_in":"x-hasura-allowed-groups"}}

magdastone avatar Apr 27 '22 15:04 magdastone

:+1: from me as well.

It doesn't seem to make sense that allowed roles are passed as an array but custom claims have to be packed into some kind of pseudo array. I'd also like to inspect the JWT for the list I'm adding in my UI to avoid an unnecessary round trip. However, that requires me to parse the Postgres array syntax on the frontend which is quite awkward.

christian-detexian avatar Oct 14 '22 00:10 christian-detexian

This seems to be resolved. When my claims object includes a key/value like this:

"x-hasura-company_ids": "{\"5ea8271d-fd4e-4531-84c9-022e80bf634a\",\"d1ad3989-e1ec-491b-85e5-be47ae1db501\"}",

I can make permissions that work as expected like this:

Screen Shot 2023-02-23 at 4 25 27 PM

dminkovsky avatar Feb 23 '23 21:02 dminkovsky

This seems to be resolved. When my claims object includes a key/value like this:

This comment above makes it clear that it is not. What you are describing is the workaround that works because you pass your list straight to Postgres. The issue is about being able to use a JSON list.

christian-detexian avatar Feb 24 '23 00:02 christian-detexian

Just chipping in here.

I'm using clerk and their new(ish) organizations feature. They have a couple of features I'd love to be able to use

image

But the JWT they generate causes issues in hasura:

image

The first is org.id (which can be null) The second is user.organization which is an object

commandodev avatar Apr 20 '23 09:04 commandodev

Coming back because we will upgrade Keycloak soon. As my workaround requires a keycloak version where script mappers are still allowed I need to come up with another workaround because... I just pulled the newest docker hasura/graphql-engine (22.33.2) and I am still getting the same error when trying to add a custom array hasura claim: x-hasura-* claims: parsing Text failed, expected String, but encountered Array

The only option for me now is writing a java plugin for keycloak and I really don't want to do this :( Did anyone come up with another workaround?

magdastone avatar Sep 05 '23 12:09 magdastone

The same issue. And the same with KeyCloak. It is obvious claims have to work like array as well. @magdastone have you written keycloak plugin already?

089-ilya avatar Nov 22 '23 08:11 089-ilya

@089-ilya sorry to disappoint :( the priority of this issue at my workplace declined… when the time comes (and I think this will at least take another 6months due to other, more important stuff) I will share the plugin in this post

magdastone avatar Nov 22 '23 09:11 magdastone

@magdastone Thanks anyway!

089-ilya avatar Nov 22 '23 10:11 089-ilya