Fun Call Flows Using SHAKEN/STIR Caller ID Attestation Levels
Time to read: 7 minutes
Sick of being SHAKEN down by robocallers? In this post, we will STIR it up by using Caller ID Attestation levels to route inbound calls with various Programmable Voice features.
What is SHAKEN/ STIR?
Let’s start from the beginning. Well, maybe not the very beginning – but let’s start with a basic understanding of the SHAKEN and STIR protocols and how they are currently implemented.
- STIR - Secure Telephone Identity Revisited
- STIR is a protocol developed by IETF, describing the process of verifying if a party is allowed to use a certain number.
- SHAKEN - Signature-based Handling of Asserted Information Using toKENs
- SHAKEN focuses on how STIR should be implemented and deployed to carrier networks.
Before the early 2000s, caller ID spoofing was much more difficult. As SIP started gaining popularity, spoofing increased because SIP From numbers could be very easily changed without the recipient knowing.
You may also have noticed robocalls coming from numbers with the same area code or exchange as your own number. This tactic, while less egregious than using the IRS 800 number as a From
, can still deceive end users by making them think the caller is familiar or from their area. For instance, I might think a call from the same local exchange is from my doctor, school, or someone in my community.
The Do Not Originate (DNO) List came a long way in preventing the spoofing of high-profile and recognizable numbers. SHAKEN/STIR goes further, and enables originating carriers to digitally sign the call with an Attestation Level. The Attestation Level applied to the call indicates the certainty level of the originating provider and whether the caller is actually allowed to use the Caller ID.
- Full Attestation (A) - The identity of the caller is known, and they have the right to use the Caller ID for this call.
- Partial Attestation (B) - The originator knows the identity of the caller, but cannot confirm their right to use the Caller ID.
- Gateway Attestation (C) - The identity of the caller is not known, as the call originated outside of the network, or internationally. C level is applied when A or B cannot be.
Due to the flexibility of Twilio's platform, users can take advantage of SHAKEN/STIR attestation in a few different ways.
Outbound Calls
For calls originating on Twilio’s platform, a From number is required.
When you make a POST
to /Calls
, a new Call resource will be created.
This From
number is what is displayed on the recipient’s device. By default, Twilio accounts can only make calls using a from number which is either:
- A Twilio number owned by said account
- A non Twilio number, validated using either
- the Outgoing Caller ID API
- or the Caller ID validation tool in Console
If an outbound call is made using a non validated Caller ID, or a Twilio Number not belonging to the account, the call will fail with a 21210 Error.
Otherwise, Twilio will cryptographically sign the call with an attestation level that best represents the state of the Twilio number (or verified Caller ID) used to make the call. The best part - you are in complete control of the attestation level of the From number.
By setting up a Business Profile and adding your selected Phone Numbers to the SHAKEN/STIR TrustProduct, you can enjoy A level attestation on all outbound calls using those Phone Numbers.
Using a Verified CallerID as the From number on outbound calls will result in B level attestation.
Using a non verified Caller ID, or a Twilio Phone Number not added to a SHAKEN/STIR Trust Product will result in a C level attestation.
Bottom line - if you want high deliverability of your Outbound API calls, use SHAKEN/STIR.
Inbound Calls
Calls terminating on Twilio’s platform use the From number assigned by the originating carrier.
In your call logs, the From number is assigned by the originating carrier, and the To number is your Twilio Inbound number. When a call comes in to your Twilio number, we make a webhook to the defined URL. As part of this HTTP request, we include the StirVerstat
parameter,
We also send the CallToken
parameter, which includes the actual jwt token containing the signed attestation information. This can be decoded with various libraries, or on jwt.io.
Let’s Build an App
This is where the fun begins!
Now that we know what SHAKEN/STIR is and how it works with Twilio, we should build something neat!
Let’s leverage the StirVerstat
parameter to route the inbound calls in interesting ways using some super powerful Programmable Voice features.
Mobile providers use attestation as one metric to apply ‘nuisance labeling’, or to block calls on behalf of their subscribers.
Why can’t you do something similar with your Twilio Programmable Voice app?
Prerequisites
If you want to follow along, you will also need to perform a few steps:
- Sign up for a free Twilio account, if you don’t have one already.
- In the Twilio Console, make a Service, and copy the js files as Functions, using this structure:
- Purchase a Phone Number and point it at the
inbound-gateway.js
Function URL. - While it is not required for inbound calls, I recommend onboarding to TrustHub and going through these steps to set up SHAKEN/STIR functionality for outbound calls.
Inbound calls trigger a webhook to the inbound-gateway
Function. The StirVerstat
value determines the ‘route’ to take, which then triggers ‘callbacks’.
In this scenario, I chose to route differently for every attestation level simply to demonstrate the power of Programmable Voice. In your case, you may decide another approach is more appropriate or practical.
And with that, we can begin.
Attestation Level Routing
To implement these call flows based on the Attestation level of the inbound caller, we must first create a ‘router’ Function which inspects the StirVerstat
parameter.
Using a switch statement, we can check the parameter against our known list of values and have fine-grained control over each possible scenario.
<Redirect> is one of my favorite TwiML verbs. It is simple, and powerful. You might think of this router function like an API gateway in a microservice architecture. The incoming requests are analyzed and forwarded according to the payload. Without <Redirect>, all of this logic would need to be in one Function.
Call Forwarding
If the caller is stamped with A attestation, then we know the caller id is trusted. Let’s just send them straight through to our cell phone - no action required. A simple <Dial> is all you need.
Keep in mind, the CallerID of the subsequent outbound <Dial> call will be the From number of the originating inbound call. You can override this by providing the CallerId attribute.
Call Screening
‘It’s all your fault. I screen my phone calls’ - Gwen Stefani
We’ve all been there. But Twilio wasn’t around when Gwen and Tony wrote “Spiderwebs”, so their idea of call screening was probably "let the answering machine get it, and I’ll pick it up if they sound cool."
Today, Gwen Stefani is still writing bangers, but we have Twilio to help us with call screening. In this example, if the call is stamped with B attestation, the recipient will hear a recording of the caller’s name before they are connected.
The inbound caller will hear the <Say> message and will be prompted to record a message notifying the recipient who is calling.
As soon as the caller is done leaving a message, the caller will hear hold music while the recording is processed and the call is forwarded.
As soon as the recording is ready, the call is updated with a <Dial>. The new RecordingURL is populated as the <Number> URL. When the recipient picks up, they will hear the recording and can decide to hang up or wait to be connected.
Voicemail
If the Attestation level of the inbound call is C, we can send them straight to a voicemail program. This Function returns a <Record> verb, and then sends a SMS to a number of your choice with a link to the recording file.
By taking advantage of a little known feature of the <Record> verb, we can make this single Function dual purpose.
If you do not provide a <Record> action URL, then Twilio will hit the same document with the action callback.
The RecordingURL parameter is not present in the initial TwiML fetch, so we return <Record>.
Whereas, the presence of RecordingURL in the request indicates the action callback, so we send an SMS with the link.
Human Detection
Human Detection is similar in logic to Answering Machine Detection in that we want to determine if the caller is a human or a machine. In the context of outbound calls, Answering Machine detection makes a lot of sense. For example, we might want to use a different call flow if a human picks up vs. a machine. In the context of inbound calls, Human Detection is more useful to root out robocalls.
As mentioned before, the StirVerstat
parameter may be missing, or have a value like “Validation-Failed” or “No-TN-Validation”. In these cases, we will use Human Detection.
Before the call is bridged, the caller will hear a <Say> message asking them to solve a captcha or puzzle.
In this example, we ask the caller to “Enter the number that comes after 9”
This can be anything, though - the harder for computers, the better.
After the user enters digits, Twilio makes a request to the <Gather> action url.
If the correct digits are not entered, the call is ended using <Hangup>. Otherwise, we use a <Dial> to forward the call to our cell.
You may decide to include these in another route, or just log them for visibility. Either way, SHAKEN/STIR rollout is still ongoing, so a missing or unexpected StirVerstat
value is no cause for immediate concern.
Conclusion
If you were building along, you can now call your number and test it out! You may need to adjust the switch statement in the router function if you don't have access to enough From numbers to test each path.
Either way, you are now one step closer to becoming a SHAKEN/STIR aficionado! Whether you are trying to improve call deliverability, dynamically route incoming calls, or just analyze what types of numbers are calling your app, then Twilio has you covered with Trusted Calling.
We can’t wait to see what you STIR up!
Matt Coser is a Senior Field Security Engineer at Twilio. His focus is on telecom security, and empowering Twilio’s customers to build safely. Hit him up on linkedin to connect and discuss more.
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.