openapi

Your gateway is your spec.
Stop maintaining two.

SBproxy emits OpenAPI 3.1 directly from the policy graph. Every route, auth method, rate limit, and cache rule is generated from the config that already runs in production. Drift is impossible because there is no second source.

tagline
One file in. Three artifacts out: OpenAPI, MCP tools, audit log.
sb.yml
live example
# sb.yml: one origin, one route, one auth, one rate limit
origins:
  "api.example.com":
    expose_openapi: true
    action:
      type: proxy
      url: https://upstream.internal:8443
    authentication:
      type: api_keys
      header: X-API-Key
    forward_rules:
      - rules:
          - path: { template: /users/{id} }
        parameters:
          - name: id
            in: path
            required: true
▶ sb.yml → openapi.yamlfull reference →
01 / the three drifts

The three places
API documentation
falls out of sync.

Every team that ships an API ships at least three artifacts that claim to describe it. The spec, the gateway config, and the consumer integrations. They start aligned. They do not stay aligned.

One source of truth closes all three drifts.

D1spec vs gateway
D2declared vs enforced auth
D3spec vs downstream tools
D01spec drift

Your spec lives in a Git repo. Your gateway lives in production.

A platform engineer renames a field. A security lead tightens an auth scheme. The gateway picks the change up on the next reload. The OpenAPI file in your docs repo learns about it weeks later, if at all.

D02auth drift

OpenAPI security schemes describe what auth should look like. The gateway enforces what auth actually runs.

Your spec says bearer token. The gateway runs JWT with JWKS rotation, or mTLS, or an API key plus IP allowlist. Auditors notice. Partners hit 401s the SDK stubs never anticipated.

D03tool drift

MCP tools, partner SDKs, and your own clients all read the spec. Each consumer ships with stale assumptions.

One spec generates dozens of artifacts. Each generation freezes the surface at a moment that no longer matches the gateway. New routes are missing. Removed routes are still callable in stub code that did not get the memo.

02 / the reframe

One config.
One contract.
One audit log.

The policy graph that runs in production is the same artifact that emits the spec. Routes, auth schemes, rate limits, and response shapes come from the YAML the gateway already compiled. There is no second pipeline to keep honest.

01 / emit

OpenAPI 3.1 generated on every config reload.

Deterministic output. Byte-stable across reloads so a Git diff of the emitted spec only changes when the config changes. Schemas, security schemes, error responses, and examples come from the YAML the gateway runs.

  • + Routes from forward_rules (exact, prefix, template, regex)
  • + Security schemes from auth_config, every type covered
  • + Response codes from response_cache and error_pages
  • + Vendor extensions for rate limits, cache, and CORS
  • + Per-host or workspace-wide via the admin endpoint
  • + Per-host /.well-known/openapi.json publishing, opt-in
02 / validate

Every inbound request validated against the contract.

Reject non-conforming requests at the gateway, before they reach your service. Optional shadow mode logs violations without blocking, so a rollout never breaks existing partners. The validator runs on the same compiled chain as auth.

  • + Request body, query, path, and header validation
  • + Response body validation, blocking or shadow
  • + Per-route override for legacy endpoints
  • + Standard 4xx for non-conforming traffic
  • + Audit event on every reject and shadow violation
  • + Zero allocations on conformant requests
03 / re-export

The same surface, re-exported for every consumer.

Point an MCP client, a Postman workspace, or a partner SDK generator at the same emitted spec. Each consumer reads the live shape of the API. When the gateway changes, every consumer sees the change on its next fetch.

  • + MCP tools generated from the same source
  • + Postman, Insomnia, and Bruno collection export
  • + Partner SDK stubs via standard generators
  • + Interactive console at /spec, off by default
  • + Schema-backed examples that pass validation
  • + No second server to write or staff
03 / emission

sb.yml is the canonical source.
openapi.yaml is generated.

Twelve lines of origin config produce the OpenAPI 3.1 fragment below. Reload the gateway and the document follows. Diff the output in CI to catch breaking changes before they ship.

input  ·  sb.yml
origins:
  "api.example.com":
    expose_openapi: true
    action:
      type: proxy
      url: https://upstream.internal:8443
    authentication:
      type: api_keys
      header: X-API-Key
    policies:
      - type: rate_limit
        requests_per_minute: 120
    response_cache:
      cacheable_status: [200, 404]
    forward_rules:
      - rules:
          - path: { template: /users/{id} }
            allowed_methods: [GET]
output  ·  openapi.yaml or openapi.json
openapi: 3.1.0
info:
  title: api.example.com
  version: 1.0.0
servers:
  - url: https://api.example.com
paths:
  /users/{id}:
    get:
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200': { description: OK }
        '404': { description: Not Found }
      security:
        - apiKeyHeader: []
      x-rate-limit:
        requests_per_minute: 120
      x-cache-policy:
        cacheable_status: [200, 404]
components:
  securitySchemes:
    apiKeyHeader:
      type: apiKey
      in: header
      name: X-API-Key
04 / what changes

Contract enforcement,
in the hot path.

Validation runs on the same policy graph as auth and rate limiting. There is no separate validator service to staff, no second hop to manage, no extra place where the contract can fall behind reality.

  • Stop non-conforming requests at the edge, not in your service.
  • Reject responses that violate the schema before they leave your network.
  • Catch breaking changes in CI by diffing the emitted spec.
  • Generate partner SDKs from the spec the gateway actually enforces.
  • Hand auditors a contract that proves what runs in production.
  • Re-export the same surface as MCP tools without writing a second server.
in the engine

What ships in the data plane.

For engineers in the buying committee. The capabilities behind the outcomes above.

  • 01
    Deterministic emissionOpenAPI 3.1, byte-stable across reloads. The same config produces the same document every time.
  • 02
    Schema validationRequest and response body validation on the hot path. Block, log, or shadow per route.
  • 03
    Vendor extensionsx-rate-limit, x-cache-policy, x-sbproxy-auth surface gateway concepts OpenAPI does not natively cover.
  • 04
    CI spec diffDiff the emitted spec against a baseline file in CI. Detect breaking changes before merge.
  • 05
    MCP tool emissionThe same spec generates MCP tool descriptors. One source of truth across REST and MCP.
  • 06
    Collection exportPostman, Insomnia, and Bruno collections built from the live config. Refresh on every reload.
  • 07
    Schema-backed examplesExamples generated from the schema and validated as part of the emission build.
  • 08
    Interactive consoleOptional interactive console served at /spec per origin. Off by default. Reads the live document.
who it's for
You, if
  • You maintain an OpenAPI spec by hand and it lags weeks behind the gateway.
  • You ship MCP tools and need them to track your REST surface.
  • You have partners consuming your API who break when fields change quietly.
  • Your auditors ask for a contract that proves what runs in production.
  • Your platform team is tired of being the tax on every API change.
Replaces
StoplightRedoclyReadMeHand-rolled OpenAPI generatorsMCP server scaffoldsBespoke spec linters
06 / talk to us

Want to talk
before you install?

The gateway is on GitHub under Apache 2.0 and you can install it right now, so nothing here is gated behind a sales call. Use this form for deployment questions, migration scoping, or anything you would rather not file as a public issue.

01
Share your stack. A few details on providers, scale, and the gateway you might be replacing.
02
Talk to engineering. A real conversation about whether SBproxy fits the deployment shape you have in mind. No demo theatre.
03
Get a straight answer. Including when the answer is that SBproxy is the wrong fit and you should run something else.