HMAC Generation
This section provides descriptions and code examples of how to construct the HMAC Digest that is required to make an authenticated request to the Cloud9 APIs.
Every request to an API endpoint must be authenticated. Authentication is verified by Cloud9 through the customer providing an HMAC SHA512 signature that is generated with a public and private key created through the Cloud9 Portal.
The following description and code examples call for an HMAC SHA512 hash to be generated. This is not interchangeable with a SHA512 hash and submitting a SHA512 hash as the authentication to a request will cause it to be rejected. HMAC SHA512 is a well-defined standard for which Cloud9 never used custom libraries. Each code example in the following section details what standard library for the specified language is being used to generate the HMAC SHA512 hash.
All requests to REST endpoints must include an HMAC SHA512 authentication signature generated over the entirety of the request (headers and body) where the HMAC algorithm is salted with the secret key. This step allows Cloud9 to verify that the request has not been tampered with in transit.
The public key must be provided in every request allowing Cloud9 to verify the IP whitelist associated with the key against the source of the incoming request and that the key is valid and unexpired.
HMAC Signature
The Signature is an HMAC SHA512 hash of the entire contents of the request, including headers and body of the message. To generate the HMAC signature, you can use any standard HMAC SHA512 library in your preferred language. The API secret is used to seed the HMAC SHA512 hashing algorithm. The API key, along with the entire contents of the request (including headers and body) are combined into a string which is passed into the hashing algorithm. The resulting HMAC signature is provided in the Authentication header of the request and used by Cloud9 to verify that the customer's request is authentic and authorized.
HMAC Digest
The Digest is composed of four separate pieces: a prefix, the public API key used in the generation of the Signature, a globally unique identifier (guid), and the Signature.
The purpose of the Digest is for Cloud9 to verify both the authenticity and integrity of the request from a customer. To verify authenticity, Cloud9 compares the API public key against the key generated by the customer through the Cloud9 Portal. To verify message integrity, Cloud9 compares the Signature against a hash created on the received message with the customer’s public and private keys using the same methodology described on this page.
HMAC Signature and Digest Construction
The HMAC Signature is generated on the entirety of the request that will be sent to Cloud9, including all headers and the body of the request. To generate the HMAC Signature, the entire request should be provided in string format into your chosen HMAC library in the order specified as follows:
request type (ex. ‘POST’)
delimiter (ex. ‘\n’)
‘https’
delimiter
API URI and port (ex. ‘calldataapi.xhoot.com:443’)
delimiter
API endpoint (ex. ‘/v1/calls/metadata’)
delimiter
Content-Type (ex. ‘application/json’)
delimiter
API public key
delimiter
nonce (guid)
delimiter
request timestamp (ex. ‘Thu, 3 Dec 2019 05:27:23 GMT’)
delimiter
request body
delimiter
As an example, a complete string on which the HMAC SHA512 hash should be created would appear as follows:
'POST\nhttps\ncalldataapi.xhoot.com:443\n/v1/calls/metadata\napplication/j son\n' + api_public_key + '\n' + nonce + '\nThu, 23 Apr 2020 17:45:11 GMT\n{"beginDate": "2020-01-27 20:19:00","endDate": "2020-01-27 21:51:00","pageSize": 1000}\n'
There are no specific requirements on the length or type of the nonce so long as it is globally unique. The nonce is provided to ensure variability so that no two requests have identical Signatures.
It is important that all fields provided in the string on which the hash is computed are identical to the values and formatting of those fields as they appear in the request to Cloud9. In particular:
Ensure that the timestamp is generated once for the hash and message to avoid differences in the timestamp if it is generated separately for the hash and message.
Ensure the nonce is generated once to avoid difference in the nonce if it is generated once for the hash and once for the Digest.
Ensure that the body format is identical, paying particular attention to line feeds and carriage returns (if any) in the request body vs the body provided in the hash string.
Note that the request body is always required to compute the HMAC signature, even for requests that do not require a body (e.g. Monitoring API GET /userPresence). When an endpoint does not require a body, the request body should be set to a null (empty) string. Failing to do this will cause a signature mismatch when the request is checked, resulting in an HTTP 403.
As the body and date/times may change with each request, every new request to a Cloud9 API must have a newly computed HMAC Signature. An HMAC Signature generated from one request should never be used for another request as the request will be rejected for having an invalid Signature.
The HMAC Digest is the final value that will be provided in the Authorization header of the request. The Digest is composed as follows:
Algorithm (ex. ‘HMACSHA512’)
[space]
API public key
‘:’
nonce
‘:’
HMAC Signature (as a Base64 string)
An example of a complete Digest which would be put into the Authorization header is as follows:
HmacSHA512 ZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKSVV6VXhNaUo5LmV5SnpkV0lpT2lKRFlXeHNjeU JFWVhSaElpd2lZWFZrSWpvaU1UTWlMQ0poY0dsRmJuWWlPaUpRVWs5RUlpd2libUptSWpveE5U Z3dPRFl3T0RBd0xDSmhjR2xXWlhKemFXOXVJam9pTVM0d0xrZEJJaXdpYVhOeklqb2lZemtpTE NKbGVIQWlPakUyTVRJek9UWTRNREFzSW1saGRDSTZNVFU0TURreE1UazBObjAuRFNaTG9TU09a dzR0QUJEUnMzbWZ1QUVIRGZCRFNTR0xLbmJfUDRnTjFTZ0c2S09RdzlDcWZvdmxDNWlqbkoyM1 p3Q1lWTDNtYmNiOTBjRmFadURTbFE=:4b426367-7c46-4554-b4a7 dff043526862:Ldf+UUVyXf0moAz6quG5/KEHq2qLUSbczursglLa/on0ZTkgD3LQdtFJgWgG6 9MICOMJ/6fzbV2nh5Li/AK19w==
As previously mentioned, it is important that the nonce provided in the digest is the same nonce that was used in the Signature.
If a Digest is incorrectly formatted, the expected response is an HTTP 401. If a Signature does not match, the expected response is an HTTP 403. Cloud9 cannot determine the specific nature of what may be causing an invalid Digest or Signature. Under no circumstances should the API secret be transmitted to Cloud9 in any request.
Code Examples
The description and examples in this document demonstrate constructing the HMAC Digest for a Call Data API request, but the principles can be expanded to any of the Cloud9 APIs. As stated in the introduction, this section only provides details on the generation of the HMAC Digest. None of the code examples provide details of how an https request may be submitted to Cloud9 with the exception of the Javascript example.
The JavaScript code sample uses CryptoJS to calculate the HMAC. See https://cryptojs.gitbook.io for library details. It is up to the customer’s discretion how they prefer to make http requests – the following example uses Axios.
PHP has a native HMAC function as part of the language’s core libraries.
This code example uses RestTemplate from the Spring framework but any HTTP client can be used.
This Python implementation makes use of the HMAC library and request library. Note that json.dumps(body) is used when generating the HMAC signature and again when sending the request. This ensures that the data is exactly the same in both the signature and the request body.
This C# implementation is provided as a .NET Framework Console application for a Visual Studio app dev environment. The implementation makes use of a helper class to read in a separate apiKeys.txt file, which is provided after the code example below. This example makes use of the .NET System.Security.Cryptography library to provide the HMAC algorithm.
The following PowerShell example uses the System.Security.Cryptography library for the HMAC algorithm. It is important to Initialize() the HMAC object before using it, or an invalid signature will be generated.
Complete Message Exchange
For demonstration purposes, the following is a complete message exchange between a client requestor and the Cloud9 Monitoring API (audit endpoint). Sensitive information has been replaced with filler characters of the same type as would be expected in a real request/response.
Last updated