I'm currently using Auth0 with Hasura for a React project, and I've run into some confusion when it comes to authentication.
Hasura documentation states you can pass x-hasura-role
to your request to specify the users role. This is great for testing as I can easily jump between roles, and is easy to do with the Hasura console.
However, I don't want this option to be available for production, then any user could just specify x-hasura-role=admin
in the request header and they'd have full admin access. I assumed these flags would be disabled in production, and that those roles would be pulled form the signed JWT key with the Hasura claims.
What I'd like to do is for Hasura to pull "role" (x-hasura-role
) from my Authorization
JWT token, which looks like this when decoded:
{
"https://hasura.io/jwt/claims": {
"x-hasura-role": "admin",
"x-hasura-default-role": "user",
"x-hasura-allowed-roles": [
"admin",
"user"
],
"x-hasura-user-id": "auth0|42a80d679dc71e396ce57cd1"
},
...
}
So really I have 2 questions:
- Does Hasura allow variables like
x-haura-role
in production? If so, what's the appropriate way to handle this? - Do I need to pull the
x-hasura-role
out of my JWT key myself and pass it via my Apollo Client? Again, I don't see how this would work in production, as anyone could just setx-hasura-role
, why can't Hasura just pull it from it's "Hasura Claims" that I added?
I feel like I'm missing a piece of information somewhere here, thank you!
CodePudding user response:
So it seems instead of using x-hasura-role
, if I set x-hasura-default-role
to my desired role, it works as expected. This is odd, since it should only use x-hasura-default-role
if no x-hasura-role
is available, unless I'm reading this wrong:
https://hasura.io/docs/latest/graphql/core/auth/authentication/jwt/#the-spec
Anyways, for now I'm setting x-hasura-default-role
and getting the desired behaviour.
CodePudding user response:
I think you're close to having the full picture here but are still missing some of the specifics.
Assuming you're not also passing the x-hasura-admin-secret
header (you shouldn't except maybe for testing and profiling queries), Hasura will read the roles from the JWT if it can be verified correctly against the JWT secret that needs to be registered with Hasura.
The x-hasura-default-role
that is signed in the token payload is the role that will be used to evaluate the GraphQL request as you've seen.
The point of the x-hasura-role
header however, is that it can change the role that the request will be executed under as long as the specified role is also inside the x-hasura-allowed-roles
array that is inside your signed token.
Image you had the following token:
{
x-hasura-default-role: "member",
x-hasura-allowed-role: ["member", "teammate"]
}
In this case, it would be possible to set the x-hasura-role
header to teammate
and then the request would be evaluated using a different set of permission rules.
This is not a security feature because once the user has been granted a token and if they're smart, they could make requests using either role. So you should only put roles in the x-hasura-allowed-roles
array if you are completely comfortable with the user having access to that role.
However, this can be helpful in some application contexts where you want to evaluate a different set of permission rules based on where the users is in the app. Eg. if they're on the team page your application code can send the header on their behalf so access a simplified set of permissions that make sense for that context.