Skip to main content
Version: v2.x

Quickstart Auth

In this quickstart, we'll use a JWT and permissions to limit a query to only the user making the request. We're using our sample app, which you can read more about below. If you don't use the sample app, you'll need to ensure your data model includes a users table and modify the values of the encoded and decoded JWT to match your user's information.

DOCS E-COMMERCE SAMPLE APP

You can use this quickstart with any project, but it pairs well with our docs e-commerce sample app, which you can deploy to Hasura Cloud with one click below. If you've already deployed the sample app, access your existing project.

Deploy to Hasura Cloud

Step 1: Add an environment variable

Depending on how your instance is deployed, you can either use the GUI or your configuration files to set this secret.

Head to your Project's settings page and click on the Env vars option in the side navigation:

Authentication and authorization with Hasura

Once there, click on New Env Var and select HASURA_GRAPHQL_JWT_SECRET from the Key field. Paste this value into the environment variable's value field:

{
"key": "oursupersecretsupersecurekey1234567890",
"type": "HS256"
}

Click Add:

Authentication and authorization with Hasura

Step 2: Create a user role

Head to the Data tab of the Hasura Console. If you have a users table, select it from the list on the left-hand side, and open the Permissions tab:

Authentication and authorization with Hasura

As you can see, we currently only have an admin role. To make access to data more granular, we'll create a new role by entering user into the text input. After entering the name of the role, click the ❌ in the select column:

Authentication and authorization with Hasura

Configure the Row select permissions by choosing With custom check and pasting the following value in the editor on line 1:

{ "id": { "_eq": "X-Hasura-User-Id" } }

Configure the Column select permissions by clicking Toggle All:

Authentication and authorization with Hasura

Finally, click Save Permissions.

Step 3: Add a header in the GraphiQL explorer

Head back to the API tab and add a new row to the Request Headers. Enter this key:

Authorization

And this value:

Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IlNlYW4iLCJlbWFpbCI6InNlYW5kZW1vQGhhc3VyYS5pbyIsImlhdCI6MTUxNjIzOTAyMiwiaHR0cHM6Ly9oYXN1cmEuaW8vand0L2NsYWltcyI6eyJ4LWhhc3VyYS1hbGxvd2VkLXJvbGVzIjpbInVzZXIiLCJhZG1pbiJdLCJ4LWhhc3VyYS1kZWZhdWx0LXJvbGUiOiJ1c2VyIiwieC1oYXN1cmEtdXNlci1pZCI6IjdjZjBhNjZjLTY1YjctMTFlZC1iOTA0LWZiNDlmMDM0ZmJiYiJ9fQ.jSp42PsCa4r-2ObfopkiDBvTn9nDysIv-NOIEnU3wR0

Check the box next to Authorization; the final result should look like this:

Authentication and authorization with Hasura

Step 4: Test it out

Before demonstrating the access control you just designed, run the following query:

query GetUsers {
users {
id
email
name
}
}

You should see an array of 5 records returned:

{
"data": {
"users": [
{
"id": "7cf0a66c-65b7-11ed-b904-fb49f034fbbb",
"email": "[email protected]",
"name": "Sean"
},
{
"id": "82001336-65b7-11ed-b905-7fa26a16d198",
"email": "[email protected]",
"name": "Rob"
},
{
"id": "86d5fba0-65b7-11ed-b906-afb985970e2e",
"email": "[email protected]",
"name": "Marion"
},
{
"id": "8dea1160-65b7-11ed-b907-e3c5123cb650",
"email": "[email protected]",
"name": "Sandeep"
},
{
"id": "9bd9d300-65b7-11ed-b908-571fef22d2ba",
"email": "[email protected]",
"name": "Abby"
}
]
}
}

Uncheck the x-hasura-admin-secret request header. Re-run the query; this time, your output should be similar to this:

{
"data": {
"users": [
{
"id": "7cf0a66c-65b7-11ed-b904-fb49f034fbbb",
"email": "[email protected]",
"name": "Sean"
}
]
}
}
Did you see that?!

If you weren't watching closely, you may have missed it. When you deselected your admin secret in the request headers and used only the authorization header, the available schema changed to what you defined in step 2 🔥

You can see that in the screenshot below, the only field available to the user is the users table:

Authentication and authorization with Hasura

Recap

What did we just do? Well, you just implemented a JWT-based authorization system with Hasura 🎉

Is this production-grade? Not quite. In a real-world application, you'd need to generate and verify the JWTs on the server-side. You'd also need to implement a mechanism to refresh the JWTs. What we've demonstrated is how Hasura utilizes the JWT to determine the role of the user and the permissions that they have access to.

The environment variable we set up in the beginning contains a secret; this secret is used to encode your JWTs wherever they're generated, be it on your own server, a third-party service, or even a client-side library. Hasura is agnostic about how or where you generate your JWTs. Saving that secret as an environment variable allows Hasura to decode the JWTs and verify that they're valid.

If you're curious about the composition of the JWT, you can view the decoded version one of two ways. By visiting this link, you can see the payload and other data associated with the JWT we used in this example. Alternatively, Hasura provides a JWT decoder tool that you can use to decode any JWT. You can utilize this by clicking the "detective" icon next to the Authorization header's value in the GraphiQL explorer.

The permissions we set up in step 2 are the most basic form of access control. We created a new role called user and limited the rows returned on the users table to only those whose id matches the x-hasura-user-id claim in the JWT.

As you can see from the example, Hasura automatically provides a schema that only exposes the users table to the user role. This is a great way to limit the exposure of your data to the outside world and ensure that your users only have access to the data they're authorized to see.