Skip to content

Releases: soapbucket/sbproxy

v1.1.0

07 Jun 05:44

Choose a tag to compare

Changelog

All notable changes to SBproxy v1.x. Versions before v1.0 shipped as the
Go implementation and now live in the archived
soapbucket/sbproxy-go
repository.

[Unreleased]

Work that has merged to main since the v1.1.0 tag and is queued for
the next version cut. No promises about backward compatibility for any
of the new YAML fields below until the version that ships them.

[1.1.0] - 2026-06-06

First minor release on the Rust v1.x line. This release carries
breaking changes to the MCP tool-access policy (now closed-by-default
and principal-aware); read the Breaking section and
docs/migration-mcp-rbac.md before upgrading. It also ships 66 native
AI providers behind one OpenAI-compatible API.

Breaking

  • MCP default-deny: ToolAccessPolicy flipped from
    open-by-default to closed-by-default. An unknown caller (no
    matching ACL rule) is denied every tool. An empty allowed: []
    list under an ACL rule means "deny all", not "allow all".
    Operators who want the legacy behaviour add default_allow: true
    on the origin's MCP action. The legacy key_permissions: { key: [tools] }
    shape is gone; rewrite to the principal-aware tool_access[]
    selector list. See docs/migration-mcp-rbac.md.

  • MCP principal-aware ACL: ToolAccessPolicy now
    carries tool_access[] rules with principals[] selectors
    (virtual_key, sub, team, project, user, role,
    tenant_id) plus an allowed[] tool list. The legacy
    key_permissions: HashMap<String, Vec<String>> map is removed
    along with ToolAccessPolicy::is_tool_allowed(key, tool); the new
    surface is policy.check(&principal, tool) -> ToolAccessDecision
    and policy.filter_tools(&principal, &tools). tools/list now
    filters by RBAC against the inbound principal (the legacy schema
    leaked tool names through tools/list even when the gate would
    deny the matching tools/call). A new tool_quotas[] table
    enforces per-tool sliding-window quotas keyed on
    (tenant_id, principal_id, tool_name). See
    docs/migration-mcp-rbac.md.

