ITADN
svix/svix-webhooks
README.md
以下内容由 AI 翻译,如有问题请点此提交 issue 反馈

Svix - Webhooks as a service

网站 | 文档 | 社区 Slack

GitHub tag Build Status Server Security Twitter Follow Join our slack

Docker Pulls NPM Downloads Pypi Downloads

Svix 是企业级就绪的 webhook 服务

Svix 让开发者轻松发送 webhooks。开发者只需发起一次 API 调用,Svix 便会处理投递、重试、安全等事宜。更多信息,请参阅 Svix 主页

PyPI Crates.io NPM version Gem Maven Central (Java) Maven Central (Kotlin) Nuget Packagist Version PkgGoDev

文档

你可以在 https://docs.svix.com 找到通用使用文档。要查看包含所有官方客户端库中每个端点代码示例的完整 API 文档,请访问位于 https://api.svix.com 的 API 文档站点。

支持 & 社区

为了及时了解新功能和改进,请务必关注我们的仓库!

Watch & Star our repo

客户端库概览

⚡️ 功能细分 ⚡️
语言官方支持API 支持Webhook 验证其他备注
Go
Python
Typescript/Javascript
Java计划支持异步。(如果您使用 kotlin,请查看我们的 kotlin 库以获取协程支持。)
Kotlin
Ruby
C# (dotnet)
Rust
PHP
TerraformN/A

试用 CLI

Svix CLI 已发布在 npm 上,包名为 svix-cli。你可以直接使用 npx 运行它,无需安装任何内容:

npx svix-cli --help

或将其全局安装:

npm install -g svix-cli
svix-cli --help

运行服务器

有多种方式可以启动 Svix 服务器。Docker 可能是最常见的方式,但你可以选择最适合你的方式。

Svix 服务器使用 Rust 🦀 编写,这意味着你可以将其编译为适用于多种目标的静态库。有关更多信息,请参阅下面的从源代码构建部分。

有关可用设置的更多信息,请参阅下面的服务器配置部分。

部署

Docker

你可以使用来自 Docker Hub 的官方 Svix Docker 镜像。你可以使用 latest 标签,或者改用 版本化标签 之一。

你可以使用带有 docker compose(最简单)、docker swarm(高级)的示例 docker-compose.yml 文件,或者单独运行容器。

使用 Docker Compose

这种替代方案最简单,因为它还会启动并配置 redispostgresql

这假设你已安装 Docker Compose v2。

cd server
docker compose up

独立容器

运行独立容器稍微复杂一些,因为它要求你设置一些环境变量,并使它们指向你的 redispostgres 实例。 你可以使用 -e 标志将单个环境变量传递给 docker,或者创建一个类似 development.env 的文件,并像下面的示例那样使用 --env-file 标志:

docker run \
  --name svix-server \
  -p 8071:8071 \
  --env-file development.env \
  svix/svix-server

从源码构建

Svix 服务器使用 Rust 🦀 编写,需要一个 Rust 构建环境。

如果你已经拥有该环境,只需运行 cargo build,否则,请参阅 Svix 服务器 README 以获取有关从源码构建服务器的更多信息。

运行时依赖

服务器需要以下运行时依赖项才能正常工作:

  • 一个 PostgreSQL 服务器 - 用于存储事件。
  • 一个可选的 Redis 服务器,版本 6.2.0 或更高 - 用于任务队列和缓存。

Redis/Valkey 注意事项

持久性

请注意,建议在 Redis 中启用持久性,以便在 Redis 服务器重启和升级期间持久化任务。

驱逐策略

请确保你的 Redis 实例配置为在未显式设置 expire 策略的情况下不驱逐键。这意味着应将 maxmemory-policy 设置为 noeviction 或任何可用的 volatile- 策略。有关更多信息,请参阅 Redis/Valkey 文档。

服务器配置

配置 svix-server 有三种方式:环境变量、.env 文件以及配置文件。

配置文件

你可以在 svix-server 的当前工作目录中放置一个名为 config.toml 的文件,它将自动加载该文件。 你可以查看示例文件以获取更多信息和支持设置的完整列表:config.toml

以下是最重要配置的快速示例:

# The JWT secret for authentication - should be secret and securely generated
jwt_secret = "8KjzRXrKkd9YFcNyqLSIY8JwiaCeRc6WK4UkMnSW"

# The DSN for the database. Only postgres is currently supported.
db_dsn = "postgresql://postgres:postgres@pgbouncer/postgres"

# The DSN for redis (can be left empty if not using redis)
redis_dsn = "redis://redis:6379"

# What kind of message queue to use.
queue_type = "redis"

