HawkScan and GitHub Actions

To integrate StackHawk into GitHub Actions workflows, simply:

  1. Secure your API key as a Secret in your GitHub repository
  2. Configure your workflow with a .github/workflows/hawkscan.yml file
  3. Configure HawkScan with a stackhawk.yml file

In this how-to, we will first describe the simple scenario of scanning a publicly available example app, example.com. Then under Local Scanning, we will show you how to run and test your app all within the self-contained GitHub Actions build environment.

Secure Your API Key

When you signed up on StackHawk, you created an API key. To keep it a secret, and out of your repository, copy it to a GitHub secret for your repository. On GitHub, find your repository, and click into the ⚙️Settings tab near the top right side of the screen. Then click Secrets near the bottom left . Add your StackHawk API key as a secret called HAWK_API_KEY.

Configure Your Workflow

At the base directory of your code repository, add a .github/workflows/hawkscan.yml file to configure GitHub Actions to run HawkScan. Your file should look like this.

.github/workflows/hawkscan.yml

name: HawkScan
on:
  push:
  pull_request:
jobs:
  hawkscan:
    name: HawkScan
    runs-on: ubuntu-latest
    steps:
      - name: Clone repo
        uses: actions/checkout@v2
      - name: Run HawkScan
        env:
          API_KEY: ${{secrets.HAWK_API_KEY}}
        run: >
          docker run --volume $(pwd):/hawk --tty
          --env API_KEY="${API_KEY}"
          stackhawk/hawkscan

This configuration tells GitHub Actions to run a single job which checks out your code, and then runs HawkScan as a Docker container. We pass the StackHawk API key to HawkScan as an environment variable from the GitHub secret, HAWK_API_KEY.

Configure HawkScan

At the base directory of your code repository, create a stackhawk.yml appropriate for scanning your application. For our example, we will create a minimal configuration pointing to our Development environment API endpoint, http://example.com.

stackhawk.yml

app:
  applicationId: xxXXXXXX-xXXX-xxXX-XXxX-xXXxxXXXXxXX
  host: http://example.com
  env: Development

Replace the value for applicationId with your Application ID from StackHawk.

Run It

Check those two files into source control, and push them to GitHub. Head over to the GitHub Actions console to watch your workflow run. When it is complete, check your account at StackHawk to review your scan details!


Local Scanning

The previous example is simple, but it assumes that you have an integration environment that is publicly accessible. Alternatively, you can run your app and scan it directly on the ephemeral GitHub build host. Here are two common ways of doing that.

Service on Localhost

One way to test an app after building it is to launch it on the VM where the workflow is running, and scan it on the localhost address. You can launch the HawkScan container with the flag --network host to give it access to localhost, and set app.host in stackhawk.yml to http://127.0.0.1.

For our example app, we will launch an Nginx container listening on port 80. Then we will scan it at the localhost address with HawkScan running in host networking mode. This method works with any app you wish to scan, containerized or not.

Here’s our modified GitHub workflow.

.github/workflows/hawkscan.yml

name: HawkScan
on:
  push:
  pull_request:
jobs:
  hawkscan:
    name: HawkScan
    runs-on: ubuntu-latest
    steps:
      - name: Clone repo
        uses: actions/checkout@v2
      - name: Run Nginx
        run: docker run --rm --detach --publish 80:80 --name nginx_test nginx
      - name: Run HawkScan
        env:
          API_KEY: ${{secrets.HAWK_API_KEY}}
        run: >
          docker run --volume $(pwd):/hawk --tty --network host
          --env API_KEY="${API_KEY}"
          stackhawk/hawkscan

☝️ Notice the new Run Nginx step which launches our app, and the --network host flag appended to the HawkScan docker run command.

Finally, here’s our modified HawkScan configuration pointing to the localhost address, 127.0.0.1.

stackhawk.yml

app:
  applicationId: xxXXXXXX-xXXX-xxXX-XXxX-xXXxxXXXXxXX
  host: http://127.0.0.1
  env: Development

Pro Tip: avoid using localhost, because that name won’t resolve in Docker containers running on a Linux host. Instead, use 127.0.0.1.

When you run this workflow, it will launch Nginx, scan it with HawkScan, and post the results to your StackHawk scan list.

Service on Bridge Network

Another option is to run the test app in a container and scan it on a Docker bridge network using the --network <network-name> flag for docker run. With this approach it becomes easier to build complex arrangements of Docker containers, adding databases and other services that you can address by name.

Building on the last example, we add a step to create a Docker bridge network called scan_net. Then we launch an Nginx container with the name nginx_test as our test app on that network. Finally, we run HawkScan against nginx_test on the scan_net network.

.github/workflows/hawkscan.yml

name: HawkScan
on:
  push:
  pull_request:
jobs:
  hawkscan:
    name: HawkScan
    runs-on: ubuntu-latest
    steps:
      - name: Clone repo
        uses: actions/checkout@v2
      - name: Create Docker network
        run: docker network create scan_net
      - name: Run Nginx on Docker network
        run: docker run --rm --detach --network scan_net --name nginx_test nginx
      - name: Run HawkScan on Docker network
        env:
          API_KEY: ${{secrets.HAWK_API_KEY}}
        run: >
          docker run --volume $(pwd):/hawk --tty --network scan_net
          --env API_KEY="${API_KEY}"
          stackhawk/hawkscan

Finally, update the HawkScan configuration to point to your test app, http://nginx_test.

stackhawk.yml

app:
  applicationId: xxXXXXXX-xXXX-xxXX-XXxX-xXXxxXXXXxXX
  host: http://nginx_test
  env: Development

This is a great way to build out more complicated arrangements of containers. You can even use docker-compose to make the configuration more readable and portable.