Added

  • 66 native AI providers behind one OpenAI-compatible API. The
    embedded ai_providers.yml registry ships 66 providers (up from 43),
    adding Hugging Face Inference, GitHub Models, Vercel AI Gateway,
    Nebius, Baseten, Lambda, FriendliAI, Scaleway, Nscale, DigitalOcean
    Gradient, OVHcloud, Inference.net, kluster.ai, OpenPipe, Writer,
    Upstage, Aleph Alpha, MiniMax, Volcengine Ark (Doubao), Tencent
    Hunyuan, Baidu Qianfan (ERNIE), StepFun, and Mixedbread. The catalog
    is plain YAML and operator-extensible at runtime via
    proxy.ai_providers_file; the model field passes through to the
    upstream, so any model a provider serves is reachable without
    per-model config. The "200+ models" reach is native (bring your own
    keys); OpenRouter is one provider among the 66, not a dependency. See
    docs/providers.md#extending-the-provider-catalog.

  • Session ledger from live MCP traffic. A new top-level
    session_ledger: block makes SBproxy emit the canonical
    session-ledger-v1 run record (shared with mcptest) from its
    tools/call path: one header per session, then one tool_call
    record per call carrying session_id, a zero-based hop_index, the
    bare tool name and server, redacted params / result, an error
    flag, and the round-trip duration_ms. sink: logging (default)
    emits each record as a session_ledger tracing line; sink: file
    with a path: appends NDJSON. Off unless enabled: true; when off
    the tool-call path pays only a single atomic load. Payloads are
    redacted with the same secret-stripping the access log uses. See
    docs/mcp.md and examples/mcp-federation/sb.yml.

  • Structured-log schema v2 (SCHEMA_VERSION = "2"). Three changes
    land together so downstream tooling can read them in one swing:
    optional session_id and user_id top-level fields parallel the
    RequestEvent envelope (cross-surface JOIN no longer relies on
    request_id alone); the field-key redaction marker is normalised
    to [REDACTED:<NAME>] everywhere (was <redacted:name> in v1) so
    the schema-v1 layer matches the existing PII-rule replacement
    shape; the schema bump is additive on the field set (a v1 reader
    parsing a v2 line keeps working because every new field is
    skip_serializing_if = Option::is_none). Marker normalisation is
    a string change; downstream tooling that greps for the old
    <redacted:...> form must update.

  • Phase-timing breakdown on the access log + new
    sbproxy_phase_duration_seconds Prometheus histogram.
    The
    access log carried latency_ms end to end and that was it; an
    operator looking at a slow request could not tell from the log
    whether the time went to the auth provider, the upstream, or a
    response transform. Three new optional fields land on every
    AccessLogEntry: auth_ms (request_start → auth provider
    returned), upstream_ttfb_ms (request_start → first upstream
    response byte), response_filter_ms (first upstream byte → end
    of response_filter). All three are Option<f64> and
    serde-skip when None, so origins that short-circuit (cache
    hit, auth deny) keep compact lines. The same observations also
    feed a new sbproxy_phase_duration_seconds{phase, origin}
    histogram with buckets identical to
    sbproxy_request_duration_seconds for cross-cut dashboards. See
    docs/access-log.md and docs/metrics-stability.md.

  • Nine standard HTTP fields on the access log: host, query,
    protocol, scheme, user_agent, referer, upstream_status,
    response_content_type, response_content_encoding.
    The log
    was missing the canonical fields most HTTP access-log consumers
    expect (Apache, NGINX, Envoy, the cookie-cutter ELK pipeline).
    host is the client-supplied Host header (distinct from
    origin, the matched virtual-host pattern); upstream_status
    is the upstream's response code when the proxy rewrote the
    status the client sees. All nine are Option, serde-skip when
    not applicable. Promoted from the generic header allowlist
    because nearly every analytics consumer wants them. See
    docs/access-log.md.

  • Opt-in OpenTelemetry metrics mirror alongside the canonical
    Prometheus surface.
    New telemetry.export_metrics: true
    (with telemetry.metrics_interval_secs cadence, default 30s)
    installs an OTel MeterProvider that ships observations to the
    same OTLP collector the trace pipeline targets. The first two
    mirrored instruments are sbproxy.phase.duration and
    sbproxy.request.duration; record-paths fall back to OTel's
    global no-op meter when the export is off, so operators pay
    nothing for the mirror unless they opt in. The Prometheus
    surface remains canonical; this is for operators who already
    aggregate via Mimir / Datadog / Honeycomb and want to skip the
    Prometheus scrape.

  • OIDC Relying-Party stack shipped end to end.
    /oidc/callback (auth-code + PKCE + sealed session cookie)
    plus the helpers + config wiring for
    /.well-known/openid-configuration discovery, refresh-token
    rotation, RP-initiated logout at /oidc/logout, userinfo →
    X-Auth-* trust headers, an optional server-side session store
    (in-memory + KV-backed redb/file/Redis) for targeted revocation.
    See docs/configuration.md § OIDC auth.

  • OpenAI Apps SDK / MCP Apps (SEP-1865) compatibility.
    Gateway-side _meta.mcpApps passthrough for tool definitions,
    params.audit.cause plumbing on tools/call, and a typed
    validator set (apps.template_declared, apps.iframe_sandbox,
    apps.csp_present, apps.cache_metadata) usable by sbproxy,
    the enterprise extension, and any CI gate over the
    sbproxy-plugin surface.

  • Web Bot Auth full conformance, publish + sign sides.
    SBproxy now publishes its own JWKS-shaped
    directory at /.well-known/http-message-signatures-directory
    and a Signature Agent Card at
    /.well-known/web-bot-auth/agent-card (opt in via
    web_bot_auth_publish per origin). New
    sbproxy-middleware::signatures::MessageSignatureSigner
    primitive signs outbound requests per RFC 9421, round-trips
    through the existing verifier. See docs/web-bot-auth.md and
    examples/web-bot-auth-publish/.

  • Three previously-undocumented OSS policies now have docs +
    runnable examples:
    object_authz (BOLA + BFLA with
    enumeration detection), content_digest (RFC 9530 request-body
    verification), agent_budget (per-agent semantic rate limit).
    See docs/object-authz.md, docs/content-digest.md,
    docs/agent-budget.md.

  • Discoverable FAQ. docs/faq.md covers install, common
    401 causes, OIDC minimal config, log levels, OSS-vs-enterprise
    scope, and pointers into the rest of docs/. Wired into
    docs/README.md under "Getting started".

  • Explicit SIGINT/SIGTERM handling with a structured shutdown
    event and a 30s default drain budget.
    Pingora's
    Server::run_forever already trapped SIGTERM and SIGINT, but
    the proxy emitted no operator-facing log line on receipt, so a
    pod eviction or docker stop looked the same as a crash in the
    log stream. This change subscribes to Pingora's execution-phase
    broadcast and emits shutdown_signal_received,
    shutdown_grace_period, and shutdown_complete tracing events
    with the resolved grace budget. The Kubernetes operator
    (sbproxy-k8s-operator) now installs the same SIGINT/SIGTERM
    handlers via tokio::signal::ctrl_c and
    tokio::signal::unix::signal(SignalKind::terminate()); before
    this change the operator relied on the orchestrator SIGKILL at
    terminationGracePeriodSeconds. The drain budget is the new
    SBPROXY_SHUTDOWN_GRACE_MS env var (or --shutdown-grace-ms
    CLI flag) which defaults to 30000ms, matching Kubernetes'
    default terminationGracePeriodSeconds. The legacy
    SB_GRACE_TIME / --grace-time (seconds) still works and
    takes precedence when expli...

