Signing secret validation

Overview

To ensure secure communication and verify the authenticity of incoming requests, all requests to your endpoints include a signature in the x-seismic-signature header. This signature is generated using HMAC (Hash-based Message Authentication Code) with the request body as input.

Signature Validation

How the Signature is Generate

  • Signing Secret: A secret key generated in the app.
  • Request Body: The raw body of the incoming HTTP request.
  • HMAC Algorithm: SHA-256 is used as the hashing algorithm.
  • Hex Encoding: The resulting hash is encoded in hexadecimal format without the dashes.
  • Header: The signature is sent in the x-seismic-signature header. A separate header x-seismic-signature-old during signature rotation.

Here is a sample script that can be used to validate the signing secret that is sent with payloads coming from your Seismic hosted app.


private bool ValidateSignature(byte[] body, string secret, string headerName)
{
    // Check if the header exists
    if (!this.HttpContext.Request.Headers.TryGetValue(headerName, out var actualSignature))
    {
        return false; // Header is missing
    }

    // Compute the expected HMAC hash
    var key = System.Text.Encoding.UTF8.GetBytes(signingSecret);
    using (var hmac = new System.Security.Cryptography.HMACSHA256(key))
    {
        byte[] bodyHash = hmac.ComputeHash(body);
        var expectedSignature = System.BitConverter.ToString(bodyHash).Replace("-", "").ToLower();

        // Compare the computed signature with the actual signature (case-insensitive)
        return string.Equals(actualSignature, expectedSignature, StringComparison.OrdinalIgnoreCase);
    }
}

public async Task<IActionResult> RequestHandler()
{
    using (var memoryStream = new System.IO.MemoryStream())
    {
        // Read and copy the request body into memory
        await this.HttpContext.Request.Body.CopyToAsync(memoryStream);
        var body = memoryStream.ToArray();

        // Validate using the current signing secret
        if (ValidateSignature(body, signingSecret, "x-seismic-signature"))
        {
            return ProcessRequest();
        }

        // Validate using the old signing secret, if present
        // Optional but recommended for seamless secret rotation
        if (this.HttpContext.Request.Headers.ContainsKey("x-seismic-signature-old") &&
            ValidateSignature(body, oldSigningSecret, "x-seismic-signature-old"))
        {
            return ProcessRequest();
        }

        // Return unauthorized if neither signature validates
        return Unauthorized();
    }
}


// Your business logic
public IActionResult ProcessRequest()
{
    // Your business logic goes here
    return Ok();
}

📘

Case insensitive

Ensure the signature comparison is case-insensitive.

Timestamp verification

The following type of requests contains a timestamp in the payload.

  • App configuration extension
  • App installation callbacks such as install, uninstall, enable and disable notification
  • Scheduler extension request
  • App dynamic field replacement request

It is expected that all services use this timestamp to verify that the request is recent. It is recommended to check the timestamp is no more than 2 minutes old. Not building this check may lead to request replays. All timestamps are in yyyy-MM-ddTHH:mm:ssZ format and are based on UTC.

❗️

Timestamp verification is not supported for webhooks

The following request types does not have timestamp in payload and cannot be used for timestamp validation.

  • Webhook event deliveries
  • Event url challenge

Signing secret rotation

Signing secrets can be changed on the app. On generating a new signing secret, the old secret is not deleted, but rather Seismic sends two signatures in the header.

  • x-seismic-signature - This signature is generated from the new signing secret.
  • x-seismic-signature-old - This signature is generated from the old signing secret.

This allows app developers to update the new signing secret in their service without introducing any downtime.

Once the service has been updated with new signing secret, the old secret can be deleted from the App. Seismic will stop sending the x-seismic-signature-old header one the old secret is deleted.

🚧

Secret rotation delay

Changing signing secret may take 30 mins to an hour for the signatures in the request to use the new secret.

It recommended to add signature validation for both new and old signature in the header for easy rotation of signing secret.

Not supported

Signature is not added on following event url challenge request. This request is sent on adding or updating the url in the app.