Skip to content

runax-software/runax-hookpipe

Hookpipe

GHCR CI License: MIT

Config-driven webhook gateway. Receive HTTP webhooks, validate them, and route messages to queues.

How it works

External service (GitHub, Stripe, Coolify, etc.)
  → POST https://hooks.yourdomain.com/github/push
    → Hookpipe matches route from config
      → validates request (signature, bearer token)
        → wraps in message envelope
          → produces to sink (RabbitMQ, Kafka, SQS, HTTP, stdout)
            → returns 202 Accepted

Quick start

Docker

docker run -p 8080:8080 \
  -v ./config:/app/config \
  -e RABBITMQ_URL=amqp://guest:guest@rabbitmq:5672 \
  ghcr.io/runax-software/hookpipe:latest

From source

git clone https://github.com/runax-software/runax-hookpipe.git
cd runax-hookpipe
cp .env.example .env

# Start RabbitMQ + Kafka (optional)
docker compose up -d

dotnet run --project src/Hookpipe.API

Test

curl -X POST http://localhost:8080/test/webhook \
  -H "Content-Type: application/json" \
  -d '{"hello":"world"}'

Config

Define endpoints and sinks in config/hookpipe.yaml:

endpoints:
    - id: github-push
      path: /github/push
      methods:
          - POST
      validation:
          signature:
              header: X-Hub-Signature-256
              secret_env: GITHUB_WEBHOOK_SECRET
              algorithm: hmac-sha256
      sinks: # Fan-out to multiple sinks
          - rabbitmq-main
      message:
          include_body: true
          include_headers: true
          header_filter:
              - X-GitHub-Event
              - X-GitHub-Delivery

sinks:
    - id: rabbitmq-main
      type: rabbitmq
      settings:
          url_env: RABBITMQ_URL
          exchange: webhooks
          routing_key: events

See Configuration for full reference.

Hot-reload

Hookpipe watches the config file and reloads automatically when it changes. Validation rules, sink routing, message config, and allowed methods can be changed without restart. See Configuration for details.

Sinks

Sink Type Status
Stdout stdout Available
RabbitMQ rabbitmq Available
Kafka kafka Available
HTTP Relay http Available
SQS sqs Available
Redis Streams redis-stream Available
Google Pub/Sub google-pubsub Available
SNS sns Available
EventBridge eventbridge Available

See Sinks for details.

Validators

Validator Type Use case
Bearer token bearer Coolify, custom webhooks
HMAC-SHA256 hmac-sha256 GitHub, Shopify
Stripe stripe-v1 Stripe webhooks
API key api-key Custom header + key
IP allowlist ip-allowlist Restrict by IP/CIDR

See Validators for details.

Message envelope

Every webhook is wrapped in a standardized envelope:

{
    "id": "13979c7e-108c-48b1-aac5-ff9220a3875b",
    "endpointId": "github-push",
    "receivedAt": "2026-05-07T16:23:55.644839+00:00",
    "method": "POST",
    "path": "/github/push",
    "remoteAddress": "192.30.252.1",
    "headers": { "X-GitHub-Event": "push" },
    "body": { "ref": "refs/heads/main" },
    "metadata": {}
}

See Message Envelope for full format.

Environment variables

Variable Description Default
HOOKPIPE_CONFIG_PATH Path to YAML config config/hookpipe.yaml
HOOKPIPE_MAX_BODY_SIZE_MB Max request body size (MB) ~28.6 (Kestrel default)
RABBITMQ_URL RabbitMQ connection string
KAFKA_BROKERS Kafka broker list
SEQ_URL Seq server URL — (disabled)
LOKI_URL Grafana Loki URL — (disabled)

See Configuration for all env vars and Logging for log destinations.

Endpoints

Method Path Description
GET /health Liveness check
GET /metrics Prometheus metrics
* /* Dynamic — defined in config

See Metrics for available metrics and Prometheus scrape config.

Contributing

See CONTRIBUTING.md.

License

MIT

About

Config-driven webhook gateway that routes HTTP callbacks to message queues (SQS, Kafka, RabbitMQ) with pluggable validation and a consistent message envelope.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors