Adding Stir/Shaken Attestation with Sansay NSS API


If you have a requirement to add a Stir/Shaken attestation to calls leaving a FreePBX/PBXact system and you have an account with the Sansay NSS service, you can apply headers by making an API call on each outbound call using the modifications described herein. There are a few third party services that will assist with generating S/S attestations for SIP calls, Sansay NSS does not rely on an SBC or proxy between the PBX and the provider.

This information is current as of 2022-05-20. Subsequent developments in FreePBX, Asterisk or in Sansay's APIs may render it obsolete. Start a new thread on thr FreePBX forum to discuss issues.


  • FreePBX/PBXact version 15/16. Not tested with other versions but will likely work with little or no modification

  • Account with Sansay NSS service

  • A Stir/Shaken certificate

  • Sansay portal has been configured with the WAN source IP of the PBX API requests, CID numbers and the S/S cert

Step 1 - Predial Hook

On the PBX we need to add some custom Asterisk dialplan that is executed on every outbound trunk call. Edit the file /etc/asterisk/extensions_custom.conf and add the following:

[macro-dialout-trunk-predial-hook] exten => s,1,Noop(Entering user defined context macro-dialout-trunk-predial-hook) exten => s,n,Set(signature=${SHELL(/var/lib/asterisk/bin/ ${CALLERID(num)} ${CALLERID(dnid)})}) ; get s/s signature using Sansay bash script and assign to channel var exten => s,n,Set(sig_length=${LEN(${signature})}) exten => s,n,Set(signature=${signature:0:$[${sig_length}-1]})      ; in testing, the script always returns sig with a trailing <cr> character which malforms the SIP INVITE, this line removes it exten => s,n,GoSub(func-set-sipheader,s,1(Identity,${signature}))  ; add signature to outbound SIP channel Identity header using FreePBX built in subroutine exten => s,n,MacroExit() ; end macro-dialout-trunk-predial-hook

Step 2 - Create the Sansay Script

On the PBX create the file /var/lib/asterisk/bin/ Substitute your actual NSS domain name from the Sansay portal in place of Probably best to request the latest version of the get_shaken bash script from Sansay support. At the time of this writing, ver 1.0 looks like this:

#!/bin/bash # Bash client to use Sansay NSS API with Asterisk # version 1.0 # Script arguments are orig_tn and dest_tn as follows " 8587542200 8587542211" # Generate unique Request ID Request_ID=`echo $RANDOM | md5sum | head -c 20` # Send Request to Sansay NSS # sub actual url domain curl --silent -k -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -H "X-RequestID: $Request_ID" -d "{\"signingRequest\":{\"orig\":{\"tn\":\"$1\"},\"dest\":{\"tn\":[\"$2\"]},\"iat\":$(date +%s)}}" | jq .signingResponse.identity | sed 's/\"//g; s/\\//g'

Step 3 - Change script ownership and make it executable

Sansay script must be accessible by the Asterisk service

chown asterisk:asterisk /var/lib/asterisk/bin/ chmod +x /var/lib/asterisk/bin/

Step 4 - Script Dependencies

Note the Sansay bash script uses echo, md5sum, head, curl, jq, and sed. A stock FreePBX Distro/PBXact system will not have jq installed by default. Install with

Step 5 - Apply Config

You need to Apply Config before the dialplan changes become live. This can be done with the red Apply Config button in the FreePBX GUI or by using the command


After the reload, all outbound calls that use a configured trunk on the PBX will launch the above bash script, which will make an API call to the Sansay NSS service, get a signature string, and add that string as an Identity header to the SIP INVITE being sent to the provider. If you're using unencrypted signaling you can observe the SIP signaling packets directly with sngrep, or in all cases by enabling debug at the Asterisk console.


Return to Documentation Home I Return to Sangoma Support