Read more

v1.0.1

04 May 16:14

Choose a tag to compare

Changelog

All notable changes to SBproxy v1.x. Versions before v1.0 shipped as the
Go implementation and now live in the archived
soapbucket/sbproxy-go
repository.

[1.0.1] - 2026-05-04

Patch release. No runtime behavior changes.

Fixed

  • Container image publish: the release.yml workflow's docker
    prepare step extracted the flat-layout tarballs into /tmp/
    directly, which tripped a sticky-bit Cannot utime error on the
    archive's ./ entry and caused ghcr.io/soapbucket/sbproxy:1.0.0
    to never publish. Each platform tarball now extracts to a per-arch
    staging dir before the binary moves into the docker context.

[1.0.0] - 2026-05-03

First Rust release of SBproxy on this repository.

What changed

  • Implementation: SBproxy is now written in Rust on Cloudflare's
    Pingora. The Go implementation that previously occupied this repo
    (v0.1.0 through v0.1.2) has moved to
    soapbucket/sbproxy-go,
    preserved as the v0.1.2-go-final branch and tag, and is now in
    maintenance-only mode.
  • Data plane: routing, AI gateway, MCP gateway, guardrails, security
    policies, and scripting (CEL, Lua, JavaScript, WebAssembly) all ship
    open source in this release. See docs/architecture.md
    for the request pipeline shape.
  • Enterprise tier: see docs/enterprise.md for
    what enterprise adds on top of the OSS data plane and how to request
    access.

Upgrading from v0.1.x (Go)

The internal config schema (schema-v1) is supported by both the Go
v0.1.x line and this Rust v1.x line, so existing sb.yml files
should compile unchanged. See MIGRATION.md for the
full upgrade path.

v1.0.0

04 May 15:05

Choose a tag to compare

Changelog

All notable changes to SBproxy v1.x. Versions before v1.0 shipped as the
Go implementation and now live in the archived
soapbucket/sbproxy-go
repository.

[1.0.0] - 2026-05-03

First Rust release of SBproxy on this repository.

What changed

  • Implementation: SBproxy is now written in Rust on Cloudflare's
    Pingora. The Go implementation that previously occupied this repo
    (v0.1.0 through v0.1.2) has moved to
    soapbucket/sbproxy-go,
    preserved as the v0.1.2-go-final branch and tag, and is now in
    maintenance-only mode.
  • Data plane: routing, AI gateway, MCP gateway, guardrails, security
    policies, and scripting (CEL, Lua, JavaScript, WebAssembly) all ship
    open source in this release. See docs/architecture.md
    for the request pipeline shape.
  • Enterprise tier: see docs/enterprise.md for
    what enterprise adds on top of the OSS data plane and how to request
    access.

Upgrading from v0.1.x (Go)

The internal config schema (schema-v1) is supported by both the Go
v0.1.x line and this Rust v1.x line, so existing sb.yml files
should compile unchanged. See MIGRATION.md for the
full upgrade path.

v0.1.2-go-final

04 May 02:12
33f7303

Choose a tag to compare

