Foundation Data & Integrations
Inbound Authentication for Integrations
13 min
servicely supports a number of authentication methods for inbound integrations basic authentication basic authentication is the simplest, but most insecure authentication mechanism basic authentication passes a username and password (unencrypted) in the http headers basic authentication can be disabled on an instance by setting the application property system auth basic enable to false api token authentication api tokens provide a simple mechanism to provide controlled access to the servicely apis, while providing a basic level of control and validation of the authentication process api tokens can be used either with or without a shared secret and request level verification bearer authentication token bearer tokens are the simplest form of password less authentication bearer tokens are sent in the http headers of a request, and provide a very simple mechanism to set up an integration with minimal effort however, bearer tokens provide no protection against man in the middle (mitm) attacks, and provide no mechanism to validate the identity of the sender, or of the integrity of the message bearer authentication can be disabled on an instance by setting the application property system auth bearer enable to false bearer authentication token (provided by url) to use this functionality, you need to be on version 1 10 or later an alternate object for bearer tokens is where they are provided via a url such as http //example servicely ai/v1/itsmwork?token=xxxx this is not typically a preferred way, as it does not provide protection against man in the middle (mitm) attacks, and provide no mechanism to validate the identity of the sender, or of the integrity of the message by default, this is disabled, however, you can enabled it by setting the application property system auth bearer token url enable to true going to the available value table (specifically the following record #/availablevalue/617185e6bb4211ef937dba899352c358) and making it active if you use this mechanism, we strongly suggest utilising the url allowed paths field to secure further hmac (hash based message authentication codes) hmac defines a mechanism to provide validation of both the authentication, and validation of the message structure, based on an api token and a shared client secret servicely provides two levels of hmac authentication hmac header the hmac header scheme provides a simple mechanism to provide an extra layer of validation over bearer tokens the hmac header validation uses a shared secret key and hashing to validate that authenticity of the sender this provides a level of confidence that the message originated from someone who knew the shared secret (i e protects against some mitm attacks); however, it does not provide any validation that the message structure was received unmodified testing with postman create a request and use the following ‘pre request script’ to set up the hmac header authentication // this is your token and shared secret let token = "gx8joyntbvop9 cltzmnytsvk2tnvbwu7amwyfrroa7k24"; let sharedsecret = "l9yddaong7cbuclgmgivtyuelhwcigfy"; // set the date as the utc string format let formatteddate = (new date()) toutcstring(); // hash the date with hmac256 and base64 the result let hasheddate = cryptojs enc base64 stringify(cryptojs hmacsha256(formatteddate, sharedsecret)); // add the date header pm request headers upsert({ key "date", value formatteddate }); // add the authorization header pm request headers upsert({ key "authorization", value "hmac " + token + " " + hasheddate }); multiple header support servicely can perform the hmac hash on multiple headers, allowing you to customise the level of validation of the message in the system api token definition, the header fields can be specified in the ‘header key’ field (comma separated) on the client side, the hmac needs to be calculated on all of the header values concatenated with a colon character ( ) below is an example postman script to work with the above example // this is your token and shared secret let token = "nneypres5yjw3 cvultz1po5c3eufngn4ss2bmzdnhbqgb"; let sharedsecret = "5bnd61nfv58foqnmiopjja1edlrbiwzw"; // this is an example of hashing multiple fields let customvalue = pm variables replacein('{{$guid}}') // set the date as the utc string format let formatteddate = (new date()) toutcstring(); // the complete string to hash let tohash = formatteddate + " " + customvalue; // hash the date with hmac256 and base64 the result let completehash = cryptojs enc base64 stringify(cryptojs hmacsha256(tohash, sharedsecret)); // add the date header pm request headers upsert({ key "date", value formatteddate }); // add the custom header (in servicely, specify the 'header key' = \[date,x custom]) pm request headers upsert({ key "x custom", value customvalue }); // add the authorization header pm request headers upsert({ key "authorization", value "hmac " + token + " " + completehash }); hmac body the hmac body scheme combines hashing of both the authorisation (api token) and of the content of the message body and headers this provides the ability to validate both authenticity (the message is from a trusted party) and integrity (that the message has not been altered in transit) of the request the amazon web services (aws) apis are a high profile example of an api that uses this authentication scheme http requests will be signed with a shared secret key using hmac the string to sign format is \<method>\n \<content md5>\n \<content type>\n \<date>\n \<url> example string to sign post vvqhe1k/ubrcowe0fah95g== application/json tue, 12 jan 2016 14 57 28 gmt /v1/incident example authorization header with hmac signature authorization hmac dpklk3jcjdgnz wt5zfsfdpjajltjcgudq8f6bbzkytqbm\ smoxggvwwjjmlt4swtyh9qb5r/boqujrb6jrwecnwvm= testing with postman create a request and use the following ‘pre request script’ to set up the hmac authentication // this is your token and shared secret let token = "dpklk3jcjdgnz wt5zfsfdpjajltjcgudq8f6bbzkytqbm"; let sharedsecret = "xhwrfk236jz1mjo1skgt4h4oqvyp5cji"; // set the date as the utc string format let formatteddate = (new date()) toutcstring(); // ensure the content type is set let contenttype = "application/json" let separator = "\n"; // newline separator let bodymd5 = ""; // if the request has a body, we need to md5/base64 it if (pm request body tostring() != "") { bodymd5 = cryptojs enc base64 stringify(cryptojs md5(pm request body tostring())); } // then build the message to sign in this format let stringtosign = request method + separator + bodymd5 + separator + contenttype + separator + formatteddate + separator + pm request url getpath(); // hmac sha256 and base64 the body string using the shared secret let signed = cryptojs enc base64 stringify(cryptojs hmacsha256(stringtosign, sharedsecret)); // add the date header (ensure it is present and the same as the signed copy) pm request headers upsert({ key "date", value formatteddate }); // ensure the content type is present pm request headers upsert({ key "content type", value contenttype }); // if we have a body, add the content md5 header if (bodymd5 != "") { pm request headers upsert({ key "content md5", value bodymd5 }); } // finally, add the authorization header pm request headers upsert({ key "authorization", value "hmac " + token + " " + signed }); generating api tokens to generate a system api token, navigate to administration → integration → system api tokens → new fill in the mandatory fields (name, validation type, hash method, impersonate user), and click the ‘generate token’ button a new token and secret will be generated and displayed it is important to copy this information and store it somewhere safe the information can not be regenerated on the servicely side to ensure no one can ever get the information required to authenticate from the application (the token itself is hashed and never stored servicely only stores the token prefix before the dot) restricting token use new in 1 9 as part of the token setup, you can also restrict which url paths the token can be used for such as, if the token is for a specific integration, you can restrict the token to only be accessible with path note that if it has not been populated, the token will be usable based on the impersonated user’s normal permissions and restrictions an example of this is populating it with /controller/controllername , so the token can only be used for that controller note that if you want multi paths here, you can comma separate it, such as /controller/controllername,/controller/bidirectionalincidentvendorcontroller