go-routine-id/bifrost-guardrail-plugin

GitHub: go-routine-id/bifrost-guardrail-plugin

为 Bifrost LLM 网关提供 system prompt 注入和正则输入拦截的内置治理插件,解决静态编译环境下无法动态加载插件的问题。

Stars: 0 | Forks: 0

# bifrost-guardrail-plugin 一个内置的 [Bifrost](https://github.com/maximhq/bifrost) HTTP-transport 插件,它可以: 1. 将**治理 system prompt 注入**到每个推理请求中,并且 2. **拦截**用户输入匹配已配置 regex 模式的请求(返回 HTTP 403)。 它同时支持 Anthropic (`/v1/messages`) 和 OpenAI (`/chat/completions`, `/v1/responses`) 的请求格式。 ## 为什么是内置的而不是 `.so` 插件 官方的 `maximhq/bifrost` 镜像是**静态链接**的,因此 Go 的共享对象(shared-object)插件 无法被加载 —— `plugin.Open` 会失败并提示 `"Dynamic loading not supported"`。可行的 方案是将 guardrail 作为内置插件**编译到二进制文件中**,并构建一个 自定义镜像。(`.so` 变体保留在 `legacy-so-plugin/` 下供参考;它仅在 你自行构建动态链接的 Bifrost 时才有效。) ## 目录说明 | 文件 | 用途 | |------|---------| | `guardrail.go` | 插件源代码 —— 一个 `schemas.HTTPTransportPlugin`(放入 `transports/bifrost-http/guardrail/`) | | `wiring.patch` | 两处用于在 Bifrost 的内置 registry 中注册该插件的小修改 | | `Makefile` | 获取标签,重新应用插件,进行 vet 检查,并构建自定义镜像 | `wiring.patch` 修改了以下文件: - `transports/bifrost-http/server/plugins.go` —— 导入 + 在 `loadBuiltinPlugin` 中添加一个 `case` + 在 `loadBuiltinPlugins` 中进行注册 - `transports/bifrost-http/lib/config.go` —— 导入 + 在 `builtinPluginNames` 中添加条目 ## 构建 ``` # 1. 将 upstream 克隆到此 repo 旁边(或将 FORK_DIR 指向现有的 clone) git clone https://github.com/maximhq/bifrost.git ./bifrost # 2. 为给定的 upstream tag 构建自定义 image make update TAG=transports/v1.6.0 \ FORK_DIR=./bifrost \ SERVER=dev@your-build-host \ IMAGE_REPO=your-org/bifrost ``` `make help` 会列出所有目标。`make smoke` 会启动一个临时容器,并验证 guardrail 是否已注册(`plugin status: guardrail - active`),是否拦截了匹配的请求(403), 以及是否放行了不匹配的请求。 ## 与上游保持同步 其足迹仅包含一个新文件和两处微小的接线修改,并保存为 `wiring.patch`。当 上游发布新版本时,`make update TAG=` 会重新应用所有内容。如果 上游插件 registry 改动较大导致 patch 无法应用,请手动重新接线这两个 文件,并运行 `make regen-patch` 来刷新 `wiring.patch` 和 `guardrail.go`。 ## CI:构建和自动部署 `.github/workflows/build-deploy.yml` 会在 GitHub runner 上构建镜像,将其推送到 GHCR (`ghcr.io//bifrost:`),并且可以通过 HTTP API 直接将其部署到 Nomad —— 无需 SSH。 - **仅构建**:通过 *Actions → build-and-deploy → Run workflow* 运行工作流,并设置 `deploy = false`,或者直接针对特定的上游标签依赖此流程。 - **构建 + 部署**:在运行时设置 `deploy = true`,或者推送一个 `v*` git 标签(即视为 发布)。部署作业会执行 `nomad job run -var "image=…" deploy/bifrost.nomad.hcl`。 所需的 repository secrets: | Secret | 值 | |--------|-------| | `NOMAD_ADDR` | Nomad API 的 base URL,例如 `https://nomad.example.com` | | `NOMAD_TOKEN` | 允许提交 `bifrost` 作业的 Nomad ACL token(请缩减其权限范围) | 镜像本身不携带任何密钥(provider 密钥 + `config.json` 存放在 Nomad 宿主机卷中)。 Nomad 节点仍然需要拉取它,因此请选择以下一种方式: - **Public package** —— 将 GHCR package 可见性设置为公开;节点无需认证即可拉取。 - **Private package** —— 保持其为私有,并让节点进行认证。`deploy/bifrost.nomad.hcl` 会从 Nomad Variable 中读取内容并填充给 Docker driver 的 `auth` 配置块:`ghcr_user`(GitHub 用户名)和 `ghcr_pass`(权限范围仅限 `read:packages` 的 PAT)。只需设置一次: nomad var put nomad/jobs/bifrost \ ghcr_user='' \ ghcr_pass='' \ kimi_api_key=… kimi_api_key_2=… bifrost_encryption_key=… `deploy/bifrost.nomad.hcl` 将镜像作为变量接收,并在 部署时从 Nomad Variables 中读取所有的 provider 密钥以及 GHCR 认证信息。 ## 启用插件 该插件是**可选开启 (opt-in)** 的。在你的 Bifrost `config.json` 中添加一个条目: ``` { "plugins": [ { "name": "guardrail", "enabled": true, "config": { "system_prompt": "You are a governed assistant...", "system_mode": "prepend", "block_patterns": ["(?i)some-forbidden-phrase"], "block_message": "Request blocked by guardrail policy." } } ] } ``` | 字段 | 含义 | |-------|---------| | `system_prompt` | 注入到每个请求的 system prompt 中的文本 | | `system_mode` | `prepend`(默认值 —— 我们的 prompt 置于调用者 prompt 之上)或 `override` | | `block_patterns` | Regex 列表;如果其中任何一个匹配到拼接后的用户输入,则拦截该请求 | | `block_message` | 在触发拦截并返回 HTTP 403 时返回的消息 | 如果没有 `plugins` 条目,自定义镜像的行为将与上游 Bifrost 完全一致。
标签:AI网关, DLL 劫持, EVTX分析, Go语言, 人工智能, 大语言模型, 护栏机制, 日志审计, 用户模式Hook绕过, 程序破解, 请求拦截