By: Julian Salama
Published: January 26, 2020

Last year, my business partner and I decided to offer a compliance software solution to manage privacy requests via a web form and toll-free number letting businesses comply with the requirements of the California Consumer Privacy Act (CCPA). Since then, we have been adding enterprise-level features like 100% encryption at rest, multi-factor authentication for additional security, and privacy request deadline reminders for all of our users. My partner is a lawyer by trade, and I am an engineer and helped build the software solution for the 866-I-OPT-OUT (866-467-8688) privacy hotline. 

If you’re curious about the inner workings of our SaaS solution, read on!

We built CCPATollfree.com in three parts. First, a dashboard publishes our user’s account configuration and management details to a Postgres database. Second, we use certain of those details to enable a twilio programmable voice experience, and a web form integration that sends privacy requests back to our database. Third, we use background jobs to send reports to our users, and compute call usage for each account. Let’s take a deep dive into all three parts.

Account Configuration and Management

The dashboard lets you create service codes, which you can think of as distinct repositories where consumers can register their privacy preferences. They are a means to logically segment the privacy requests. For example, it’s common for enterprise clients to own multiple brands and to publish the same phone number with different service codes on different websites. In addition to segmenting privacy requests, you can  customize the greeting associated with each service code so the phone experience differs between service codes. All this configuration is published and stored in real time in a Postgres Database. We store greetings in an Amazon S3 bucket and make them available in real time for when consumers call your toll-free phone number.

Each tab that you see in the dashboard is a resource on our backend that has certain actions associated with them. The backend is a Ruby on Rails application. It’s critical for each of our clients that the data being stored in a shared database doesn’t leak across different client accounts. Each controller for those resources can only return data belonging to the account for the currently logged-in user. This is what we call horizontal segmenting of the data, and it prevents records in the database belonging to another account from ever being displayed. Another type of segmentation is vertical segmenting: only the columns absolutely necessary for the user interface are made available to that user interface. In order to enforce this behavior, we test each endpoint to make sure no data fails the horizontal segmentation, or vertical segmentation. For enterprise clients who require the absolute highest level of assurance, we offer private cloud instances of our app connected to a unique rather than a shared database.  

Twilio and Webform Experience

Twilio provides a product called programmable voice. The architecture of inbound calls is infinite in Twilio’s architecture, meaning we can accept an unlimited number of concurrent inbound calls per second. This is a critical part of our architecture that allows us to use a shared number across hundreds of different clients no matter how large. Twilio supports telephony for users like Uber on shared phone numbers, so we believe that it will be good enough for us for some time!

Twilio’s programmable voice will make an HTTP request for each interaction from a consumer. The experience starts when a consumer calls our phone number: 1-866-467-8688 or 1-866-I-OPT-OUT. The request reaches our backend and responds with xml directing how Twilio should behave. For instance, when entering service code 1#, our backend will use the configuration data available from the dashboard to direct twilio to next step of the experience: listening to the greeting for service code 1.

When integrating our service on your website, you will have access to our webform that sends privacy requests to your dashboard alongside the requests you receive from your toll-free number. Notice how the webform includes a RECAPTCHA? This is a free tool from Google that secures webforms. It generates a token on Google’s backend, which we receive on our web form and pass to our backend. We then check that token’s validity against Google’s RECAPTCHA service. In fact, we protect every endpoint. We use a Ruby gem called Devise to make sure all users are authenticated before we allow them to access data. We use signature technology with timestamp checks to avoid replay attacks for webhooks. We also whitelist origins so that a third party can not provide a web form that submits requests to your dashboard. This is why you need to email us requesting that we set up your domain to communicate with our application using HTTPS.

Background Jobs

The last critical piece of our architecture is background jobs. We use them for details such as asynchronously computing telephony usage from every account, that we then push to Stripe on a daily basis. We also construct reporting emails that we send based on your preferences selected in the dashboard. Those jobs run on our infrastructure built on Heroku, and are also segmented by account to ensure that data never leaks across accounts. We only send aggregate data via email, so emails never contain sensitive information. 

Another important part of our asynchronous work is the ability to replay data streams in the case of a network or computing failure. To track account usage (e.g., number of calls), we open a database transaction, update the usage to “processed,” and then send aggregate usage count to Stripe daily. If that is successful, we commit a transaction. If anything goes wrong, we rollback usage to “un-processed.” If an error occurs after the call to Stripe and before the transaction completes, we can handle the issues predicted by the CAP theorem by re-computing the daily count of calls for each account. 

We monitor background jobs with Papertrail and New Relic and receive alerts anytime anything goes wrong. In fact, the same level of alerting exists for each part of our system. We receive alerts when anything goes wrong with Twilio, the backend, the webform, our email server, or Stripe payments so we can address any issues as soon as a problem occurs. This is part of our commitment to proving enterprise-level support to our clients.

CCPA Toll Free is expanding its feature set following the same model for security and monitoring we set out to have from the start. On our roadmap, we have numerous partnerships, integrations, and more to build. Feel free to reach out to support@privacytollfree.com with questions and feature requests.