The API uses HMAC signing to ensure the requests are valid and originate from the requesting client. Each client of the API will use a set of keys that will be used to sign each request, providing it's identity and ensuring it's validity.

Keys

Clients will be able to generate HMAC keys through the Portal UI. You may create one key pair to be used by all systems that publish data, or create multiple separate key pairs for each publishing application.

Each pair will consist of a ClientAccessKey and a ClientSecretKey. Below is a sample set of keys:

Client Access Key
ecc21f08-5428-407f-be22-f59628b946c3
Client Secret Key
KUv5kFx9mLa3FFk3YGx2dqw4tCB8Dam2VYy3bKS4Ooy6hKk4Ogw4nWT7dmX2tkc9

HTTP Headers

The publish API requires an Authorization header on each request which contains the HMAC signing information. This header contains all the information needed to identify the sender, as well as validate the request. It must be uniquely generated for each request sent to the APIs.

The following pseudo code depicts how the HMAC signature and header are generated:

StringToSign = HTTP-Verb + "\n" +
    RequestPath + "\n" +
    RequestTimestamp + "\n" +
    Nonce + "\n"

Signature = ToHex( HMAC-SHA256( ClientSecretKey, StringToSign ) )

Authorization = "hmac" + " " +
    ck=ClientAccessKey + "," +
    ts=RequestTimestamp + "," +
    n=Nonce + "," +
    sig=Signature

Field Definition

ClientAccessKey
The identifying key provided to you that uniquely identifies the requestor.
ClientSecretKey
The secret key provided to you that is used to sign the request.
HTTP-Verb
The HTTP Request method, POST, GET, PUT, etc. always in caps.
RequestPath
The HTTP path of the request, not including the Scheme or Hostname.
RequestTimestamp
The UNIX time of request, in seconds.
Nonce
A UUID type 4, generated specifically per request.
Signature
The resulting HMAC signature generated from the above data fields.

Example

An example request would be as follows. Although the Authorization header shown here has new lines for readability, an actual header would not have them.

POST /publish/v1/events HTTP/1.1
Host: api.journera.com
Date: Tue, 27 Mar 2018 19:42:41 +0000
Host: localhost
User-Agent: curl/7.43.0
Accept: application/json
Content-Type: application/json
Content-Length: 1252
Authorization: hmac ck=547c8037-241c-4b63-8c04-e4a1b0a76a89,
  ts=1477669126,n=d0c1a8e9-cd65-4f75-953f-2ce298871dda,
  sig=a65a746eb8d1614ed42a5645a35d24a10e45d5427c379d384bb3f283eefd71ea

{ ... json encoded request payload ... }
The StringToSign for this request would be:
POST
/publish/v1/events
1477669126
d0c1a8e9-cd65-4f75-953f-2ce298871dda

Validation

In order to validate the request, the following rules will be honored regarding the fields in the HMAC signature:

Timestamp
The timestamp marks the time at which the HMAC signature was generated. A timestamp is only considered valid for five minutes. After that, the request will be rejected with an invalid signature. This helps ensure request playback is not possible. Timestamp validation also allows for the value to be a small time in the future to deal with clock skew issues, but this is only on the order of a few seconds.
NONCE
The nonce is a "used once" value. Each request will be signed with a nonce that cannot be used again. This prevents a request from being played back into the system and will remain in the validation cache for five minutes. However, the nonce value is only stored in the cache after the request has been successfully processed and the response has been sent back. This allows the sending system to resend a request that had a momentary failure and needs to be retried.

Working together, these two HMAC signature values ensure a request can only be sent to our system one time.

Testing

We have a small python script that will generate HMAC signatures from the command line that may help with testing.

Python v2.x:
hmacgen-v2.py
Python v3.x:
hmacgen-v3.py

Here is an example execution using the sample request above.

$ ./hmacgen-v2.py -k ecc21f08-5428-407f-be22-f59628b946c3 -s KUv5kFx9mLa3FFk3YGx2dqw4tCB8Dam2VYy3bKS4Ooy6hKk4Ogw4nWT7dmX2tkc9 -m POST -p /publish/v1/events -t 1477669126 -n d0c1a8e9-cd65-4f75-953f-2ce298871dda
Dihedral HMAC Generator
-- HMAC Parameters ------------------------------------
Method:    POST
Path:      /publish/v1/events
Timestamp: 1477669126
Nonce:     d0c1a8e9-cd65-4f75-953f-2ce298871dda
Secret:    K ... tkc9
-------------------------------------------------------
HMAC: c89cca4c4f04a21d0b04449aa4b2e727cdad10fbe5aaa69f4e6bc889e575fc60
-------------------------------------------------------
Authorization: hmac ck=ecc21f08-5428-407f-be22-f59628b946c3,ts=1477669126,n=d0c1a8e9-cd65-4f75-953f-2ce298871dda,sig=c89cca4c4f04a21d0b04449aa4b2e727cdad10fbe5aaa69f4e6bc889e575fc60
-------------------------------------------------------