Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

42 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Switchyard — self-hosted webhook operations

Latest release CI Elixir 1.19 Phoenix 1.8 PostgreSQL 17 License Apache 2.0

Self-hosted webhook operations: receive, inspect, route, replay, and diagnose deliveries on your own infrastructure.


Get running in 60 seconds

You need Git, Docker, and Erlang/OTP + Elixir (see .tool-versions).

git clone git@github.com:jenksed/switchyard.git
cd switchyard
bin/setup        # starts PostgreSQL, installs deps, migrates, builds assets
bin/dev          # serves http://localhost:4000

Open http://localhost:4000 and click Create an endpoint. bin/setup is safe to run repeatedly.

Port clash? If 5432 is taken:

POSTGRES_PORT=55432 docker compose up -d db
export POSTGRES_PORT=55432

What it looks like

Workspace overview
Switchyard workspace overview
Event stream & inspector
Switchyard event stream and request inspector
Operations & health
Switchyard operations page
Create endpoint
Switchyard create endpoint form

What Switchyard does

Switchyard is a control point for the webhooks hitting your services. It sits between providers and your apps so you can see exactly what arrived, decide where it goes, and fix what broke.

  • Capture everything — exact bytes, malformed bodies, empty payloads, binary uploads. No request is silently dropped.
  • Inspect live — watch events stream in, inspect headers and body, with secrets masked by default.
  • Route intentionally — draft immutable routing versions with match/skip/label/send/stop actions, or fall back to fan-out.
  • Deliver safely — remote HTTPS destinations or localhost via an authenticated WebSocket relay. Private networks are never dialed from the server.
  • Replay & recover — retry, replay, or cancel deliveries. Full durable attempt history survives restarts.
  • Operate as a team — workspaces, role-based access, audit trail, encrypted secrets, and shareable evidence links.
  • Automate — stable REST API v1, switchyard CLI, SSE event streaming, and sanitized JSON/Markdown/HTML receipts.
  • Run anywhere — one non-root, read-only application image across dev, single-node team, and multi-node team profiles.

The diagnostic loop

flowchart LR
    P[Provider] -->|POST /in/token| I[Ingest]
    I -->|exact bytes, 202 after commit| E[(Event<br/>PostgreSQL)]
    E --> S[Live stream<br/>& inspector]
    E --> Q{Route<br/>evaluator-v1}
    Q --> D{Deliver selected}
    Q -->|labels + decision| S
    D -->|remote| R[HTTP destination]
    D -->|localhost| Y[Relay client]
    R -.->|500 → retry / replay → 200| E
    Y -.->|at-least-once| L[Local target]
    E --> C[Sanitized receipt]
Loading
  1. Create an endpoint; copy the ingest URL.
  2. Send any HTTP request to the ingest URL and watch it appear live.
  3. Route it with an immutable draft, dry-run against a captured event, then activate.
  4. Forward to a remote destination or run a local relay:
    mix switchyard.relay --server ws://localhost:4000 --token rel_… --target http://127.0.0.1:PORT
  5. Fail & replay — repair the receiver and replay; the full history is preserved.
  6. Export a sanitized receipt for your incident log.

For a complete walkthrough see docs/quickstart.md.

How it is built

  • PostgreSQL is the source of truth. PubSub only carries notifications.
  • At-least-once delivery. Duplicates are possible; exactly-once is not claimed.
  • Durable work runs on Oban — nothing important lives only in memory.
  • Localhost delivery goes through the relay so the server never dials private networks.
  • Thin web layer; domain contexts own behavior.

See docs/adr/ for the full architectural reasoning.

Deployment

Three profiles share one immutable application image:

Profile How to run
Single-node development bin/setup + bin/dev (or compose.yaml)
Single-node team compose.team.yaml + TLS proxy + external SMTP
Multi-node team compose.cluster.yaml — encrypted gossip, rolling upgrades, rehearsed rollback

Full details: docs/v0.9/PROFILES.md. Operational runbooks live at docs/runbooks/.

Verification

mix check        # format, compile (warnings as errors), Credo, security, tests
mix check.all    # everything above plus Dialyzer
bin/verify-v0.9  # full v0.9 operator exit gate

Release gates chain their predecessors, so bin/verify-v0.9 re-proves the complete tree.

The v0.9 tested-limits record (docs/v0.9/TESTED_LIMITS.md) includes a full two-hour soak at 19.74 events/s sustained on Apple M1 Pro / PostgreSQL 17.

Documentation

Roadmap

Stop Theme Status
v0.1–v0.8 Diagnostic loop → operational collaboration ✅ Complete
v0.9 v1 release candidate: multi-node, deployment profiles, tested limits, contract freeze 🔶 Release candidate
v1.0 Stable Switchyard (stability contract) Next
v1.1 Signal View — experimental operational lens Planned

Contributing

Read AGENTS.md for the project operating manual, coding standards, and release discipline.

License

Apache License 2.0. See LICENSE.