Deadshot: Keep Sensitive Data Out of Code

May 18, 2021
Written by

Deadshot Header Image

Code is no place for credentials, secrets, SQL statements, or any kind of sensitive data. But everyone makes mistakes, and it’s important to be able to catch human errors before they create real problems.

It is impossible to manually monitor any organization’s entire code base hoping to catch sensitive changes before they escape to live forever on Github. This is a problem every security team faces when dealing with product code.

The Product Security team at Twilio needed an automated way to ensure that developers weren’t accidentally adding sensitive data to code repositories and to flag sensitive changes for a security review. We knew we couldn’t monitor all code manually. Our solution: an automated way to monitor GitHub repositories in real-time, catching any sensitive data at the pull request stage, flagging issues as well as changes to sensitive functionality for a manual review. Thus was born Deadshot – which we’re happy to be releasing as open source today.

Deadshot: an automated service to monitor Github

Deadshot is a Github app that you can install on your Github organization. Deadshot runs on every commit, using regular expressions to scan the pull request diff for whatever is important for you. If it finds a match, it adds a comment to the pull request and can also notify a specified Slack channel. It also creates a Jira ticket in your Security team’s queue if the pull request is merged without addressing the identified secrets.

Designing Deadshot

We wanted a deploy-and-forget solution that constantly monitors for sensitive data matching a predefined set of regular expressions which we considered to be widely used in our organization. It had to be a service we never needed to touch except to add or remove regular expressions to match sensitive data.

Deadshot is a Python-based Flask-Celery-Redis multi-container application that is installed as a Github app, and runs on every pull request created against the main branch of a repo where you install it.

The Flask container exposes API routes to receive pull request payloads. When a pull request payload is received, the service forwards the payload to a Redis queue. The Celery container picks up the payload from the queue and scans through the diff of the pull request, looking for the specified sensitive data. If it finds a match, the Celery container adds comments on the pull request, notifies the appropriate Slack channel, or creates a JIRA ticket.

Try using Deadshot

Here at Twilio, Deadshot has proven to be very helpful in catching sensitive data in pull requests before it gets merged to a repository. We’re excited to release it to the open source community and hear about Deadshot in your organisation.

To learn more about how to deploy Deadshot, see:

Laxman Eppalagudem is a Senior Product Security Engineer at Twilio focused on securing Twilio’s products before they go out to customers. He can be reached at seppalagudem [at]