Skip to content
BreachPilot

AI providers

One contract. Any backend. You choose where inference runs.

Every chat and generate call goes through the ModelClient contract and a provider registry. Engine code never talks to a vendor SDK. Swap Ollama, OpenCode Go, or ChatGPT in config and your runs, memory, and reports keep working unchanged.

3 backends · one contractKeys in env onlyLocal embeddings optional

Authorized testing only. Only run BreachPilot against systems you own or have explicit written permission to assess.

3 backends · one contract

Provider catalog

Pick the backend that fits your lab. Each card shows the config keys it reads and where its secret lives: always the environment, never the config file.

  • Default · Local or Cloud

    ollama

    Ollama / Ollama Cloud

    Default chat/generate path: a cloud endpoint with bearer key, or a local daemon. Handles context-window translation and the model catalog sync.

    Local-first runs and air-gapped labs

    • Local daemon or Cloud endpoint
    • Context-window translation built in
    • Model catalog sync

    Config

    ollama.host · ollama.model glm-5.2:cloud · ollama.embed_host

    Auth · env only

    OLLAMA_API_KEY (environment only, never in config)

  • Hosted · OpenAI-compatible

    opencode_go

    OpenCode Go

    OpenAI Responses API over HTTPS. Model discovery from the provider's /models endpoint with caching.

    Strong reasoning over HTTPS

    • OpenAI Responses API
    • Automatic model discovery
    • Cached /models listing

    Config

    providers.opencode_go · base_url https://opencode.ai/zen/go/v1

    Auth · env only

    OPENCODE_GO_API_KEY (environment only)

  • Opt-in · Browser OAuth

    chatgpt

    ChatGPT

    Opt-in route via the vendored oauth/ loopback proxy, backed by browser OAuth. Tokens stay in the OAuth store.

    Reusing an existing ChatGPT plan

    • Loopback OAuth proxy
    • Tokens stay in OAuth store
    • Existence-checked, never inlined

    Config

    models.provider: chatgpt · loopback 127.0.0.1:10531

    Auth · env only

    ~/.codex/auth.json (existence-checked only, never read into config)

Architecture

Your run never touches a vendor SDK

Every backend behavior lives inside its adapter. The planner, swarm, and memory layers only ever see one stable interface. A provider swap is a config change, not a code change.

  1. Step 1

    Run asks for a role

    Planning, exploit drafting, peer consult, or titling requests a named role, not a vendor.

  2. Step 2

    Router resolves the client

    The model router maps each alias to a registered ModelClient built from your config.

  3. Step 3

    Adapter translates

    The adapter handles context windows, endpoints, and model discovery for its backend.

Role-based routing

Run planning on your strongest model, titling on the cheapest, and peer consult on a different family for a second opinion. Consulted models receive no tool schemas and cannot execute anything.

Embeddings stay local and optional

Semantic memory and skill matching embed over a local model on your own host by default. Disable embeddings entirely to fall back to keyword storage, with zero network traffic and zero secret reads.

Routing

Give each job the right brain

One provider for everything works. Splitting roles across models works better, and peer consult stays advisory either way.

RoleWhat it doesTip
PlanningBreaks the authorized objective into scoped stepsBenefits from the strongest reasoning model
ExploitationSelects capabilities and drafts payloads for targets the operator approvedBenefits from precise instruction following
Peer consultSecond opinion on findings and strategyAdvisory only, no tools, no execution
TitlingNames runs, steps, and report sectionsA small fast model is plenty

Secrets

Secrets live in the environment. Full stop.

Config files are shareable, diffable, and committable, so they must never contain a key. Each provider declares which variable it reads, and BreachPilot refuses to accept secrets any other way.

The rule, on every provider

  • Ollama / Ollama Cloud: OLLAMA_API_KEY (environment only, never in config)
  • OpenCode Go: OPENCODE_GO_API_KEY (environment only)
  • ChatGPT: ~/.codex/auth.json (existence-checked only, never read into config)

If a key ever lands in a config file, log, or shared snippet by mistake, rotate it. Treat the config as public.

config.yaml provider selection
models:
  provider: opencode_go   # ollama | opencode_go | chatgpt
providers:
  opencode_go:
    api_key_env: OPENCODE_GO_API_KEY   # env-only, never in config
  1. Export the key in your shell. Never paste it into config.yaml.
  2. Set models.provider to the backend you want for this lab.
  3. Restart the run and confirm the router resolves each role.

Full reference: providers · provider development · GitHub

Start local, scale to hosted when you need it

Begin on a local backend for authorized lab work, then point the same contract at a hosted model for harder targets. Always within scope, always operator supervised.