HMAC Authentication
Overview
HMAC (Hash-based Message Authentication Code) is an authentication protocol that allows you to integrate the Mekari API faster than OAuth2. However, an HMAC credential (consisting of CLIENT ID
and CLIENT SECRET
) is tied to one specific company, which means you can only perform API requests that are limited to your company data in Mekari Product.
For example, if your company is already a Talenta subscriber and you want to get a list of your employees who have registered on Talenta, you’ll need new HMAC client credentials with the appropriate scopes. Using these credentials, you can generate an HMAC signature and attach it to your request header when making an API call to one of our API endpoints.
If you have multiple Mekari product subscriptions, you must have HMAC client credentials for each company in order to successfully perform API calls to our API endpoints.
Currently, one HMAC credential is also limited to each Mekari product, which means that if your company subscribes to multiple Mekari products (for example, Talenta and Klikpajak), you must create one HMAC credential for each product API you wish to access.
HMAC Credentials
We are currently developing a platform that will allow you to create your own HMAC credentials. For the time being, if you require HMAC credentials, please contact our customer support or a product specialist. From there, we will assist you in creating new HMAC credentials for your company as well as selecting the appropriate application scopes for the credentials.
API Availability
Not all Mekari product API endpoints can be accessed via HMAC authentication. Please visit our Product API section to learn more about the APIs available for HMAC authentication.
Authorization Header
When using HMAC authentication to call Mekari API endpoints, the Authorization
header is required. We expect your application to send the Authorization
header with the following parameterization.
credentials := "hmac" params
params := keyId "," algorithm ", " headers ", " signature
keyId := "username" "=" plain-string
algorithm := "algorithm" "=" "hmac-sha256"
headers := "headers" "=" "date request-line"
signature := "signature" "=" plain-string
plain-string = DQUOTE *( %x20-21 / %x23-5B / %x5D-7E ) DQUOTE
parameter | description |
---|---|
username | The CLIENT_ID of the HMAC credential |
algorithm | Digital signature algorithm used to create the signature, in this case hmac-sha256 . |
headers | List of HTTP header names, separated by a single space character, used to sign the request. In this case date and request-line |
signature | Base64 encoded digital signature generated by your application. |
An example of an authorization header on your application request is as follows:
Authorization: hmac username="YOUR_CLIENT_ID", algorithm="hmac-sha256", headers="date request-line", signature="xxxx"
Generating Signature
You must have a signature on your API request, as you can see from the parameter and the example above. The following code (pseudocode) was used to generate this signature:
function generate_hmac_auth_token:
input:
client_id: string
client_secret: string
base_url: string
pathWithQueryParam: string
http_method: string
date_rfc_1123 = now().format(RFC7231)
signing_string = "date: \n HTTP/1.1"
digest = HMAC-SHA256(signing_string, client_secret)
base64_digest = base64(digest)
hmac_auth_token = `hmac username="", algorithm="hmac-sha256", headers="date request-line", signature=""`
return hmac_auth_token
Please see our code examples section for a specific implementation in your preferred programming language.
Date Header
Along with the Authorization header, you must also include the Date header in your API request. It must have the current datetime in UTC timezone, as specified in RFC7231. If you look at the above signature generation, you will notice that it also uses a datetime string, and the value between that and the Date header must be the same.
An example of a Date header:
Date: Sun, 06 Nov 1994 08:49:37 GMT
The Date
header is also used to prevent replay attacks and has a clock skew of 300 seconds. It means that the time difference between the time you send the API call and the datetime you specify in the Date
header and the signature must be less than 300 seconds. Otherwise, the request will be rejected.
Body Validation
You need to provide Body Validation on your API request. This is because we need protect the API call from Man-in-the-Middle attacks (MITM). To do this, you need add a new header to your request called Digest
, which contains the SHA-256 hash of your request body, which is required when performing a POST
, PUT
, PATCH
, or DELETE
request.
The Digest
header should be formatted as follows:
digest=SHA-256(body)
base64_digest=base64(digest)
Digest: SHA-256=<base64_digest>
In cURL, this is an example of the Digest
header:
curl --request POST 'https://examples.com/foo/bar' \
--header 'Digest: X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=' \
--data-raw '{"hello": "world"}'
Please keep in mind that the content of the Digest
header is determined by the body of your request. This means you probably don’t want to use the Digest
header on API calls that require a large request body, such as APIs that require an upload file, because it will generate a larger Digest value.
Please see our code examples section for a specific implementation in your preferred programming language.
Final Result
After you’ve met all of the prerequisites listed above, your API request should look like this in cURL format:
curl --request POST 'https://examples.com/foo/bar?hello=world' \
--header 'Authorization: hmac username="CLIENT_ID", algorithm="hmac-sha256", headers="date request-line", signature="r70pUQMDXWaFUEWPybBbn9d+ae2naufbIckiT6wcAio="' \
--header 'Date: Tue, 24 Aug 2021 02:18:19 GMT' \
--header 'Content-Type: application/json' \
--header 'Digest: SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=' \
--data-raw '{"hello": "world"}'
The actual implementation may differ depending on the programming language used. Please consider looking at to see the examples of the code below.