diff --git a/.github/workflows/bridge-release.yml b/.github/workflows/bridge-release.yml index 8afddede9..dbdb34252 100644 --- a/.github/workflows/bridge-release.yml +++ b/.github/workflows/bridge-release.yml @@ -1,11 +1,61 @@ -name: Webhook Bridge Release +name: Bridge Release on: - push: - branches: - - onelson/bridge + release: + types: [published] jobs: + release: + name: release ${{ matrix.target }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - target: x86_64-pc-windows-gnu + os: windows-latest + extension: ".exe" + + - target: x86_64-unknown-linux-gnu + os: ubuntu-latest + extension: "" + + - target: x86_64-apple-darwin + os: macos-latest + extension: "" + + - target: aarch64-apple-darwin + os: macos-latest + extension: "" + steps: + - uses: actions/checkout@master + + - name: Install Rust toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + profile: minimal + target: ${{ matrix.target }} + + - name: Install musl for x86_64-unknown-linux-musl + if: ${{ matrix.target == 'x86_64-unknown-linux-musl' }} + run: sudo apt-get install -y musl-dev musl-tools + + - name: Compile bridge + uses: actions-rs/cargo@v1 + with: + command: build + args: --target ${{ matrix.target }} --release --manifest-path bridge/svix-bridge/Cargo.toml + + - name: Release + uses: actions/upload-artifact@v3 + with: + name: svix-bridge-${{ matrix.target }} + path: bridge/target/${{ matrix.target }}/release/svix-bridge${{ matrix.extension }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + docker: name: release docker runs-on: ubuntu-latest @@ -25,16 +75,15 @@ jobs: uses: docker/setup-buildx-action@v2 - name: Derive Version Numbers - # FIXME: don't have a release name when running on a branch push - hardcode to 0.0.0 for now run: | - export REPO="${{ secrets.DOCKERHUB_USERNAME }}/svix-webhook-bridge" - echo DOCKER_TAGS="$(echo "v0.0.0" | sed -E "s#v([0-9]+)\.([0-9]+)\.([0-9]+)#${REPO}:latest,${REPO}:v\1.\2.\3,${REPO}:v\1.\2,${REPO}:v\1#")" >> "$GITHUB_ENV" + export REPO="${{ secrets.DOCKERHUB_USERNAME }}/svix-bridge" + echo DOCKER_TAGS="$(echo "${{ github.event.release.tag_name }}" | sed -E "s#v([0-9]+)\.([0-9]+)\.([0-9]+)#${REPO}:latest,${REPO}:v\1.\2.\3,${REPO}:v\1.\2,${REPO}:v\1#")" >> "$GITHUB_ENV" - name: Build and push Docker image uses: docker/build-push-action@v2 with: - context: ./webhook-bridge - file: ./webhook-bridge/Dockerfile + context: ./bridge + file: ./bridge/Dockerfile push: true tags: ${{ env.DOCKER_TAGS }} platforms: linux/amd64 diff --git a/.github/workflows/bridge-security.yml b/.github/workflows/bridge-security.yml new file mode 100644 index 000000000..6edd78380 --- /dev/null +++ b/.github/workflows/bridge-security.yml @@ -0,0 +1,24 @@ +name: Bridge Security + +on: + push: + branches: + - main + paths: + - 'bridge/**/Cargo.toml' + - 'bridge/**/Cargo.lock' + - '.github/workflows/bridge-security.yml' + pull_request: + paths: + - 'bridge/**/Cargo.toml' + - 'bridge/**/Cargo.lock' + - '.github/workflows/bridge-security.yml' + +jobs: + security_audit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: EmbarkStudios/cargo-deny-action@v1 + with: + arguments: --manifest-path=bridge/Cargo.toml diff --git a/bridge/Dockerfile b/bridge/Dockerfile index fa5d308e9..fa557860a 100644 --- a/bridge/Dockerfile +++ b/bridge/Dockerfile @@ -66,6 +66,7 @@ RUN apt-get update ;\ USER appuser COPY --from=build /app/target/release/svix-bridge /usr/local/bin/svix-bridge +EXPOSE 5000 # Will fail if there's no `svix-bridge.yaml` in the CWD or `SVIX_BRIDGE_CFG` is not set to a valid # path to a config. diff --git a/bridge/LICENSE b/bridge/LICENSE new file mode 100644 index 000000000..954e47172 --- /dev/null +++ b/bridge/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2021-2023 Svix Inc. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/bridge/README.md b/bridge/README.md index e78565a31..836d97ee8 100644 --- a/bridge/README.md +++ b/bridge/README.md @@ -1,6 +1,21 @@ -# Svix Bridge +

+ + +

Svix - Webhooks as a service

+
+

-`svix-bridge` is organized in terms of **senders** and **receivers**. +![GitHub tag](https://img.shields.io/github/tag/svix/svix-webhooks.svg) +[![Build Status](https://github.com/svix/svix-webhooks/workflows/Bridge%20CI/badge.svg)](https://github.com/svix/svix-webhooks/actions) +[![Bridge Security](https://github.com/svix/svix-webhooks/actions/workflows/bridge-security.yml/badge.svg)](https://github.com/svix/svix-webhooks/actions/workflows/bridge-security.yml) +[![License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE) +[![Join our slack](https://img.shields.io/badge/Slack-join%20the%20community-blue?logo=slack&style=social)](https://www.svix.com/slack/) + +# Svix Bridge (beta) + +Bridge is an agent to help integrate webhooks into your existing messaging infrastructure. + +Bridge is organized in terms of **senders** and **receivers**. **Senders** are useful when you have a data source (an "input") such as a message queue and want to generate Svix webhooks from those messages. @@ -8,6 +23,10 @@ message queue and want to generate Svix webhooks from those messages. **Receivers** act as HTTP endpoints which wait for Svix webhooks to arrive, then publish the payload on to a specified "output." +**Receivers** also (optionally) perform validation of the webhooks using Svix's signature verification. + +Both **senders** and **receivers** are defined in terms of their input, and optional JavaScript transformation, and their output. + Currently the supported Sender inputs and Receiver outputs are the following messaging systems: @@ -16,13 +35,28 @@ messaging systems: - Redis - SQS -## Usage +> Important to note that queues, exchanges, topics, etc should be created and configured independently, +> prior to using launching Bridge. Bridge will not automatically attempt to create these resources, it will only try +> (and fail) to read from or publish to the stream/queue in this case. + + +## Installation + +Docker images are available on [docker hub](https://registry.hub.docker.com/r/svix/svix-bridge) ``` -svix-bridge -c path/to/svix-bridge.yaml +$ docker pull svix/svix-bridge ``` -## Configuration +If you don't want to use docker, see [Building from Source](../README.md#building-from-source). + + + +# Usage and Configuration + +``` +$ svix-bridge -c path/to/svix-bridge.yaml +``` The CLI itself exposes only a single flag (`-c`, `--cfg`) used to set the path for the config file. The location of the config file can also be set with the `SVIX_BRIDGE_CFG` env var. @@ -34,7 +68,6 @@ Each sender and receiver can optionally specify a `transformation`. Transformations should define a function called `handler` that accepts an object and returns an object. Senders should produce JSON following an expected shape: - ``` { // This indicates which Svix application to send the message to @@ -52,21 +85,36 @@ Senders should produce JSON following an expected shape: > The comments in the above JSON are for illustrative purposes only ;) > That's not valid JSON! Sorry! - For detail on the `message` field, see: -Important to note that queues, exchanges, topics, or what have you, should be created and configured independently, -prior to using the plugin. There's nothing in place to automatically create these resources. -The plugin will only try (and fail) to read from the stream in such a case. +See the example configs for how to configure each input and output in more detail: +- [senders](./svix-bridge.example.senders.yaml) +- [receivers](./svix-bridge.example.receivers.yaml) -- GCP Pub/Sub -- RabbitMQ -- Redis -- SQS +# Building from source -The HTTP server also (optionally) performs validation of the webhooks using Svix's signature verification method. +You would need a working Rust compiler in order to build Svix Bridge. +The easiest way is to use [rustup](https://rustup.rs/). -The `verification` section for each route can be set one of two ways: -* `none` which accepts and forwards any JSON POST HTTP request. -* `svix` that takes a Svix endpoint secret (starting with `whsec_`) and - validating it using an official Svix library +``` +# Clone the repository +git clone https://github.com/svix/svix-webhooks +# Change to the source directory +cd svix-webhooks/bridge/ +# Build +cargo install --path svix-bridge +``` + +Some system dependencies are required for Bridge to build successfully. +Consult the [Dockerfile](./Dockerfile) for a good reference of what's required at build time. + +# Building with Docker + +``` +# Clone the repository +git clone https://github.com/svix/svix-webhooks +# Change to the source directory +cd svix-webhooks/bridge/ +# Build +docker build --tag svix-bridge:local . +``` diff --git a/bridge/generic-queue/LICENSE b/bridge/generic-queue/LICENSE new file mode 100644 index 000000000..954e47172 --- /dev/null +++ b/bridge/generic-queue/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2021-2023 Svix Inc. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/bridge/svix-bridge-plugin-queue/LICENSE b/bridge/svix-bridge-plugin-queue/LICENSE new file mode 100644 index 000000000..954e47172 --- /dev/null +++ b/bridge/svix-bridge-plugin-queue/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2021-2023 Svix Inc. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/bridge/svix-bridge-types/LICENSE b/bridge/svix-bridge-types/LICENSE new file mode 100644 index 000000000..954e47172 --- /dev/null +++ b/bridge/svix-bridge-types/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2021-2023 Svix Inc. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/bridge/svix-bridge.example.receivers.yaml b/bridge/svix-bridge.example.receivers.yaml index 2ddf2b4e7..46075f842 100644 --- a/bridge/svix-bridge.example.receivers.yaml +++ b/bridge/svix-bridge.example.receivers.yaml @@ -107,4 +107,4 @@ receivers: # - `AWS_ACCESS_KEY_ID` # - `AWS_SECRET_ACCESS_KEY` type: "sqs" - queue_dsn: "https://example.aws.com/my-queue" + queue_dsn: "https://aws.example.com/my-queue" diff --git a/bridge/svix-bridge/LICENSE b/bridge/svix-bridge/LICENSE new file mode 100644 index 000000000..954e47172 --- /dev/null +++ b/bridge/svix-bridge/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2021-2023 Svix Inc. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.