Authentication

There are two sorts of keys in the dfuse ecosystem:

  1. A long-lived API key, which will resemble server_abcdef123123123000000000000000000, used to generate short-lived JWT.
  2. A short-lived JWT, used when performing any call on the dfuse Platform, which looks like:

eyJhbGciOiJLTVNFUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NTYxMzI4MjAsImp0aSI6IjQwNWVmOTUxLTAwZTYtNGJmNC1hZWMxLTU0NTU1ZWMzMTUwMiIsImlhdCI6MTU1NjA0NjQyMCwiaXNzIjoiZGZ1c2UuaW8iLCJzdWIiOiJ1aWQ6MHdlbnU2NmUwNzU4OWRhODY4MWNlIiwiYWtpIjoiM2NhYWEzYzA3M2FlZjVkMmYxOGUwNjJmZDkzYzg3YzMzYWIxYzA1YzEzNjI3NjU2OTgzN2Y5NDc5NzZlMjM0YSIsInRpZXIiOiJmcmVlLXYxIiwic3RibGsiOi0zNjAwLCJ2IjoxfQ.000HeTujIuS_LRvvPN6ZRCmtoZqZyV6P1enNBviwK8v7Tf7BLHJIrEpQoEREKSIMdZWPrMQl_OE55yJP0MxUDA

Obtaining a Long-Lived API Key

Once you have created an account through the dfuse portal you will be able to obtain an API key.

  1. Click on “GENERATE NEW KEY” and you’ll now be able to start customizing your key for your specific needs.
  2. First assign the API key a name so that you’ll be able to differentiate it from other API keys that you generate.
  3. Then, select the key-type between mobile, web, or server:

    • Mobile - adaptive rate limiting to ensure abuse prevention. The rate limiting thresholds will eventually be controllable by yourself. Mobile can handle a large number of IPs, with more granular rate limiting by IP.
    • Web - adaptive rate limiting to ensure abuse prevention. The rate limiting thresholds will eventually be controllable by yourself. JWTs generated by a Web key will be scoped to a small number of IPs, with heavier limiting of calls per IP. Web keys will have their Origin header verified to help with abuse prevention.
    • Server - Should be used for server-to-server data access. Aggressive rate limiting for JWT issuance, as the generated tokens should be cached and used for their lifespan. Accepts a large number of calls per IP.

For ease of identification, all keys will be prefixed by their key type.

Tip

Mobile and Web keys are safe to publish within your mobile or web application.

Obtaining a Short-Lived JWT

Once you have this API key, call the https://auth.dfuse.io/v1/auth/issue endpoint to obtain a fresh Authentication Token using the following command. Do not forget to replace the API key by your own!


curl -XPOST \
  -H "Content-Type: application/json" \
  --data '{"api_key":"web_abcdef12345678900000000000"}' \
  "https://auth.dfuse.io/v1/auth/issue"

fetch("https://auth.dfuse.io/v1/auth/issue", {
  method: "POST",
  body: JSON.stringify({
    api_key: "web_abcdef12345678900000000000"
  }),
  headers: {
    "Content-Type": "application/json"
  }
}).then(console.log) // Cache JWT (for up to 24 hours)

import requests

headers = {
    'Content-Type': 'application/json',
}

data = '{"api_key":"web_abcdef12345678900000000000"}'

# Cache JWT response (for up to 24 hours)
response = requests.post('https://auth.dfuse.io/v1/auth/issue', headers=headers, data=data)

package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
)

func main() {
    client := &http.Client{}
    var data = []byte(`{{"api_key":"web_abcdef12345678900000000000"}}`)
    req, err := http.NewRequest("POST", "https://auth.dfuse.io/v1/auth/issue", data)
    if err != nil {
        log.Fatal(err)
    }
    req.Header.Set("Content-Type", "application/json")
    resp, err := client.Do(req)
    if err != nil {
        log.Fatal(err)
    }
    bodyText, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatal(err)
    }

  // Cache JWT response (for up to 24 hours)
  fmt.Printf("%s\n", bodyText)
}

# Use this in your .bashrc to speed your development environment

