Based on Personalization account configuration, API calls may require HMAC authentication in the form of a HMAC-SHA256 message hash as a header within the request. HMAC is a keyed-hash authentication code that calculates a message authentication code (MAC) involving a cryptographic hash function in combination with a secret cryptographic key. SHA256 is one kind of cryptographic hash function used in the calculation of an HMAC header; the resulting algorithm is known as HMAC-SHA256.
Profiles API calls authenticate using HMAC v2 to protect your data and ensure that your secret keys stay secure, while using the Access Key ID and secret access key associated with your Personalization subscription.
Important
Profiles API calls support authentication only with HMAC v2.
Acquia has HMAC implementation scripts in several languages, including the following:
- HTTP HMAC Signer for Ember
- HTTP HMAC Signer for Go
- HTTP HMAC Signer for JavaScript
- HTTP HMAC Signer for PHP
- HTTP HMAC Signer for Ruby
For more information about the HMAC implementation that is in use, see the Acquia HMAC spec.
- Setting HMAC authentication as an HTTP request
- Response
- Managing HMAC authentication in Personalization Web
- Code examples
Setting HMAC authentication as an HTTP request¶
In the Profiles API, HMAC authentication is set as a header in an HTTP request. The HTTP client signs the request by adding the following HTTP headers:
Authorization : <HMACAuthorization>
X-Authorization-Timestamp : <Unix Timestamp In Seconds>
X-Authorization-Content-SHA256 : <HashedContent> (if Content-Length > 0)
Creating the authorization header¶
To create the authorization header, include the following attributes:
realm
: The provider—for example,Acquia
orMyCompany
id
: The API key’s unique identifier, which is an arbitrary stringnonce
: A hex version 1 or 4 UUIDversion
: The version of HMAC this request usesheaders
: A list of additional request headers that are to be included in the signature base string—these are lowercase, and are separated with the semicolon (;
) charactersignature
: The Base64-encoded signature as described in Creating the signature
Ensure that each attribute value is enclosed in double quotes and percent encoded.
Creating the signature¶
The signature is a Base64-encoded binary HMAC-SHA256 digest generated from the following elements:
Base64 Hashed SecretKey
: The API key’s shared secret. The secret key must be a 256 to 512 bit binary value. The secret key will normally be stored as a Base64-encoded or hex-encoded string representation, but must be decoded to the binary value before use.StringToSign
: A concatenated string generated from the following parts:HTTP-Verb
: The uppercase HTTP request method. For example,GET
orPOST
.Host
: The hostname in lowercase, matching the HTTP Host request header field, including any port number.Path
: The HTTP request path with leading slash. For example,/resource/11
.QueryParameters
: Any query parameters or empty string, which should be the exact string sent by the client, including percent encoding.AuthorizationHeaderParameters
: Normalized parameters similar to section 9.1.1 of OAuth 1.0a, which uses the following parameters:- id
- nonce
- realm
- version
Parameters are sorted by name and separated by
&
with name and value separated by=
. They are percent encoded.AdditionalSignedHeaders
: The normalized header names and values specified in the headers parameter of the authorization header Names should be lowercase, sorted by name, separated from value by a colon, and the value followed by a newline (so each extra header is on its own line). If there are no added signed headers, an empty line should not be added to the signature base string.X-Authorization-Timestamp
: The value of the X-Authorization-Timestamp header, a Unix timestamp (integer seconds since Jan 1, 1970 UTC) - required for all requests If this value differs by more than 900 seconds (15 minutes) from the time of the server, the request will be rejected.Content-Type
: The lowercase value of theContent-type
header or an empty string if absent (omit ifContent-Length
is0
)Body-Hash
: The Base64-encoded SHA-256 digest of the raw body of the HTTP request, for POST, PUT, PATCH, DELETE or other requests that may have a body (omit this parameter ifContent-Length
is0
) This value should be identical to the string sent as the X-Authorization-Content-SHA256 header.
X-Authorization-Content-SHA256 header¶
This header is the Base64-encoded SHA-256 hash value used to generate the signature base string. It is required for any request where Content-Length
is not 0. For example, a POST request with a body. This header should be provided by the client to ensure that the request body it sent was not tampered on its way to the server. After the server receives the request body, it forms the Body-Hash
, and then compares it to the request body again.
Example¶
In the following example, the HTTP Authorization header and signature are constructed:
HMACAuthorization = "acquia-http-hmac" + " " +
"realm=" + Provider + "," +
"id=" + AccessKey + "," +
"nonce=" + HexV4OfRandomUUID + "," +
"version=" + HMACVersion + "," +
"headers=" + AdditionalSignedHeaderNames + "," +
"signature=" + HMACSignature
AdditionalSignedHeaderNames = "" or
Lowercase( HTTP-Header-Name ) [ + ";" + Lowercase( HTTP-Header-Name ), for additional headers]
HMACSignature = Base64( HMAC-SHA256 ( SecretKey, UTF-8-Encoding-Of( StringToSign ) ) )
StringToSign = HTTP-Verb + "\n" +
Host + "\n" +
Path + "\n" +
QueryParameters + "\n" +
AuthorizationHeaderParameters + "\n" +
[ AdditionalSignedHeaders, If the headers attribute is not empty, + "\n" ] +
X-Authorization-Timestamp +
[ "\n" + Content-Type +
"\n" + HashedContent, if Content-Length > 0 ]
AuthorizationHeaderParameters = "id=" + URLEncode( AccessKey ) + "&" +
"nonce=" + URLEncode( HexV4OfRandomUUID ) + "&" +
"realm=" + URLEncode( Provider ) + "&" +
"version=" + URLEncode( Version )
AdditionalSignedHeaders = Lowercase( HTTP-Header-Name ) + ":" + HTTP-Header-Value
[ + "\n" + Lowercase( HTTP-Header-Name ) + ":" + HTTP-Header-Value, for additional headers]
(must be sorted by Lowercase( HTTP-Header-Name ) )
HashedContent = Base64( SHA256 ( Request-Body ) )
"\n"
denotes a Unix-style line feed (ASCII code 0x0A).
Setting HMAC authentication using a GET method¶
In the following example, HMAC authentication is set using a HTTP GET method.
https://example-liftapi.lift.acquia.com/dashboard/rest/EXAMPLEINC/segments?site_id=10
X-Authorization-Timestamp: 1432075982
In this example, the authorization header contains the following values:
realm
:AcquiaLiftWeb
id
:Ra9YgrsKAcXDLMexg44N
nonce
:d1954337-5319-4821-8427-115542e08d10
Base64 Hashed SecretKey
:KgFBhwQMC4wZ6Ls9u7UNbX6jV4xEt5Xvetr9zCEQ
Signature-Base-String
is:
GET
example-liftapi.lift.acquia.com
/dashboard/rest/EXAMPLEINC/segments
site_id=10
id=Ra9YgrsKAcXDLMexg44N&nonce=d1954337-5319-4821-8427-115542e08d10&realm=AcquiaLiftWeb&version=2.0
1432075982
Note
Content type and body hash are omitted for GET methods.
The request signature is 4wYr5sIgw5C3f6CjO2UGimuCmrwm+PFtZ2CjyW5+7j4=
This value is created by signing the Signature-Base-String
with the hashed SecretKey
.
The authorization header is:
acquia-http-hmac realm="AcquiaLiftWeb",id="Ra9YgrsKAcXDLMexg44N",nonce="d1954337-5319-4821-8427-115542e08d10",version="2.0",signature="4wYr5sIgw5C3f6CjO2UGimuCmrwm+PFtZ2CjyW5+7j4="
The full HTTP request is:
GET /dashboard/rest/EXAMPLEINC/segments
Host: example-liftapi.lift.acquia.com
X-Authorization-Timestamp: 1432075982
Authorization: acquia-http-hmac realm="AcquiaLiftWeb",id="Ra9YgrsKAcXDLMexg44N",nonce="d1954337-5319-4821-8427-115542e08d10",version="2.0",signature="R6y7kWkBnUdcSNXMxh4Vib6wSSHYKY4srCA1d4unW78="
Setting HMAC authentication using a POST method¶
In the following example, HMAC authentication is set as an HTTP request using a POST method.
https://example-liftapi.lift.acquia.com/dashboard/rest/EXAMPLEINC/event_import
X-Authorization-Timestamp: 1449578521
Content-Type: application/json
The body of the request contains the following values:
{"identity":"[email protected]","identity_source":"email","event_name":"Content View",
"event_source":"web","event_date":"2015-11-05 10:22:03.111","engagement_score":"15",
"identities":{"fb_event_import_eg":"facebook"}};
X-Authorization-Content-SHA256
is zC4p8Oa+aw6pTdoW1uFN0ngemDjd5QlZXBK5tcUKzCw=
. This value is the SHA256-encoded request body.
In this example, the authorization header contains the following values:
realm
:AcquiaLiftWeb
id
:Ra9YgrsKAcXDLMexg44N
nonce
:64d02132-40bf-4fce-85bf-3f1bb1bfe7dd
- Base64 Hashed SecretKey -
eox4TsBBPhpi737yMxpdBbr3sgg/DEC4m47VXO0B8qJLsbdMsmN47j/ZF/EFpyUKtAhm0OWXMGaAjRaho7/93Q==
Signature-Base-String
is:
POST
example-liftapi.lift.acquia.com
/dashboard/rest/EXAMPLEINC/event_import
id=Ra9YgrsKAcXDLMexg44N&nonce=64d02132-40bf-4fce-85bf-3f1bb1bfe7dd&realm=AcquiaLiftWeb&version=2.0
1449578521
application/json
zC4p8Oa+aw6pTdoW1uFN0ngemDjd5QlZXBK5tcUKzCw=
Note
The preceding code example contains an empty line. This is because there are no query parameters being passed in the URL. Omitting this line may cause this code example to not work properly.
The request signature is: sW4t14rZvcZDEpJwwWWkqCRwTUYiKVAK2aHURtBCIrU=
The authorization header is:
acquia-http-hmac realm="AcquiaLiftWeb",id="f0d16792-cdc9-4585-a5fd-bae3d898d8c5",nonce="64d02132-40bf-4fce-85bf-3f1bb1bfe7dd",version="2.0",signature="sW4t14rZvcZDEpJwwWWkqCRwTUYiKVAK2aHURtBCIrU="
The full HTTP request is:
POST /dashboard/rest/EXAMPLEINC/event_import
Host: example-liftapi.lift.acquia.com
X-Authorization-Timestamp: 1449578521
Content-Type: application/json
Request body: {"identity":"[email protected]","identity_source":"email","event_name":"Content View","event_source":"web","event_date":"2015-11-05 10:22:03.111","engagement_score":"15","identities":{"fb_event_import_eg":"facebook"}}
X-Authorization-Content-SHA256: zC4p8Oa+aw6pTdoW1uFN0ngemDjd5QlZXBK5tcUKzCw=
Authorization: acquia-http-hmac realm="AcquiaLiftWeb",id="efdde334-fe7b-11e4-a322-1697f925ec7b",nonce="d1954337-5319-4821-8427-115542e08d10",version="2.0",signature="R6y7kWkBnUdcSNXMxh4Vib6wSSHYKY4srCA1d4unW78="
Response¶
The server responds to the client’s request by constructing a header and signature.
Response header¶
The following example illustrates construction of the HTTP X-Server-Authorization-HMAC-SHA256 header and signature for all non-HEAD requests:
HMACServerAuthorization = Base64( SHA256 ( ResponseStringToSign ) )
ResponseStringToSign = Nonce + "\n" +
X-Authorization-Timestamp + "\n" +
Response-Body
Response signature¶
The response signature base string is a concatenated string generated from the following elements:
Nonce
: The nonce that was sent in the Authorization headerX-Authorization-Timestamp
: The timestamp that was sent in the X-Authorization-Timestamp headerResponse-Body
: The response body (or empty string)
Example¶
The following is an example of a response signature base string:
Response body - {"id": 133, "status": "done"}
Nonce - d1954337-5319-4821-8427-115542e08d10
X-Authorization-Timestamp - 1432075982
Base64 encoded secret key - eox4TsBBPhpi737yMxpdBbr3sgg/DEC4m47VXO0B8qJLsbdMsmN47j/ZF/EFpyUKtAhm0OWXMGaAjRaho7/93Q==
Signature-Base-String
is:
d1954337-5319-4821-8427-115542e08d10
1432075982
{"id": 133, "status": "done"}
The signed response is: M4wYp1MKvDpQtVOnN7LVt9L8or4pKyVLhfUFVJxHemU=
The full HTTP response is:
Response body - {"id": 133, "status": "done"}
X-Server-Authorization-HMAC-SHA256 - M4wYp1MKvDpQtVOnN7LVt9L8or4pKyVLhfUFVJxHemU=
Response validation¶
Requests using the GET method will return a response with a X-Server-Authorization-HMAC-SHA256
header. This header is created when the response Signature-Base-String
is signed with the client’s secretKey
.
Managing HMAC authentication in Personalization Web¶
Although HMAC is enabled by default, you can disable it for troubleshooting.
To either enable or disable HMAC authentication:
- Sign in to Personalization as an administrator, and then click the Admin tab.
- In the System menu, click Manage customers.
- In Account ID, click your ID.
- In the API Authentication settings, depending on the API call you are using, select or clear the appropriate checkboxes to either enable or disable your HMAC authentication settings:
- Enable Segment REST Api HMAC Authentication: Controls HMAC authentication for segment calls in the Profiles API
- Enable Event Import REST Api HMAC Authentication: Controls HMAC authentication for event imports in the Profiles API
- Enable File Export REST Api HMAC Authentication: Controls HMAC authentication for file exports in the Profiles API
- Enable Visitor Query REST Api HMAC Authentication: Controls HMAC authentication for visitor queries in the Profiles API
Code examples¶
We have developed several code examples you can use to help you understand how to make calls to the Profiles API reference using different programming languages:
- PHP code example: Makes a call to the Profiles API based on the parameters you have provided.
getMakeAPICall
is the entry point of the example. Java code example
Makes several calls to the Profiles API. The entry point of the example is themain
method.