Bitbucket Pipelines
Adding StackHawk to Bitbucket Pipelines is simple. In this guide we will describe how to do it with concrete examples you can try yourself. We will describe three scenarios, each installing the hawk CLI with the hawk CLI install script, with Docker alternatives:
- Scan a publicly available endpoint such as example.com
- Scan a service running on localhost
- Scan an application stack running locally in Docker Compose
Create a Bitbucket Repository
If you don’t have one already, create a new Bitbucket account. Then create a new repository to contain the configurations for the examples below.
Secure Your API Key
Your API key should be kept secret. Rather than saving it in your repository, store it as a secret environment variable in Bitbucket Pipelines.
Log on to Bitbucket and navigate to your repository. From the left-hand pane , select (⚙️) Repository settings, and then below PIPELINES, select Repository variables.


Add an environment variable called HAWK_API_KEY, and enter your API key from the HawkScan app. If you need to look up your API key or create a new one, navigate to your API Keys in the StackHawk platform.
Now you’re ready to define your scan and pipeline configurations.
Scenario One: External Site Scanning
In this scenario you will scan an existing external site. Typically, this would be your own integration test site running your latest pre-production code. For this simple example we will use example.com as our external site.
At the base of your repository, create a bitbucket-pipelines.yml file with the following contents.
image: atlassian/default-image:4
pipelines:
default:
- step:
name: Scan Example.COM
script:
# Optional: pin a version (6.0.0 or later). Leave it unset to install the latest release.
# - export HAWK_INSTALL_VERSION=6.6.0
- curl -fsSL https://download.stackhawk.com/hawk/install.sh | sh
- export PATH="$HOME/.hawk/bin:$PATH"
- hawk --api-key="$HAWK_API_KEY" scan
This is a single step pipeline that installs the hawk CLI with the install script and runs a scan. The script installs the latest HawkScan release and checks its checksum. It doesn’t change the PATH, so the next line adds its install directory, ~/.hawk/bin; the commands in a Bitbucket step share one shell, so the hawk command that follows can find it.
Notice that we pass the API key to HawkScan using the --api-key="$HAWK_API_KEY" flag.
Docker Alternative
If you’d rather run HawkScan as a Docker container instead:
image: atlassian/default-image:4
pipelines:
default:
- step:
name: Scan Example.COM
services: [docker]
script:
- >
docker run -v $(pwd):/hawk:rw -t
-e API_KEY=$HAWK_API_KEY
stackhawk/hawkscan
This step enables Docker, and then runs HawkScan as a Docker container. The Docker command to run HawkScan is a little long, so we break it up into multiple lines using the YAML special character > to fold the following lines into one long line, removing any newline characters.
Next, add a HawkScan configuration file to the root of your repository like so.
app:
applicationId: xxXXXXXX-xXXX-xxXX-XXxX-xXXxxXXXXxXX
host: http://example.com
env: Bitbucket Pipelines
Set app.applicationId to the StackHawk application ID for your application. You can find it in StackHawk Applications.
Commit your code and push it to Bitbucket to initiate a pipeline run. You can watch your scan progress in Bitbucket, and check the StackHawk Scans console to see your results.
Scenario Two: Localhost Scanning
In this scenario we will start a service locally and scan it on the localhost address. You can use this approach to scan your own application within the Bitbucket Pipelines build environment.
For this scenario, you will fire up Nginx in a Docker container, and scan it at the localhost address. Any application running on the localhost address can be scanned. It doesn’t need to be in a Docker container!
At the base of your repository, create a bitbucket-pipelines.yml file with the following contents.
image: atlassian/default-image:4
pipelines:
default:
- step:
name: Scan localhost
services: [docker]
script:
- docker run --detach --publish 8080:80 nginx
- while ! curl -s -o /dev/null localhost:8080; do echo Waiting for app; sleep 1; done
- curl -fsSL https://download.stackhawk.com/hawk/install.sh | sh
- export PATH="$HOME/.hawk/bin:$PATH"
- hawk --api-key="$HAWK_API_KEY" scan
The script in this pipeline has three steps:
- start an Nginx container, listening on localhost port 8080
- wait for Nginx to become responsive at http://localhost:8080
- install the
hawkCLI, put it on the PATH, and run HawkScan.
Because the hawk CLI runs directly in the build container, it reaches the application at localhost with no extra network configuration.
Docker Alternative
To run HawkScan as a Docker container instead, replace the last three script lines with:
- >
docker run -v $(pwd):/hawk:rw -t
-e API_KEY=$HAWK_API_KEY
--add-host host.docker.internal:$BITBUCKET_DOCKER_HOST_INTERNAL
stackhawk/hawkscan
Notice the flag to the HawkScan Docker command line that reads, “--add-host host.docker.internal:$BITBUCKET_DOCKER_HOST_INTERNAL.” This allows the HawkScan container to reach services on the localhost address, such as the Nginx container started in step 1 of the script. See this Bitbucket security bulletin for more information on why this flag is necessary.
Add a HawkScan configuration to the root of your repository:
app:
applicationId: xxXXXXXX-xXXX-xxXX-XXxX-xXXxxXXXXxXX
host: http://localhost:8080
env: Bitbucket Pipelines
Set app.applicationId to the StackHawk application ID for your application. You can find it from the StackHawk Applications screen.
Commit your code and push it to Bitbucket to initiate a pipeline run. You can watch your scan progress in Bitbucket, and check the StackHawk Scans console to see your results.
Scenario Three: Docker Compose Scanning
Docker Compose is a great way to build up a multi-tier application or set of microservices to create a repeatable integration test environment. You can bring the environment up with Docker Compose and scan the port it publishes with the hawk CLI.
For this scenario, we will start up an Nginx container using Docker Compose, and then scan it from the build container.
Create the following pipeline configuration file in the base of your repository.
image: atlassian/default-image:4
pipelines:
default:
- step:
name: Scan docker-compose
services: [docker]
script:
- docker-compose -f docker-compose-base.yml up --detach
- while ! curl -s -o /dev/null localhost; do echo Waiting for app; sleep 1; done
- curl -fsSL https://download.stackhawk.com/hawk/install.sh | sh
- export PATH="$HOME/.hawk/bin:$PATH"
- hawk --api-key="$HAWK_API_KEY" scan
There are three steps in the script defined above:
- Bring up the
docker-compose-base.ymlDocker Compose configuration, which contains the service,nginx-test. - Wait for the
nginx-testcontainer to become reachable on localhost. - Install the
hawkCLI, put it on the PATH, and run HawkScan.
Add the docker-compose-base.yml Docker Compose configuration file to your repo.
version: "3.7"
services:
nginx-test:
image: nginx
ports:
- 80:80
logging:
driver: none
The nginx-test service runs the nginx docker container and publishes it on localhost port 80, where HawkScan scans it.
We also set the logging driver for nginx-test to none. Since HawkScan will be probing many URLs on nginx-test, logging would generate excessive output in your pipeline results.
Add your HawkScan configuration file, stackhawk.yml, to the base of your repo.
app:
applicationId: xxXXXXXX-xXXX-xxXX-XXxX-xXXxxXXXXxXX
host: http://localhost
env: Bitbucket Pipelines
Set app.applicationId to the StackHawk application ID for your application. You can find it from the Applications screen.
Commit your code and push it to Bitbucket to initiate a pipeline run. You can watch your scan progress in Bitbucket, and check the StackHawk Scans console to see your results.
Docker Compose Alternative
You can also run HawkScan as a service in its own Docker Compose overlay, and scan your application by its service name on the private bridge network that Docker Compose sets up. Replace the last three script lines in bitbucket-pipelines.yml with:
- docker-compose -f docker-compose-base.yml -f docker-compose-hawkscan.yml up --abort-on-container-exit
The flag --abort-on-container-exit tells Docker Compose to bring down the whole environment when HawkScan finishes and the hawkscan container exits.
Then create a Docker Compose configuration for HawkScan in a file named docker-compose-hawkscan.yml.
version: "3.7"
services:
hawkscan:
image: stackhawk/hawkscan
environment:
API_KEY: "${HAWK_API_KEY}"
volumes:
- .:/hawk
tty: true
depends_on:
- nginx-test
This file creates the service hawkscan which runs the container stackhawk/hawkscan. It passes along the HAWK_API_KEY environment variable from your secured Repository Variables. And it mounts the current working directory . to /hawk within the container so that HawkScan can find your HawkScan configuration files.
Point stackhawk.yml at the service name, which is reachable within the Docker Compose private bridge network:
app:
applicationId: xxXXXXXX-xXXX-xxXX-XXxX-xXXxxXXXXxXX
host: http://nginx-test
env: Bitbucket Pipelines
For a more in-depth example of scanning a realistic integration test environment using Docker Compose, see our tutorial, Test-Driven Security With StackHawk Travis CI and Docker Compose. In this tutorial we build, seed, and scan a Django application with an Nginx proxy front-end and PostgreSQL database backend, all in Docker Compose.