Hamburger Icon

Add AppSec to Your
CircleCI Pipeline
With the StackHawk Orb


Zachary Conger|April 29, 2020

When you check in a new web app vulnerability, do you get an alert and guidance on how to fix it? With the new StackHawk CircleCI Orb you can, and it’s easy.

The modern CI/CD environment bristles with automation. When you check in your code, an invisible army of robots goes to work linting, compiling, unit testing, and integrating your software.

These processes help us code faster since you don’t have to spend time manually building and testing, and better since you get quick feedback and guidance on code quality. Now you can add test-driven security to your pipeline with StackHawk.

In this post, we will use the StackHawk CircleCI Orb to build an app, fire it up in a container, and scan it for vulnerabilities, all within the CircleCI build environment.

The Application

I will be building and scanning Vulny Django. It’s a small web poll app that StackHawk’s Chief Security Officer, Scott Gerlach, built from the Django tutorial. We often use it to test scans and pipelines because it’s simple, quick to build, and it has a good set of routes and potential security flaws.

The Orb

CircleCI Orbs are a clever way to package complicated bits of code to make your pipeline configuration code clean and DRY. We recently launched our own orb, which makes it simple to weave scans into your pipeline. It exposes all the features of StackHawk, including the ability to scan any web app, find routes by spidering, parse an OpenAPI spec, and even probe GraphQL.

The orb provides two jobs, hawkscan-remote, and hawkscan-local. Each has advantages, but one is generally better suited for remote scans, and the other is best for running a self-contained scan within the CircleCI build environment.

Let’s take a look at the two options.


This is the faster and simpler of the two scan jobs, but it requires a remote instance of your app to be up and running. This is great if you have an existing integration environment accessible to CircleCI. All you need is to add a valid stackhawk.yml configuration file to your source repository, and add your StackHawk API key as a secret environment variable HAWK_API_KEY.

Here’s an example CircleCI configuration to use the hawkscan-remote job:

# .circleci/config.yml
  stackhawk: stackhawk/stackhawk@x.y.z
version: 2.1
      - stackhawk/hawkscan-remote

And here’s an example StackHawk configuration:

# stackhawk.yml
  applicationId: xxXXXXXX-xXXX-xxXX-XXxX-xXXxxXXXXxXX
  env: Development


This job allows you to spin up your own ephemeral integration environment right in your CircleCI pipeline.

When hawkscan-local runs, it starts a build VM, checks out your source code, runs a series of steps you provide, and then launches a stackhawk/hawkscan container. In the steps you provide, you can launch local services or containers to be scanned, right there in the CircleCI cloud.

Putting It All Together

We will use the second job, stackhawk/hawkscan-local, to demonstrate using the orb to run an integration test in your CircleCI pipeline. Let’s get started!

Get a StackHawk API Key

Go to to sign up. Create an account, and get an API key. Be sure to save a copy in a secure undisclosed location. You will need it later.

Clone the Vulny Django Repository

Head over to and fork our repository. You can also clone it and copy it up to Bitbucket if you like. The key is to have your own copy to play with, and to set up as a project in CircleCI.

Take a glance at the files in this repository.

├── .circleci/
│   └── config.yml
├── .gitlab-ci.yml
├── Dockerfile
├── nginx.default
├── src/
├── stackhawk-circleci.yml
├── stackhawk-gitlab.yml
├── stackhawk.yml

The src directory contains the app itself. And the Dockerfile file will be used to build the app and containerize it. There are other files associated with other build systems, such as .gitlab-ci.yml for GitLab. For our purposes we will focus on these three files:

  • stackhawk.yml – The HawkScan configuration file

  • stackhawk-circleci.yml – An additional HawkScan configuration file that we’ll use to customize our scan for CircleCI

  • .circleci/config.yml – The CircleCI project configuration file

Configure HawkScan

Check out the primary configuration file, stackhawk.yml. We use this project to test lots of command line and automation scenarios, so we put all of our common configs in here, such as authentication parameters (app.authentication), and scan depth (hawk.spider).

