Expert agent for StackHawk CI/CD-native DAST. Covers stackhawk.yml configuration, HawkScan Docker runner, authenticated scanning, API scanning, GitHub/GitLab/Jenkins/CircleCI integration, and developer-focused DAST workflows. WHEN: \"StackHawk\", \"HawkScan\", \"stackhawk.yml\", \"hawkscan\", \"StackHawk DAST\", \"hawk scan\", \"stackhawk API scan\".
Pro shows the line behind each finding and how to fix it
Scanned 9/24/2026
npx -y skills add chrishuffman5/domain-expert --skill stackhawk --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Stackhawk?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/chrishuffman5-stackhawk)More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.
---
name: stackhawk
description: "Expert agent for StackHawk CI/CD-native DAST. Covers stackhawk.yml configuration, HawkScan Docker runner, authenticated scanning, API scanning, GitHub/GitLab/Jenkins/CircleCI integration, and developer-focused DAST workflows. WHEN: \"StackHawk\", \"HawkScan\", \"stackhawk.yml\", \"hawkscan\", \"StackHawk DAST\", \"hawk scan\", \"stackhawk API scan\"."
license: MIT
---
# StackHawk
This skill covers StackHawk, a developer-centric DAST platform built on OWASP ZAP. StackHawk is designed specifically for CI/CD integration, with a configuration-as-code approach (`stackhawk.yml`) and a developer-friendly experience for finding and fixing API and web application vulnerabilities.
## How to Approach Tasks
1. **Identify the task:** Configuration, CI/CD integration, authentication setup, API scanning, results triage.
2. **Identify the application type:** REST API, web application, GraphQL API.
3. **Understand the environment:** Where will the scan run? (local dev, CI/CD, staging).
## StackHawk Overview
StackHawk wraps OWASP ZAP in a developer-optimized experience:
- **Configuration as code:** All scan settings in `stackhawk.yml` committed to the repository
- **Docker-based:** `hawkscan` runs as a Docker container — no installation required
- **API-first:** Strong OpenAPI/Swagger support built in
- **Developer feedback:** Results delivered in the StackHawk platform with contextual fix guidance
- **CI/CD native:** First-class integrations for GitHub Actions, GitLab CI, Jenkins, CircleCI, Bitbucket
---
## stackhawk.yml Configuration
The `stackhawk.yml` file is the core of StackHawk configuration. Check it into your repository.
### Minimal Configuration
```yaml
app:
applicationId: ${APP_ID} # From StackHawk platform (env var)
env: Development
host: http://localhost:8080 # Where your app is running during CI
```
### Full Configuration Reference
```yaml
app:
applicationId: ${APP_ID}
env: ${APP_ENV:Development} # Environment name (Development, Staging, Production)
host: http://localhost:8080
# Authentication configuration
autoPolicy: true # Automatically detect and use session cookies
authentication:
loggedInIndicator: "LOGGED_IN" # String in response when logged in
loggedOutIndicator: "LOGGED_OUT" # String in response when logged out
usernamePassword:
type: FORM # FORM | TOKEN_REQUEST | SCRIPT
loginPath: /api/v1/login
usernameField: username
passwordField: password
scanUsername: ${HAWK_USERNAME}
scanPassword: ${HAWK_PASSWORD}
# API definition for better coverage
openApiConf:
filePath: openapi.yaml # Local file
# apiUrl: /api/v1/openapi.json # Or URL path on the running app
contextPath: /api/v1 # Base path prefix
# Scope control
includePaths:
- /api/v1.*
- /app/.*
excludePaths:
- /api/v1/logout.*
- /api/v1/health
- /api/v1/metrics
# Path-specific settings (override global auth or settings per path)
antiCsrfParam: _csrf # CSRF token parameter name if needed
hawk:
# Scan configuration
spider:
base: true # Use traditional spider
ajax: false # AJAX spider (requires headless browser)
scanDepth: 10
failureThreshold: HIGH # INFORMATIONAL | LOW | MEDIUM | HIGH | CRITICAL
# Fail CI if any finding at this level or above
# Custom headers for all requests
customHeaders:
- name: X-API-Key
value: ${API_KEY}
- name: X-Test-Mode
value: "true"
```
---
## Running HawkScan
### Locally
```bash
# Install StackHawk CLI (optional, for non-Docker use)
brew install stackhawk/tap/hawkctl
hawkctl init
# Run with Docker (recommended)
docker pull stackhawk/hawkscan:latest
docker run --rm \
-v $(pwd):/hawk \
-e APP_ID=$APP_ID \
-e HAWK_API_KEY=$HAWK_API_KEY \
stackhawk/hawkscan:latest
# Specify custom config file
docker run --rm \
-v $(pwd):/hawk \
-e APP_ID=$APP_ID \
-e HAWK_API_KEY=$HAWK_API_KEY \
stackhawk/hawkscan:latest /hawk/stackhawk-staging.yml
```
**Environment variables:**
- `HAWK_API_KEY` — StackHawk platform API key (required)
- `APP_ID` — Application ID from StackHawk platform (can also be in stackhawk.yml)
- Any other variables referenced in `stackhawk.yml` via `${VAR_NAME}` syntax
### Scanning an API in CI/CD
Typical workflow: start app → wait for ready → run hawkscan → report results
```bash
# Start application
./start-app.sh &
# Wait for app to be ready
until curl -s http://localhost:8080/health | grep -q "UP"; do sleep 2; done
# Run HawkScan
docker run --rm \
--network=host \
-v $(pwd):/hawk \
-e APP_ID=$APP_ID \
-e HAWK_API_KEY=$HAWK_API_KEY \
stackhawk/hawkscan:latest
```
**Network mode:** Use `--network=host` when the app is running on the host (not in Docker). If app is in Docker, use the same Docker network.
---
## Authentication Methods
### Form-Based Login
```yaml
app:
authentication:
loggedInIndicator: "Welcome"
loggedOutIndicator: "Sign In"
usernamePassword:
type: FORM
loginPath: /login
usernameField: email
passwordField: password
scanUsername: ${HAWK_USERNAME}
scanPassword: ${HAWK_PASSWORD}
```
### API Token (Bearer)
```yaml
app:
authentication:
tokenExtraction:
type: TOKEN_REQUEST
tokenRequest:
url: http://localhost:8080/api/v1/auth/token
method: POST
body: '{"username":"${HAWK_USERNAME}","password":"${HAWK_PASSWORD}"}'
contentType: application/json
tokenJsonPath: $.token # JSONPath to extract token from response
tokenAuthorization:
type: HEADER
headerName: Authorization
headerValue: Bearer {TOKEN}
```
### OAuth 2.0 / OIDC
```yaml
app:
authentication:
tokenExtraction:
type: TOKEN_REQUEST
tokenRequest:
url: https://auth.example.com/oauth/token
method: POST
body: "grant_type=password&client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}&username=${HAWK_USERNAME}&password=${HAWK_PASSWORD}&scope=openid"
contentType: application/x-www-form-urlencoded
tokenJsonPath: $.access_token
tokenAuthorization:
type: HEADER
headerName: Authorization
headerValue: Bearer {TOKEN}
```
### Cookie-Based Session
```yaml
app:
autoPolicy: true # StackHawk automatically detects and maintains session cookies
authentication:
loggedInIndicator: "Dashboard"
loggedOutIndicator: "Login"
usernamePassword:
type: FORM
loginPath: /login
usernameField: username
passwordField: password
scanUsername: ${HAWK_USERNAME}
scanPassword: ${HAWK_PASSWORD}
```
---
## API Scanning
StackHawk's strongest use case is API scanning with an OpenAPI definition.
### OpenAPI/Swagger
```yaml
app:
host: http://localhost:8080
openApiConf:
filePath: docs/openapi.yaml # Relative to stackhawk.yml location
contextPath: /api/v1 # Prefix to add to all paths in schema
```
StackHawk reads the OpenAPI schema and:
1. Generates requests for all endpoints and methods defined in the schema
2. Injects test payloads into all parameters (path, query, header, body)
3. Tests each combination for injection vulnerabilities, auth bypass, etc.
**JSON Schema validation:** StackHawk validates that API responses match the expected schema — responses with unexpected structures or status codes are flagged.
### GraphQL
```yaml
app:
graphQlConf:
schemaPath: schema.graphql # Local schema file
# schemaUrl: http://localhost:8080/graphql?sdl
endpoint: /graphql
```
### Fixing Schema Coverage Gaps
If your OpenAPI schema is incomplete:
```yaml
app:
openApiConf:
filePath: openapi.yaml
# Add custom paths not in OpenAPI schema
includePaths:
- /api/v1/.* # Regex pattern
excludePaths:
- /api/v1/admin/.* # Don't scan admin endpoints in this scan profile
```
---
## CI/CD Integration
### GitHub Actions
```yaml
name: StackHawk DAST
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
hawkscan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Start Application
run: docker-compose up -d
- name: Wait for Application
run: |
until curl -sf http://localhost:8080/health; do sleep 2; done
- name: Run HawkScan
uses: stackhawk/hawkscan-action@v2
with:
apiKey: ${{ secrets.HAWK_API_KEY }}
env:
APP_ID: ${{ vars.HAWK_APP_ID }}
HAWK_USERNAME: ${{ secrets.HAWK_USERNAME }}
HAWK_PASSWORD: ${{ secrets.HAWK_PASSWORD }}
```
### GitLab CI
```yaml
hawkscan:
stage: dast
image: stackhawk/hawkscan:latest
services:
- name: my-app:latest
alias: app
variables:
APP_ID: $HAWK_APP_ID
HAWK_API_KEY: $HAWK_API_KEY
APP_HOST: http://app:8080
script:
- hawkscan
artifacts:
paths:
- stackhawk-reports/
```
### Jenkins
```groovy
stage('DAST - HawkScan') {
agent {
docker { image 'stackhawk/hawkscan:latest' }
}
environment {
HAWK_API_KEY = credentials('hawkscan-api-key')
APP_ID = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
}
steps {
sh 'hawkscan'
}
}
```
### CircleCI
```yaml
jobs:
hawkscan:
docker:
- image: stackhawk/hawkscan:latest
steps:
- checkout
- run:
name: Run HawkScan
command: hawkscan
environment:
HAWK_API_KEY: $HAWK_API_KEY
APP_ID: $HAWK_APP_ID
```
---
## StackHawk Platform
### Results and Triage
After a scan, results appear in the StackHawk web platform at `app.stackhawk.com`:
- **Finding list:** All findings sorted by severity with request/response evidence
- **Trend view:** Finding count over time (catching regressions)
- **Fix guidance:** Contextual remediation advice with code examples
- **OWASP/CWE mapping:** Each finding mapped to standards
- **PR comments:** StackHawk can post finding summaries directly to GitHub PRs
### Application Management
- **Applications:** Each scanned system (tied to `applicationId`)
- **Environments:** Separate scan profiles per environment (Development, Staging)
- **API keys:** Per-team or per-user API keys for CI/CD access
- **Integrations:** GitHub, GitLab, Jira, Slack notifications
### Failure Thresholds
Control when HawkScan exits with a non-zero code (breaks the pipeline):
```yaml
hawk:
failureThreshold: HIGH # INFORMATIONAL | LOW | MEDIUM | HIGH | CRITICAL
```
This sets the minimum severity that breaks the build. `HIGH` means: fail if any High or Critical finding is new. Common practice:
- Developer feedback: `INFORMATIONAL` (always see all findings)
- PR gate: `HIGH` (only block on high/critical)
- Release gate: `MEDIUM` (stricter threshold before production)
---
## Common Issues
**HawkScan cannot reach application:**
- Verify host setting in `stackhawk.yml` matches where app is listening
- In Docker-to-Docker: use container name or `host.docker.internal` (not `localhost`)
- Use `--network=host` Docker flag when app runs on the host directly
**Authentication not working:**
- Verify login path is correct (the POST endpoint, not the login page)
- Check `loggedInIndicator` value — it should be a unique string in authenticated responses
- Test authentication manually with `curl` before configuring HawkScan
- Ensure test credentials have access to all endpoints you want to scan
**OpenAPI scan missing many endpoints:**
- Verify OpenAPI schema is valid (use swagger-editor.swagger.io)
- Check `contextPath` matches your API base path
- Ensure the schema is accessible from the scan container
**Too many false positives:**
- Use `excludePaths` to skip endpoints known to trigger false positives
- Adjust `failureThreshold` upward during initial integration
- Review findings in StackHawk platform and mark as accepted/false positive
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!