Changelog

  • d7e2c42 Bump dorny/paths-filter from 3 to 4
  • db783e0 Bump github/codeql-action from 3 to 4
  • e95ac44 Bump google.golang.org/api from 0.275.0 to 0.276.0
  • b78e049 Merge branch 'main' into docs/readme-and-site-update
  • 4697a27 Merge pull request #18 from soapbucket/rickcrawford-patch-1
  • aed73ad Merge pull request #19 from soapbucket/docs/readme-and-site-update
  • f17aa3b Merge pull request #21 from soapbucket/docs/readme-redesign
  • 4bb5600 Merge pull request #22 from soapbucket/chore/add-notice-file
  • 6266e36 Merge pull request #23 from soapbucket/dependabot/github_actions/github/codeql-action-4
  • e21ec2c Merge pull request #24 from soapbucket/dependabot/github_actions/dorny/paths-filter-4
  • 591b183 Merge pull request #25 from soapbucket/dependabot/go_modules/google.golang.org/api-0.276.0
  • a222ebb Merge pull request #26 from soapbucket/chore/add-notice-file
  • bb0c103 Merge pull request #27 from soapbucket/adding-new-features
  • 66a0ff3 Merge pull request #28 from soapbucket/adding-new-features
  • 4402d9e Merge pull request #29 from soapbucket/rickcrawford-patch-1
  • c1a1ddf Merge pull request #30 from soapbucket/dependabot/go_modules/github.com/pires/go-proxyproto-0.12.0
  • 8ec7700 Merge pull request #31 from soapbucket/dependabot/go_modules/modernc.org/sqlite-1.49.1
  • dec9446 Merge pull request #32 from soapbucket/fix-ai-pool-circuit-concurrent-load
  • 189096c Merge pull request #33 from soapbucket/adding-new-features
  • 711a9cc Merge pull request #34 from soapbucket/chore/archive-notice-and-deps
  • be2c630 Merge pull request #35 from soapbucket/chore/move-archive-notice-to-archive-repo
  • 33f7303 Merge pull request #36 from soapbucket/fix/e2e-case18-wait
  • d037fbf README cleanup
  • bb4cebc Remove GitHub Discussions link from README
  • 7c6e324 Rewrite README with feature-first, technology-agnostic messaging
  • c296a85 chore(deps): bump github.com/pires/go-proxyproto from 0.11.0 to 0.12.0
  • 9a9e61f chore(deps): bump modernc.org/sqlite from 1.48.2 to 1.49.1
  • 454b282 chore(readme): move archive notice to soapbucket/sbproxy-go
  • 539769e chore: add Go-archive notice + bump gomarkdown for CVE
  • 3657f2a chore: add NOTICE file for Apache 2.0 third-party attribution
  • 3444b15 chore: update e2e configs to use new security headers array and session key
  • b9396c0 feat(go): implement all 111 IMPLEMENTATION-GO.md features (P0-P9)
  • bb3c467 fix(ai): tune upstream pool and circuit breaker for concurrent load
  • f323ee8 fix(e2e): scope wait to flood curls in case 18 + bound them with --max-time
  • 4440bc5 fix(lint): simplify postServer declaration in SSE client test
  • d1aeae0 fix(security): mitigate reflected XSS on /metrics endpoint
  • 1d94b19 fix: resolve data race in mirror test and stripe pattern in secret warner
  • e3d730d perf(transport): match upstream pool tuning to Pingora baseline
  • eee11fa refactor: security_headers array format and session field rename

v0.1.2

12 Apr 23:40
2c86051

Choose a tag to compare

Changelog

  • fcff782 Change cloud hosting link to sbproxy.dev
  • f5352ee Fix CI running on docs-only PRs
  • 49c22e7 Fix CI skip for docs-only PRs (use step-level conditions) (#16)
  • 393813e Fix Go version badge to match go.mod (1.25)
  • d88aa8d Merge branch 'main' into feature-added-providers
  • 3fe4610 Merge branch 'main' into fix-comparison-doc
  • e3d1c77 Merge pull request #10 from soapbucket/fix-install-script
  • d7ca471 Merge pull request #11 from soapbucket/feature-added-providers
  • 59392fe Merge pull request #12 from soapbucket/feature-added-providers
  • 4738c27 Merge pull request #13 from soapbucket/rickcrawford-patch-1
  • c7833e9 Merge pull request #14 from soapbucket/fix/ci-skip-docs-only
  • 79246a1 Merge pull request #15 from soapbucket/rickcrawford-patch-1
  • 2c86051 Merge pull request #17 from soapbucket/fix-version
  • 7f4d033 Merge pull request #8 from soapbucket/fix/readme-go-version-badge
  • ebe88f4 Merge pull request #9 from soapbucket/fix-comparison-doc
  • 73956cd Update README
  • b391409 added providers
  • af88581 fixed flaky test
  • dac4c14 fixed race condition in test
  • 0a5e9a9 fixed version
  • d710844 moved codeql to build task
  • ad57f12 set to pr only
  • 679dd23 uddated ci to skip md file changes
  • 5a31939 updated comparison
  • b725592 updated docs
  • 88467bc use user's bin dir

v0.1.1

12 Apr 17:28

Choose a tag to compare

Changelog

  • c8b5131 Fix MaxConnections returning nil error on context cancellation
  • 666e234 Fix goreleaser retry failures by replacing existing release assets
  • 148deee Initial release: SBproxy v0.1.0

v0.1.0

12 Apr 16:38

Choose a tag to compare

Changelog

  • cad2626 Fix MaxConnections returning nil error on context cancellation
  • 666e234 Fix goreleaser retry failures by replacing existing release assets
  • 148deee Initial release: SBproxy v0.1.0