For my CircleCI pipeline, I wanted to customize a few of these parameters, so I created stackhawk-circleci.yml and put my overrides there. These will be merged on top of the main configuration file. Here’s the whole file:

# stackhawk-circleci.yml
  applicationId: ${APP_ID}
  host: http://vulny-django:8020

This will override the app.applicationId and entries from the main configuration. I’ll be setting the APP_ID environment variable in the CircleCI build configuration below by using the stackhawk/hawkscan-local parameter, app-id.

Configure CircleCI

Let’s look at the CircleCI build configuration file.

# .circleci/config.yml
version: 2.1

  stackhawk: stackhawk/stackhawk@1.0.1

      - stackhawk/hawkscan-local:
          configuration-files: ./stackhawk.yml ./stackhawk-circleci.yml
          docker-network: scan_net
          app-id: 685847dd-0a74-4f02-b4d2-53f2396c93ed
            - run:
                name: Build Vulny Django
                command: docker build -t vulny_django:latest .
            - run:
                name: Run Vulny Django
                command: |
                  docker network create scan_net
                  docker run --detach --network scan_net --name vulny-django --rm vulny_django:latest

Here we pull in the orb as stackhawk, and use it in our simple workflow, build-and-scan. We define a single job in the workflow using the orb job, stackhawk/hawkscan-local. The orb has several optional parameters, and we use three of them.

  1. docker-network tells hawkscan-local to start the dockerized scanner to run on a named bridge network called scan_net

  2. app-id sets the environment variable, APP_ID, that we use in stackhawk-circleci.yml above to dynamically set app.applicationId at runtime. Be sure to update this with your own app ID!

  3. steps sends a series of job steps to the orb to run on the VM before the scan starts

In our three job steps, we build the app, create a docker bridge network, scan_net, and start our new container on that network.

Add your Vulny Django Project to CircleCI

Head over to CircleCI and add your GitHub repo as a project in CircleCI. In your project settings, add your StackHawk API key as a secret environment variable, HAWK_API_KEY. This will automatically get picked up in the stackhawk/hawkscan-local job and used to send scan results to your StackHawk console.

Run the Pipeline

Make a commit to your repo and push it to GitHub to trigger a pipeline run. Then watch the job run in the CircleCI console. Here’s what you should see.

jmmcqB6zbewvkMyCgeGWZJ3k1aPVVTNbp1td6CsBMf03cP9vq92v4Rjv KIRIxq8TLoqYEEDqjXdhIdgmvzS-l2SgV4Jwzac80VXZNeoebNXZ9vqDJ3idbqRxVzVM4-LMP IuJoA image

When the job is finished, check your scan results in the StackHawk console. You can go directly to it by copying and pasting the link at the bottom of the Run HawkScan step in CircleCI. It should look like this:

View on StackHawk platform:

After following that link to the StackHawk console, you should see scan results similar to this:

Z3wPqkCUfXfSW7h61vsicz-TEyjvV-QWMPwbPF1WruXjhqtd8d5U96EpV0o3JB1F3pI-s7GDcakq0y6RYDOQoSyaKUVIiLfn2QBVm8ZfNGyQp x2vDSIpXuJJxkObdSeU66qFQ28 image


☝️ That feeling when your scan works. To experience it yourself, visit to get signed up for our early access release. Get started on the command line with our helpful Docs, and be sure to check out our integration guides for other popular CI/CD platforms.

Thanks, and good night!

Zachary Conger  |  April 29, 2020

Read More

Add AppSec to Your CircleCI Pipeline With the StackHawk Orb

Add AppSec to Your CircleCI Pipeline With the StackHawk Orb

Application Security is Broken. Here is How We Intend to Fix It.

Application Security is Broken. Here is How We Intend to Fix It.

Using StackHawk in GitLab Know Before You Go (Live)

Using StackHawk in GitLab Know Before You Go (Live)