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.
Four subcommands carry the load: bowire mock as an integration-test fixture, bowire test as the regression gate, 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
Four 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 &
bowire test — regression gate
Run a recording or a flow file headless — the format is auto-detected. Inline assertions, snapshots, and data-driven rows all execute; a non-zero exit code fails the job. Emits JUnit for the test-report tab, SARIF for Code Scanning, and an HTML --report; --annotations writes GitHub check annotations and --fail-on sets the severity gate. Pair it with bowire contract verify to hold the provider to a published Pact-style contract.
# Replay the recording as a regression gate
$ bowire test fixtures/api.bwr --base-url http://localhost:5099 \
--junit test-results.xml --sarif test.sarif \
--annotations --fail-on error
# Hold the provider to the published contract
$ bowire contract verify fixtures/api.bwr \
--base-url http://localhost:5099
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 four 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"])
Btest(["bowire test"])
Scan(["bowire scan"])
Fuzz(["bowire fuzz"])
SARIF[("SARIF reports")]
CS(["GitHub Code Scanning"])
Install --> Mock
BWR -->|"--recording"| Mock
Mock -->|"localhost:5099"| Tests
Mock -->|"--base-url"| Btest
Mock -->|"--target"| Scan
Mock -->|"--target"| Fuzz
Btest -->|"--sarif test.sarif"| SARIF
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 test, 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. Regression gate + contract verify against the mock
- name: Regression test
run: |
bowire test fixtures/api.bwr --base-url http://localhost:5099 \
--junit test-results.xml --sarif test.sarif \
--annotations --fail-on error
bowire contract verify fixtures/api.bwr \
--base-url http://localhost:5099
# 3. Security scan against the mock
- name: Security scan
run: |
bowire scan --target http://localhost:5099 \
--nuclei ~/nuclei-templates \
--out findings.sarif --severity medium
# 4. 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
# 5. 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.