# Replace this variable by an API key you got from https://app.dfuse.io
export DFUSE_KEY=server_AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
function dfusetoken {
    DFUSE_TOKEN=$(curl https://auth.dfuse.io/v1/auth/issue -s --data-binary '{"api_key":"'$DFUSE_KEY'"}' | jq -r .token)
    export DFUSE_TOKEN
}

The return value from the API is as such:


{
  "token":"eyJhbGciOiJLTVNFUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NTYxMzI4MjAsImp0aSI6IjQwNWVmOTUxLTAwZTYtNGJmNC1hZWMxLTU0NTU1ZWMzMTUwMiIsImlhdCI6MTU1NjA0NjQyMCwiaXNzIjoiZGZ1c2UuaW8iLCJzdWIiOiJ1aWQ6MHdlbnU2NmUwNzU4OWRhODY4MWNlIiwiYWtpIjoiM2NhYWEzYzA3M2FlZjVkMmYxOGUwNjJmZDkzYzg3YzMzYWIxYzA1YzEzNjI3NjU2OTgzN2Y5NDc5NzZlMjM0YSIsInRpZXIiOiJmcmVlLXYxIiwic3RibGsiOi0zNjAwLCJ2IjoxfQ.000HeTujIuS_LRvvPN6ZRCmtoZqZyV6P1enNBviwK8v7Tf7BLHJIrEpQoEREKSIMdZWPrMQl_OE55yJP0MxUDA",
  "expires_at":1556132820
}
token
required
String     The JWT to be used with all API calls, including WebSocket.
expires_at
required
Timestamp     An UNIX timestamp (UTC) indicating when the JWT will expire.

Our client-js library will handle the token issuance and caching for you if you decide to utilize it. You can also consult a working reference example if you would like to follow along with some sample TypeScript code.

Tip

To learn more about JWTs, you can consult https://jwt.io/introduction/.

Each JWT is valid for a period of 24 hours. Make sure to cache those values to avoid hitting rate limiting on JWT issuance.

Note

The token will be validated only upon connection establishment, and will never provoke a disconnection even if it expires during that connection’s lifetime.

Lifecycle of Short-Lived JWTs

Each JWT has an expiration date, so it is important to take that into account before making a request to the dfuse APIs. Here is the recommended procedure to take before making a request:

  1. Retrieve the JWT, and examine it’s expiration time
  2. If the JWT is past its expiration time, is near expiration, or is absent from cache, fetch a new one through the /v1/auth/issue endpoint, and cache the response.
  3. Call dfuse with the valid JWT token.

Each time you get a fresh JWT, it contains the updated expiration time and the token itself.

REST Authentication

To authenticate REST requests, specify an Authorization: Bearer [JWT token] header in the HTTP request. See more details


curl -H "Authorization: Bearer YOURTOKENHERE" -u https://mainnet.eos.dfuse.io/v0/state/... [ ... ]

eosc -H "Authorization: Bearer YOURTOKENHERE" -u https://mainnet.eos.dfuse.io [ ... ]

Don’t forget to replace the token in the above command with a valid JWT, retrieved using /v1/auth/issue

WebSocket Authentication

This example uses the https://github.com/hashrocket/ws command-line WebSocket program. To authenticate with query string, use this code:


ws wss://mainnet.eos.dfuse.io/v1/stream?token=YOURTOKENHERE

With browser-based WebSocket connections, it is not possible to specify additional headers. In this situation, pass your JWT as the token query string parameter.

You can pass the token query string parameter to authenticate REST or WebSocket requests.

The Origin Header

The Origin header is currently not mandatory on websocket connections.

It will, however, become mandatory at a later date, but only for web_ keys. It will then need to match the origin that you registered along with your API key identity. In a web environment, this is usually added automatically from the client’s browser without requiring extra work.

GraphQL Authentication

Using the apollo-client .

When doing POST calls to the /graphql endpoint, you must specify the Authorization header, exactly like any other REST calls.

GraphQL over gRPC Authentication

Using the language of your choice, use the OAuth2 authentication method with gRPC. Set the OAuth2 Access Token to be your JWT, and if required, specify Bearer as the method. This will set the authorization gRPC header, similiar to the HTTP header of the same name.

Refer to the official gRPC guides to see how to apply it to your language of choice.