Workflow · DevOps & platform engineers
Bowire as a pipeline step
You're wiring the CI/CD pipeline. Bowire ships as a single binary + Docker image that drops into any runner.
Three subcommands carry the load: bowire mock as an integration-test fixture, bowire scan as a SAST gate, bowire fuzz as a security-regression step. Real exit codes, no daemons, native SARIF output.
What you can do in the pipeline
Three Bowire steps cover the heavy lifting between “tests pass” and “safe to ship”. Each runs as a one-liner and exits with a real code.
bowire mock — integration-test fixture
Replay a recorded session as a live endpoint on the runner. Same protocol-shape as the real service (REST, gRPC, WebSocket, MQTT, …), hot-reload on file edits, capture-on-miss for new calls. Fixtures live in your repo as .bwr files — reviewable in PRs.
# Background the mock for the rest of the job
$ bowire mock --recording fixtures/api.bwr \
--port 5099 --hot-reload &
bowire scan — SAST gate with native SARIF
Built-in passive checks plus the 8000+ Nuclei community templates via --nuclei, fed through the same engine. Findings emit as SARIF 2.1.0 — GitHub Code Scanning, GitLab Security Dashboard, or Azure DevOps ingest it natively. Gating happens via Code-Scanning branch-protection rules.
# Built-in + Nuclei templates, one SARIF report
$ bowire scan --target http://localhost:5099 \
--nuclei ~/nuclei-templates \
--out findings.sarif --severity medium
bowire fuzz — security-regression step
Schema-aware field-level mutation. Knows not to throw SQL-injection at a latitude (lat) field; image.bytes gets magic-byte mutation, not XSS strings. Baseline-diff oracle flags responses that look materially different from clean runs. Same SARIF surface as scan.
# Targeted mutation, baseline-diff oracle, SARIF out
$ bowire fuzz --target http://localhost:5099 \
--template fixtures/api.bwr \
--payloads sqli,xss --out fuzz.sarif
How you integrate it
All three Bowire steps in one job. Same shape on GitLab CI and Azure DevOps — dotnet tool install + invoke the binary.
flowchart LR
Install(["Install bowire"])
BWR[("fixtures/api.bwr")]
Mock(["bowire mock"])
Tests(["Integration tests"])
Scan(["bowire scan"])
Fuzz(["bowire fuzz"])
SARIF[("SARIF reports")]
CS(["GitHub Code Scanning"])
Install --> Mock
BWR -->|"--recording"| Mock
Mock -->|"localhost:5099"| Tests
Mock -->|"--target"| Scan
Mock -->|"--target"| Fuzz
Scan -->|"--out findings.sarif"| SARIF
Fuzz -->|"--out fuzz.sarif"| SARIF
SARIF -->|"upload-sarif"| CS
bowire mock instance becomes the shared fixture for integration tests, bowire scan, and bowire fuzz in the same job. SARIF outputs flow straight into Code Scanning — alerts land in the calling repo’s Security tab without an intermediate format conversion.name: API check
on: [push, pull_request]
jobs:
api-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Bowire
run: dotnet tool install -g Kuestenlogik.Bowire.Tool
# 1. Mock server for integration tests
- name: Start mock server
run: bowire mock --recording fixtures/api.bwr --port 5099 &
- name: Run integration tests
run: dotnet test --filter Category=Integration
# 2. Security scan against the mock
- name: Security scan
run: |
bowire scan --target http://localhost:5099 \
--nuclei ~/nuclei-templates \
--out findings.sarif --severity medium
# 3. Field-level fuzz for regression
- name: Field-level fuzz
run: |
bowire fuzz --target http://localhost:5099 \
--template fixtures/api.bwr \
--payloads sqli,xss --out fuzz.sarif
# 4. SARIF goes to GitHub Code Scanning
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: findings.sarif
A reusable GitHub Action wraps the scan + SARIF-upload pair behind one uses: line for downstream repos — same pattern, less boilerplate.
Wire it in
Pull the binary, drop the three steps into your workflow, let SARIF light up your Security tab.