环境变量(变量或 .env

或者,你可以通过为每个受支持的设置设置等效的环境变量来配置 svix-server。环境变量可以直接传递,也可以通过在 .env 文件中设置它们。

环境变量的名称与配置名称相同,但它们全部为大写,并以 SVIX_ 作为前缀。

例如,如果上述示例配置通过环境变量传递,其形式如下:

# The JWT secret for authentication - should be secret and securely generated
SVIX_JWT_SECRET = "8KjzRXrKkd9YFcNyqLSIY8JwiaCeRc6WK4UkMnSW"

# The DSN for the database. Only postgres is currently supported.
SVIX_DB_DSN = "postgresql://postgres:postgres@pgbouncer/postgres"

# The DSN for redis (can be left empty if not using redis)
SVIX_REDIS_DSN = "redis://redis:6379"

# What kind of message queue to use.
SVIX_QUEUE_TYPE = "redis"

OpenTelemetry

您可以将跟踪信息发送到 OpenTelemetry Collector,它允许将跟踪事件转发到多个外部应用程序/服务,例如 DataDog、Jaeger、NewRelic、Prometheus、Sentry、Signoz 和 Zipkin。

您可以在这些说明中查看更多内容。

Connection Pool Size

db_pool_max_size 配置参数控制 PostgreSQL 连接池的最大允许大小。此值默认为最大 100,但增加此值可能会显著提高应用程序性能。在调整这些参数时,您可能还需要考虑 Postgres 和 PGBouncer 的配置参数。

redis_pool_max_size 参数控制每个 Svix 实例的 Redis 连接池的最大大小。其默认值为 100。请注意,只有 redis queuing 利用了连接池——缓存是完全异步的,因此不会从连接池中受益。因此,您可能不需要调整此参数。

SSRF Attacks and Internal IP Addresses

为防止 SSRF 攻击,默认情况下会阻止向内部 IP 地址的消息分发。然而,我们理解这并不满足所有用户的需求,例如,服务只能在内部访问。要绕过这些限制,请参阅 whitelist_subnets 配置选项,该选项接受一个 CIDR 表示法的子网数组,以允许向这些子网分发消息。

Webhook signature scheme (symmetric vs asymmetric)

为确保消息的安全性和完整性,Svix 在发送前会对所有 webhook 消息进行签名。 Svix 支持两种签名方案:对称(预共享密钥)和非对称(公钥)。

对称签名速度显著更快(签名约快 50 倍,验证约快 160 倍),且更为简单(这使得您的客户更容易进行验证),但它们需要每个端点使用一个预共享密钥(端点密钥)才能工作。另一方面,非对称签名只需要与您的客户共享一个公钥(而非密钥)。

基于上述原因,推荐使用对称密钥,这也是 Svix 的默认设置。其使用方法记录在文档中的验证签名部分]。

然而,在某些场景下,使用非对称签名可能更有益,因此它们也得到支持。更多信息请参阅下方的非对称签名部分]。

身份验证

使用用正确密钥生成的有效 JWT 作为 Bearer

E.g:

Authorization: Bearer <JWT_TOKEN_HERE>

或者使用

svix-server jwt generate

或者,如果您自行生成,请确保将 org_23rb8YdGqMT0qIzpgGwdXfHirMu 用作 sub 字段,并将 H256 用作算法。

使用密钥 x 的有效 JWT 示例(以便您可以查看其结构):

// JWT: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2NTUxNDA2MzksImV4cCI6MTk3MDUwMDYzOSwibmJmIjoxNjU1MTQwNjM5LCJpc3MiOiJzdml4LXNlcnZlciIsInN1YiI6Im9yZ18yM3JiOFlkR3FNVDBxSXpwZ0d3ZFhmSGlyTXUifQ.USMuIPrqsZTSj3kyWupCzJO9eyQioBzh5alGlvRbrbA
// Structure (when decoded):
{
  "iat": 1655140639,
  "exp": 1970500639,
  "nbf": 1655140639,
  "iss": "svix-server",
  "sub": "org_23rb8YdGqMT0qIzpgGwdXfHirMu"
}

使用不同的签名算法

如上所述,签名 JWT 的默认算法是 HS256。您可以通过将 jwt_algorithm 配置设置为以下受支持的值之一来选择不同的算法:HS384HS512RS256RS384RS512EdDSA

运营(入站)webhooks

运营 webhooks 是您可以订阅以接收 svix-server 上发生的重要事件通知的 webhooks。支持的事件列表可在 API 参考的 webhooks 部分 中找到。

运营 webhooks 使用 Svix,并由一个具有以下 ID 的特殊账户服务账户控制:org_00000000000SvixManagement00

第一步是通过将 operational_webhook_address 配置设置为指向您的 Svix 服务器来启用它。此设置最常见的值是 http://127.0.0.1:8071,但根据您特定的设置,它可能有所不同。

上述步骤在此实例上启用了运营 webhooks,下一步是为您的特定组织启用它。如上所述,运营 webhooks 在幕后使用普通的 Svix 账户,因此我们首先需要获取此账户的认证令牌。为此,您应该运行:

svix-server jwt generate org_00000000000SvixManagement00

这将为您提供一个特殊的 JWT,用于访问操作 Webhooks 账户,该 JWT 与您在与 Svix 交互时使用的常规 JWT 不同。例如,假设它返回的 JWT 为 op_webhook_token_123

要为特定账户启用操作 Webhooks,我们需要首先在服务账户中为其创建一个应用程序(请记住:操作 Webhooks 只是在后台使用 Svix)。我们将使用默认的 Svix 账户作为示例:org_23rb8YdGqMT0qIzpgGwdXfHirMu

