Highlights — Tier 4 of the security roadmap lands
Bowire's product positioning has been "Burp Suite for the non-HTTP protocols, with schema-awareness, self-hosted, with AI-assisted threat modeling via MCP." v1.9 closes the AI-assisted half of that promise — every discovered API surface in the workbench can now be analyzed by an LLM that grounds itself in the actual schema + traffic, not generic web knowledge.
- AI threat-model (#59) — rank every discovered endpoint by attack-surface risk. The model reads the API's input/output shapes, auth posture, and recent traffic, and returns a sorted list with reasoning per endpoint. Sets the scan order for everything that follows.
- AI Nuclei-template suggestion (#60) — per endpoint, generate Nuclei templates targeting the identified risks. Bowire feeds the model the OpenAPI / proto / GraphQL schema; the model returns YAML that drops straight into the Nuclei runner.
- AI findings triage (#61) — every Nuclei hit gets a real-vs-false-positive verdict + a concrete fix suggestion. Cuts triage time per finding by an order of magnitude on a noisy scan.
- AI schema-aware fuzz values (#62) — boundary inputs per field, derived from the schema's types + constraints. Composes with the existing fuzz harness.
- AI Settings UI (#63) — pick the provider (Ollama, LM Studio, BYOK cloud) + endpoint + model directly from the workbench's Settings dialog. No
appsettings.jsonedits, no restart.
The roadmap calls this Tier 4. Tiers 1–3 (record-as-attack, fuzz UI, MITM proxy) shipped through v1.4.x; Tier 5 (auto-exploit / proof-of-vulnerability) is its own framing and a different risk posture, deliberately out of scope here.
Also in this release
The 94 commits since v1.8.0 carry a lot more than the marquee. Highlights of the supporting work:
Security as a first-class drawer, with a tier that doesn't need AI (#111 + #112)
- Separate Security drawer. Threat-Model + Nuclei template suggestion left the AI drawer for their own surface (shield icon in the topbar,
Ctrl/Cmd+Shift+S). The AI drawer stays focused on conversational assistance (hints + chat). Mental model: AI = assistant, Security = scanner / analysis. - Heuristic ranking tier — no AI required. Default ranking is now a deterministic rule engine (
ThreatHeuristicin core): verb-based mutation scoring, BOLA-pattern detection on path params, admin / auth / PII path matching, anonymous-auth bumps, sensitive-field-name detection in the input shape. Sub-millisecond per endpoint. Each ranked row carries aruleTraceso users can audit which rules fired against which endpoint. - AI tier becomes opt-in. A tier toggle in the drawer lets the operator switch to AI-assisted ranking when they want semantic adjustments on top of the heuristic. Default heuristic → security tooling works on installs that don't have or don't want AI.
AI assistant — full MCP-style tool calling (#89, #108, #109)
- Phase 1: chat grounding. Every chat send prepends a workbench-state snapshot (loaded URLs + service names + selected method's full schema + recent calls) as a system prompt. The model answers from real data instead of generic web knowledge.
- Phase 2: read-only tools (#108). Three
Microsoft.Extensions.AIAIFunctions available on every chat request:bowire_list_services,bowire_describe_method,bowire_recent_history. The model calls them mid-conversation to drill in. The Ollama path is wrapped inFunctionInvokingChatClientso the tool-call loop actually round-trips. Tool calls render as visible "Consulted X" steps in the chat transcript with collapsible args. - Phase 3: invoke tool (#109). Opt-in via the "Allow AI to invoke methods" toggle in the drawer header. When OFF (default),
bowire_invokeisn't even registered — the model literally cannot try. When ON, the AI dispatches throughprotocol.InvokeAsync(same path/api/invokeuses) and every call writes a JSONL row to~/.bowire/.ai-actions.jsonlfor audit. Toggle is session-only — never persisted to localStorage. - Phase 4: UI navigation (#109).
bowire_open_methodtool lets the AI navigate the workbench to the right method ("Show mepet.findPetsByStatus" → workbench opens the request pane on it). Always available, no side effects beyond UI state. - "Thinking…" feedback in the drawer. Local models with tool calling take 15-45 s per turn. The chat now shows a live
(N s)counter with a pulsing accent dot + a Cancel button that aborts the fetch — no more wondering whether the request hung.
Workbench UX
- AI side panel moves into a right-side drawer (#90) with a topbar toggle +
Ctrl/Cmd+Shift+Ashortcut. Persists across method/service switches. Was a peer of Response/Logs/Code in the response-pane tab strip, which forced you to choose between seeing the AI and seeing the response. - Connection-state pill in the topbar (#93). Aggregate state for every configured discovery URL — green when all connected, amber when partial / connecting, red when any failed. Hover for a per-URL breakdown with service counts + the failure message.
- Body sub-tabs (#85). GraphQL Body now splits Query / Variables / Selection-set into a sub-tab strip; REST / gRPC / JSON-RPC get protocol-aware Form / JSON pair labels (gRPC: Message / JSON; JSON-RPC: Params / JSON; REST: Form / Body). Was a vertical stack of three surfaces; now one surface at a time.
- Filter services by discovery URL in the sidebar's filter popup. Multi-URL setups can narrow to one origin.
- Theme toggle dropped its visible label — tooltip still carries the state + next action; the topbar right cluster reads cleaner.
API conventions
- RFC 7807 ProblemDetails (#88) is the new shape for every API error response.
application/problem+jsonwith stabletypeURNs (urn:bowire:ai:model-not-found,urn:bowire:discovery:no-match, …), structureddetail, and typed extensions per error class. Backward-compatible: every body still carries anerrorfield set to the title so legacy readers degrade gracefully. - AI 404 errors now actionable (#87). Missing model surfaces as "Model 'X' isn't available — pull it with
ollama pull Xor pick a different model in Settings → AI", with alinks: [{rel: configure}]extension pointing back at the settings page.
Bug fixes
- #65 — URL input in the sidebar was read-only despite
lockServerUrl=false.el()helper coercedundefinedattribute values to the literal string"undefined", which the browser treats as truthy. - #66 — Settings → Plugins tab was in a fetch/render infinite loop; the plugins-tab fetches now fire once per tab-open instead of once per render.
- #81 — Standalone CLI without
--urlwas falling back to embedded UI mode because the heuristic checkedserverUrls.lengthinstead of trustingconfig.embeddedMode. - #82 — Standalone CLI's discovery endpoint short-circuited to
[]even when a runtime URL was passed via the sidebar. - #83 — Plugin discovery probes ran sequentially (12 plugins × ~2-3 s ≈ 30 s) and the frontend timed out at 12 s. Now parallel with
Task.WhenAll+ a 8 s per-probe ceiling. - #84 — Standalone discovery without a URL fell back to the workbench's own URL, which the JSON-RPC plugin matched with a phantom "Methods" stub.
- #86 — gRPC/HTTP transcoding toggle rendered on every REST method because the predicate didn't check
method.source === 'grpc'.
Docs
- New Topbar UI Guide page documenting the brand + command palette + connection pill + env selector + AI drawer.
- Phase F (multi-tenant UI affordances), SCIM (Phase C), and the single-user → multi-tenant migration path now tracked as discrete issues for the Cruise-ship-out-of-preview path.
Upgrading
- Pull the new tool:
dotnet tool update -g bowire - Or update an existing host:
dotnet add package Kuestenlogik.Bowire --version 1.9.0+ the matching protocol-plugin versions. - Frontend / ProblemDetails: nothing to change. Legacy
body.errorreads still work; newbody.title+body.detail+ extensions are additive. - AI defaults: if you don't have
Kuestenlogik.Bowire.Aiinstalled, every AI feature stays gracefully off and the Phase-1 hint engine continues working — no extra config required. - AI tool calling (#108 / #109): the chat side panel sends the workbench context with every request automatically. The
bowire_invokewrite-side tool is gated on the new drawer toggle ("Allow AI to invoke methods") — off by default; flip per session to let the AI dispatch real calls.