HawkScan and GitHub Actions
With our GitHub Action, it is a snap to add application scanning to your GitHub Actions workflow.
To integrate StackHawk into GitHub Actions workflows, simply:
- Secure your API key as a Secret in your GitHub repository
- Configure your workflow with a
.github/workflows/hawkscan.yml
file - 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 we will walk through how to scan a service on the localhost address, in a Docker bridge network, and in a Docker Compose configuration.
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
uses: stackhawk/hawkscan-action@v1.1
with:
apiKey: ${{ secrets.HAWK_API_KEY }}
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 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 three common ways of doing that.
Scanning a 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://localhost:8080
.
For our example app, we will launch an Nginx container listening on port 8080. Then we will scan it at the localhost address with HawkScan. This method works with any app you wish to scan, containerized or not, as long as it is listening on the localhost address.
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 8080:80 --name nginx_test nginx
- name: Run HawkScan
uses: stackhawk/hawkscan-action@v1.1
with:
apiKey: ${{ secrets.HAWK_API_KEY }}
☝️ Notice the new Run Nginx
step which launches our app.
Finally, here’s our modified HawkScan configuration pointing to the localhost address.
stackhawk.yml
app:
applicationId: xxXXXXXX-xXXX-xxXX-XXxX-xXXxxXXXXxXX
host: http://localhost:8080
env: Development
When you run this workflow, it will launch Nginx, scan it with HawkScan, and post the results to your StackHawk scan list.
Scanning a Service on a Docker 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 your app 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. Then, 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
uses: stackhawk/hawkscan-action@v1.1
with:
apiKey: ${{ secrets.HAWK_API_KEY }}
network: scan_net
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
Scanning a Service in Docker Compose
Docker Compose can be a useful tool for modeling complex test environments in your CI/CD pipeline. It provides a concise way to combine your app server with any other services it might require to create a useful environment for integration testing and of course DAST scanning.
In Docker Compose, you can publish the ports of the service you want to scan using the services.<service-name>.ports
configuration. That service would then be accessible on the localhost address of your build VM, so your HawkScan Action configuration would look just like the one above, under Scanning a Service on Localhost.
Alternatively, you can specify a named bridge network in Docker Compose to run your services on. Then, rather than publishing the ports of services you want to scan, you could run HawkScan on the same network.
For example, say you have an test environment for your application defined as the Docker Compose configuration below. It contains your app server, myapp
, and a Postgres database, db
. In addition, it defines a Docker bridge network named mynetwork
, with all the services attached to it.
# docker-compose.yml
version: "3.9"
services:
myapp:
image: myapp
networks:
mynetwork:
db:
image: postgres
restart: always
networks:
mynetwork:
networks:
mynetwork:
name: mynetwork
To scan the above, say you have a HawkScan configuration file like the following.
# stackhawk.yml
app:
applicationId: xxxxxxxx-XXXX-xxxx-XXXX-xxxxxxxxxxxx
env: Development
host: http://myapp
Here is how we could configure a GitHub Actions workflow to use the mynetwork
network.
# .github/workflows/hawkscan.yml
name: HawkScan
on:
push:
jobs:
hawkscan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: docker-compose up -d
- uses: stackhawk/hawkscan-action@v1.1
with:
apiKey: ${{ secrets.HAWK_API_KEY }}
network: mynetwork
For more details on configuring the HawkScan Action, visit HawkScan Action in the GitHub Actions marketplace!