curl -X 'POST' \
  'http://localhost:8071/api/v1/app/' \
  -H 'Authorization: Bearer op_webhook_token_123' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
        "name": "Operational webhook for default org",
        "uid": "org_23rb8YdGqMT0qIzpgGwdXfHirMu"
    }'

就是这样,我们现在已为默认账户启用了操作 Webhooks。剩下的唯一任务是添加一个端点,用于接收操作 Webhooks 的发送。例如:

curl -X 'POST' \
  'https://api.eu.svix.com/api/v1/app/org_23rb8YdGqMT0qIzpgGwdXfHirMu/endpoint/' \
  -H 'Authorization: Bearer AUTH_TOKEN' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
        "url": "https://operational-webhook-destination.com/webhook/",
        "filterTypes": [
          "endpoint.updated",
          "endpoint.deleted"
        ],
    }'

请注意,在创建端点时,我们使用默认账户的 org ID 作为 app_id(或者在本例中是 uid)。

就是这样。现在你应该已经拥有了可用的操作 Webhooks。如果你以后想创建新端点或修改现有端点,只需为服务账户生成一个 JWT,然后像使用任何其他 Svix 账户一样使用该 JWT。

非对称签名

如上所述,推荐使用对称签名。但是,如果你确定需要非对称签名,请阅读以下关于设置非对称签名的说明。

配置密钥

默认情况下,Svix 服务器会为端点生成对称密钥,这意味着消息将使用对称密钥进行签名。要更改此默认设置,请将 default_signature_type 配置设置为 ed25519,如下所示:

default_signature_type = "ed25519"

此外,无论默认值如何设置,你都可以通过在端点上显式设置密钥来覆盖它。 要设置对称密钥,请将端点密钥设置为以 whsec_ 为前缀的密钥,例如 whsec_51TKyHBy5KFY1Ab98GQ8V60BkWnejkWy。 要设置非对称密钥,请将端点密钥设置为以 whsk_ 为前缀的有效 ed25519 base64 编码私钥,例如:whsk_6Xb/dCcHpPea21PS1N9VY/NZW723CEc77N4rJCubMbfVKIDij2HKpMKkioLlX0dRqSKJp4AJ6p9lMicMFs6Kvg==

请注意,预期的私钥结构为:whsk_${base64(private_key + public_key)}

出于测试目的,可以使用以下命令生成新的非对称密钥对:

$ svix-server asymmetric-key generate

Secret key: whsk_6Xb/dCcHpPea21PS1N9VY/NZW723CEc77N4rJCubMbfVKIDij2HKpMKkioLlX0dRqSKJp4AJ6p9lMicMFs6Kvg==
Public key: whpk_1SiA4o9hyqTCpIqC5V9HUakiiaeACeqfZTInDBbOir4=

签名方案

Svix 使用 ed25519(m) 对 webhook 消息进行签名,并以与对称签名相同的方式构建 m

在验证消息时,你还应确保时间戳足够新,以限制重放攻击的可能性,如 对称验证文档 中所述。

关闭服务器

为了支持服务器的优雅关闭,在收到 SIGINT/SIGTERM 信号关闭之前,所有正在运行的任务都会完成。这通常耗时不到十秒。

与 Svix 托管服务的区别

我们将 Svix dispatcher 开源的主要目标之一是易用性。然而,托管的 Svix 服务由于我们的规模及其所需的基础设施而相当复杂。这种复杂性对绝大多数用户来说并无用处,并且会使该项目更难使用且功能受限。

因此,在发布之前,此代码已进行了调整,托管 dispatcher 支持的一些功能、优化和行为在此仓库中尚不可用。话虽如此,除了一些已知的不兼容性问题外,Svix 内部测试套件已通过。这意味着它们已经基本兼容,我们正在努力使其达到完全的功能对等。

Redis 任务队列 DLQ

在处理任务时,如果发生重复的内部错误,任务可能会进入死信队列(DLQ)。

Redis 不包含对 DLQ 的内置支持,因此在使用 Redis 队列后端时,Svix 会管理自己的 DLQ。因此,监控 DLQ 深度以确保其始终为空非常重要。您可以使用 svix.queue.depth_dlq 指标来执行此操作。非零值表示 DLQ 中存在需要处理的任务。

一旦错误条件结束,要重新驱动 DLQ,您可以向 /api/v1/admin/redrive-dlq/ 发送 POST 请求。

开发

查看我们的项目特定开发指南,开始对 Svix 进行开发!

贡献

贡献是开源世界运转的动力!我们非常欢迎并感激所有的贡献。

请参阅贡献指南以了解如何贡献。

贡献的快速指南:

  1. Fork 该项目
  2. 创建你的功能分支(git checkout -b feature/some-feature
  3. 进行你的更改
  4. 提交你的更改(git commit -m 'Implement an amazing feature.'
  5. 推送到分支(git push origin feature/some-feature
  6. 发起一个 Pull Request

License

基于 MIT License 分发。更多信息请参见 LICENSE

发送指南

以下是使用 Svix 发送 Webhooks 的指南列表:

Backed By

Backed By YC & Aleph