How to sign API

In order to communicate with the Privacy Data API you need to make a signed request to the Quadrata API server.

Request signatures are signed messages using an ECDSA private signing key and verified on the Quadrata API using the corresponding public signing key.

Private signing keys are not known to Quadrata. You should take industry standard best practices to protect your private key.

Authentication

You will need to authenticate by providing your Quadrata Login API Key, using HTTP Basic Authentication. This will allow the server to map your dApp's API Login Key to your public signing key.

Authorization: Basic {base64(API_KEY)}

This is the same API key you use to get an access token for the onboarding flow.

Signing Message Format

When verifying a request signature, the Quadrata API will attempt to create the signing message using the HTTP request and verify it with your public signing key. Since the API needs to generate a signature, you need to follow a specific generation strategy.

Included in the signing message:

  1. The HTTP request method (uppercase)

  2. The absolute request path

  3. The query string, if one is used in the request

  4. The HTTP Date header

  5. A one time use nonce, if provided

It is suggested to use a nonce to ensure signatures are always unique.

The signature has a short lifetime of 15 seconds. This is known from the HTTP Date header, which must be present in the signing message.

Signing Message Rules

  • Each part of the signing message should be joined using a new line.

  • The path is always the absolute path, so it must begin with a /

  • If the query string is not included in the request, it should be omitted completely. If it is included in the request, it should not contain the question mark ? in the signing message.

  • The signature needs to be base64-url encoded.

  • If a nonce is used, it should be appended to the signature, delimited with a period . and also base64-url encoded.

Signing Message Example

const sigParts = [
    method.toUpperCase(),
    path,
    queryString,
    date,
    nonce
];

const signingMessageStr = sigParts
    .filter(str => str && str.length !== 0)
    .join('\n');

const signature = await signMessage(privateKey, signingMessageStr);

let signatureHeader = base64UrlEncode(signature);
if (nonce && nonce.length !== 0) {
    signatureHeader += '.' + base64UrlEncode(nonce);
}

Last updated