Skip to main content
Version: v2.x

Authentication Using Webhooks


You can configure the GraphQL Engine to use a webhook to authenticate all incoming requests to the Hasura GraphQL Engine server.

Authentication using webhooks

It is mandatory to first secure your GraphQL endpoint for the webhook mode to take effect.

In webhook mode, on a secured endpoint:

  • The configured webhook is called when the X-Hasura-Admin-Secret header is not found in the request.
  • The configured webhook is ignored when the X-Hasura-Admin-Secret header is found in the request and admin access is granted.

Configuring webhook mode

  • You can configure Hasura to run in webhook mode by running the GraphQL Engine with the --auth-hook flag or the HASURA_GRAPHQL_AUTH_HOOK environment variable (see GraphQL Engine server options), the value of which is the webhook endpoint.
  • You can configure Hasura to send either a GET or a POST request to your auth webhook. The default configuration is GET and you can override this with POST by using the --auth-hook-mode flag or the HASURA_GRAPHQL_AUTH_HOOK_MODE environment variable (in addition to those specified above; seeGraphQL Engine server options).

If you are running Hasura using Docker, ensure that the Hasura Docker container can reach the webhook. See this page for Docker networking.

Spec for the webhook


GET request

GET https://<your-custom-webhook>/ HTTP/1.1
<Header-Key>: <Header-Value>

If you configure your webhook to use GET, then Hasura will forward all client headers except:

  • Content-Length
  • Content-Type
  • Content-MD5
  • User-Agent
  • Host
  • Origin
  • Referer
  • Accept
  • Accept-Encoding
  • Accept-Language
  • Accept-Datetime
  • Cache-Control
  • Connection
  • DNT

POST request

POST requests will receive the contents of the request body in addition to client headers. Given a request like

query UserQuery($a: Int) {
users(where: { id: { _eq: $a } }) {

with variables {"a": 1}, the webhook will receive a request of the following form:

POST https://<your-custom-webhook>/ HTTP/1.1
Content-Type: application/json

"headers": {
"header-key1": "header-value1",
"header-key2": "header-value2"
"request": {
"variables": {
"a": 1
"operationName": "UserQuery",
"query": "query UserQuery($a: Int) {\n users(where: {id: {_eq: $a}}){\n id\n }\n}\n"

If you configure your webhook to use POST, then Hasura will send all client headers in payload.


If an invalid JSON request is sent, then the request body is not forwarded to the webhook



To allow the GraphQL request to go through, your webhook must return a 200 status code. You should send the X-Hasura-* "session variables" to your permission rules in Hasura.

HTTP/1.1 200 OK
Content-Type: application/json

"X-Hasura-User-Id": "25",
"X-Hasura-Role": "user",
"X-Hasura-Is-Owner": "true",
"X-Hasura-Custom": "custom value"

All values should be String. They will be converted to the right type automatically.


If the Set-Cookie HTTP headers are set by the auth webhook, they are forwarded by the GraphQL Engine as response headers for both GET/POST request methods.


If you want to deny the GraphQL request, return a 401 Unauthorized exception.

HTTP/1.1 401 Unauthorized

Anything other than a 200 or 401 response from webhook makes the server raise a 500 Internal Server Error exception.

Refreshing Websocket Connections

There is no default timeout on authorized websocket connection. You can optionally add one; to do so, you need to return either:

HTTP/1.1 200 OK
Content-Type: application/json

"X-Hasura-User-Id": "26",
"X-Hasura-Role": "user",
"X-Hasura-Is-Owner": "false",
"Cache-Control": "max-age=600"
  • an Expires variable, modeled on the Expires HTTP Header, to specify an absolute expiration time. The expected format is "%a, %d %b %Y %T GMT".
HTTP/1.1 200 OK
Content-Type: application/json

"X-Hasura-User-Id": "27",
"X-Hasura-Role": "user",
"X-Hasura-Is-Owner": "false",
"Expires": "Mon, 30 Mar 2020 13:25:18 GMT"

For websockets, if the Cache-Control or Expires fields are present in the response then a new request to the auth-webhook is made after the time specified in those fields and a new websocket connection is established.

Auth webhook samples

We have put together a GitHub Node.js repo that has some sample auth webhooks configured.

You can deploy these samples using glitch:


Once deployed, you can use any of the following endpoints as your auth webhook in the GraphQL Engine:


If you are using Firebase, you will have to set the associated environment variables.

Additional Resources

Enterprise Grade Authorization - Watch Webinar.