JetBrains Space Help

Verify Requests from Space

If your application is supposed to receive requests from Space (for example, a chatbot that listens to requests on some endpoint), it should be able to verify whether the incoming requests are authentic.

There are two ways to do this:

  • Verification token– the application compares a verification token in the request to the verification token stored in the application. This method is easier to implement but is less secure.

    If you use Space SDK to develop your application, you can verify the token with the ApplicationPayload.verifyWithToken(verificationToken: String) method. Learn more

  • Signing key– the application calculates hash for each request using a signing key and compares the calculated hash to a hash in the request. This is the recommended verification method.

    If you use Space SDK to develop your application, refer to Space SDK | Verify Requests for details on how to implement the signing key verification method.

You can generate both a verification token and a signing key in the Endpoint tab of the application settings.

Verify requests from Space

Verifying requests using a verification token

The typical verification workflow looks as follows:

  1. During registration of your application, Space can issue it a verification token. To get the token, you should open the Endpoint tab of the application settings and click Generate under Verification token.

  2. Save this token in your application, for example, as a string constant.

  3. When Space sends a request to your application, it puts this verification token in the request body. For example, this is how the body of a slash command request looks like (a user presses / in the chatbot's channel):

    { "className": "ListCommandsPayload", "accessToken": "", "verificationToken": "d415ca5965b37f4f0cac59fd33de7b94e396284e897d0fb8a070d0a5e1b7f2d3", "userId": "2kawvQ4F6GM6" }

  4. The task of the application is to get the verificationToken from the request payload and compare it to the token stored in the application. If they are equal, the application is allowed to process the request, if not, the application must return the HTTP 401 Unauthorized response code.

Verifying requests using a signing key

The idea of this method is that Space uses a special signing key to generate a hash for every request it sends to your application. The hash is sent in the request as well. In turn, your application has to use the same signing key to calculate a hash of a received request. Then it should compare the calculated hash value with the hash value in the request.

We recommend using this method instead of the verification token as it is more secure. The typical verification workflow looks as follows:

  1. During registration of your application, Space can issue it a signing key. To get the key, you should open the Endpoint tab of the application settings and click Generate under Signing key.

  2. Save the signing key in your application, for example, as a string constant.

  3. Before Space sends a request to your application, it calculates the request hash using the generated signing key and puts it into the X-Space-Signature header. For example, this is a sample Space request including headers:

    POST /api/back-to-space HTTP/1.1 Host: 12345abcdef.ngrok.io User-Agent: Space (61355) Ktor http-client Content-Length: 163 Accept: */* Accept-Charset: UTF-8 Content-Type: application/json X-Forwarded-For: 123.456.123.456 X-Forwarded-Proto: https X-Space-Signature: 2aa8cba6217a28686de0ca8dcfe2a1d0795e343d744a0c5307308e43777593a5 X-Space-Timestamp: 1607623492912 Accept-Encoding: gzip {"className":"ListCommandsPayload","accessToken":"","verificationToken":"d415ca5965b37f4f0cac59fd33de7b94e396284e897d0fb8a070d0a5e1b7f2d3","userId":"2kawvQ4F6GM6"}
  4. Now, it's the application's turn to calculate the request hash. To do this:

    1. Get the value of the X-Space-Timestamp header and the request body.

    2. Generate a string consisting of the timestamp and the body. Use colon : as a delimiter. For example in Kotlin, it can look like follows:

      val str = "$timestamp:$body"
      In case of the sample request above, the str value would be:
      1607623492912:{"className":"ListCommandsPayload","accessToken":"","verificationToken":"d415ca5965b37f4f0cac59fd33de7b94e396284e897d0fb8a070d0a5e1b7f2d3","userId":"2kawvQ4F6GM6"}

    3. Use HMAC SHA256 to hash the string.

  5. Compare the calculated hash with the one you get from the X-Space-Signature header. If they are equal, the application is allowed to process the request, if not, the application must return the HTTP 401 Unauthorized response code.

Last modified: 23 June 2021