3

This is my first time using twilio and I start with the new twilio-cli and I create new project to build and deploy a backend over twilio functions, but I need that some of the functions keep in private, and I want to call that function through their specific api-endpoint but, I always receive the message "Unauthorized - you are not authenticated to perform this request"

This is the plugin that I am using with twilio-cli https://github.com/twilio-labs/plugin-serverless to start the basic project to deploy to twilio.

I already tried to use the curl documentation that I found here: https://www.twilio.com/docs/studio/rest-api/execution but none of the example execute the function.

curl -X POST 'https://serverless.twilio.com/v1/Services/ZSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/Functions/ZHXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' \
  -u ACXXXXXXXXXXXX:your_auth_token

I just need to receive a hello world message, this is the code of the function:

exports.handler = function(context, event, callback) {
  const twiml = new Twilio.twiml.MessagingResponse();
  twiml.message("Hello World!");
  console.log("Track this");
  callback(null, twiml);
};
Joao Pixeles
  • 142
  • 8

2 Answers2

4

The accepted answer doesn't actually answer the question.

To call a protected function, you must provide a signature in a X-Twilio-Signature header. This is how to create such a signature (according to the official docs):

  1. Take the full URL of the request URL you specify for your phone number or app, from the protocol (https...) through the end of the query string (everything after the ?).
  2. If the request is a POST, sort all of the POST parameters alphabetically (using Unix-style case-sensitive sorting order).
  3. Iterate through the sorted list of POST parameters, and append the variable name and value (with no delimiters) to the end of the URL string.
  4. Sign the resulting string with HMAC-SHA1 using your AuthToken as the key (remember, your AuthToken's case matters!).
  5. Base64 encode the resulting hash value.

Official docs: https://www.twilio.com/docs/usage/security#validating-requests

Dotl
  • 1,406
  • 1
  • 13
  • 16
1

Heyooo. Twilio developer evangelist here.

If you followed the serverless plugin init process by running twilio serverless:init you should have the following project structure.

.
├── assets
│   ├── index.html
│   ├── message.private.js
│   └── style.css
├── functions
│   ├── hello-world.js
│   ├── private-message.js
│   └── sms
│       └──reply.protected.js
├── node_modules
├── package-lock.json
└── package.json

These files result in the following HTTP endpoints after you run twilio serverless:deploy. (you will have a different domain).

Deploying functions & assets to the Twilio Runtime

Account     SK6a...
Token       kegH****************************
Service Name    foo-2
Environment dev
Root Directory  /private/tmp/foo
Dependencies
Env Variables

✔ Serverless project successfully deployed

Deployment Details
Domain: foo-3513-dev.twil.io
Service:
   foo (ZS8...)
Environment:
   dev (ZE0...)
Build SID:
   ZB9...
Functions:
   [protected] https://foo-3513-dev.twil.io/sms/reply
   https://foo-3513-dev.twil.io/hello-world
   https://foo-3513-dev.twil.io/private-message
Assets:
   [private] Runtime.getAssets()['/message.js']
   https://foo-3513-dev.twil.io/index.html
   https://foo-3513-dev.twil.io/style.css

Have a close look at the Runtime Urls in the functions block. These are the endpoints that will be available. As you see the bootstrap project includes two public functions (/hello-world and /private-message). You can call these with curl or your browser.

Additionally, there is one protected function (/sms/reply). This function available for calls from within Twilio.

This means that protected functions expect a valid Twilio signature. You can read about that here. If you connect e.g. Studio to call the function it will work because the webhook includes a Twilio signature. If you want to curl it you have to provide X-Twilio-Signature header.

Hope this helps. :)

stefan judis
  • 3,416
  • 14
  • 22
  • This help a lot! thanks, but, how I can get a X-Twilio-Signature? there is a guide with an example that you can shared with me. – Joao Pixeles Aug 16 '19 at 14:39
  • Creating an X-Twilio-Signature would be a challenge I think. They have library code you can dig into to see how this signature is created. Here are a couple links: https://www.twilio.com/blog/how-to-secure-twilio-webhook-urls-in-nodejs https://www.laurentluce.com/posts/c-twilio-rest-and-twiml-helper-library/ https://laurentluce@github.com/laurentluce/twilio-cplusplus.git (not sure if the laurentluce stuff still works) – jwallis Oct 27 '20 at 21:10
  • The question is how to send a request to a protected function (ie a function we don't want to be accessible by absolutely anyone). If a protected function requires a signature, which by the sounds of it is only supposed to be used by Twilio webhooks, then how else are we meant to protect our functions from the public? Twilio docs don't seem to answer this very basic question - surely leaving serverless functions public just opens them up to abuse? – Dotl Nov 25 '20 at 17:59
  • Found the answer after lots of Googling and going through the docs. See my answer :) – Dotl Nov 25 '20 at 18:16