FreePBX Inbound Caller Authentication with PIN sets

Per FreePBX‘s definition: PIN Sets are used to manage lists of PINs that can be used to access restricted features such as Outbound Routes. The PIN can also be added to the CDR record’s ‘accountcode’ field. So, if you want to limit calling to international destinations, you can define a set of PINs and assign the PIN set to an outbound route with international number pattern matching. If an extension dials a matching phone number, they will be prompted to enter a valid PIN before the call is sent out the trunk(s). This can be a useful feature, but the Authenticate() application can be used in other ways.

For example, let’s say your company provides B2B services. Your services are billed back to your customers, and they want reports of WHO exactly called you. Unless your customer’s are sourcing a unique DID for each person, how would you report this? Route all calls to an operator to capture this data? Manually listen to each call recording and create a log?

Instead, use FreePBX’s built-in application Authenticate() with a list of PINs provided by your customer for FreePBX inbound caller authentication. With the customer providing the PINs, they know exactly who should be using which ones, and they can use any existing ID they use internally, such as an extension number, an employee number, etc. If an employee doesn’t know a valid PIN when they attempt a call, the call will not be connected, keeping unauthorized people from engaging your services.

Getting Started

First, create the PIN set from the FreePBX GUI at Settings -> PIN Sets. Give the set a descriptive name, and paste in the list of PINs provided by your customer. After you submit the change, you’ll see your new PIN set listed. Select the ‘edit’ action button, and note the ‘itemid’ shown in the URL. We’ll need this later.

Add Custom Context

Next, add a custom context to extensions_custom.conf. Explanation is below:

exten => s,1,Answer
exten => s,n,Wait(2)
exten => s,n,Authenticate(/PINSETS/1,ad,6))
exten => s,n,Set(__PINNUMBER=${CHANNEL(accountcode)})
exten => s,n,NoOp(Pin number is ${PINNUMBER})
exten => s,n,Return
  • Answer the channel and wait for two seconds.
  • Send the caller to the Authenticate() application and pass along the PIN set we created above. In the above example, ‘1’ is the PIN set itemID shown in the GUI URL. To see all options for Authenticate, including passing a custom recording to use, see this wiki article. Since all PINs in our example set are six digits in length, we pass this length in the request to Authenticate(); if we do not pass a length, Authenticate() will wait for a caller to press ‘#’ before checking the entered PIN against the set.
  • The Set() and NoOp() lines are optional; they log the inputted PIN to the Asterisk CLI and log for review, if needed.
  • The Return() line sends authenticated callers back to the Custom Destination -> Destination we set in the GUI in the next step.

Create Custom Destination

Now, let’s create a custom destination so we can easily route callers to our custom context. From Admin -> Custom Destinations, create a Custom Destination:

Note that the target of our Custom Destination points to our custom context ‘inbound_authentication’, extension ‘s’, priority ‘1’ from the code snipped above.

In the Custom Destination, set the Destination to the next step in call routing.  In this case, I’ll send authenticated users to the ‘Main’ IVR.

Make it live

Lastly, it’s time to point inbound callers to our Custom Destination. Since we’ve defined a Custom Destination, this will be available in the GUI as a destination everywhere, including Inbound Routes, Time Conditions, Call Flow Control, etc.


When it’s time to send a report to your customer, it’s as easy as filtering and exporting a CDR. In our example, since we are passing the ‘a’ option to Authenticate(), the accepted PIN will be shown as the account code in the CDR. Filter for a date range, select any other appropriate filters needed, and download the .csv file! If your customer needs to add/remove/change any PINs in the set, it’s as easy as editing the PIN set in the FreePBX GUI, without having to change any code!

This is just one example of customization that is available within FreePBX. We hope you find FreePBX inbound caller authentication interesting.

Contact Us