Szesnasty/ContextGuard

GitHub: Szesnasty/ContextGuard

面向 RAG 系统的上下文防火墙,在检索与生成之间执行租户隔离、数据脱敏、访问控制和提示注入防御,并为每次决策生成可审计的证据记录。

Stars: 0 | Forks: 2

# ContextGuard [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/b763fc5c63220052.svg)](https://github.com/Szesnasty/ContextGuard/actions/workflows/ci.yml) [![Release](https://img.shields.io/github/v/release/Szesnasty/ContextGuard?label=release&sort=semver&cacheSeconds=3600)](https://github.com/Szesnasty/ContextGuard/releases/latest) [![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE) **一个用于 RAG 系统的上下文防火墙。** ContextGuard 位于检索和生成之间。它决定哪些 chunk 可以到达模型,哪些必须被脱敏,哪些必须被拦截,以及为什么。每一个决定都会成为你可以检查、重放和测试的证据。 它是库优先的:核心防护可以脱离 Docker、数据库、模型或网络访问运行。 大多数 RAG 系统会问: ContextGuard 会问: 在以下情况使用它: - 你的 RAG 系统使用私有、内部或多租户数据, - 你需要针对每个 chunk 的 `allow`、`redact` 和 `block` 决定, - 你需要关于为什么上下文能够到达模型的证据。 ## 为什么需要它 生产环境中的 RAG 不再仅仅是一个相关性问题。内部助手现在会检索合同、工单、HR 文件、路线图笔记、客户数据、源代码和特定于租户的知识。检索层通常针对语义匹配进行优化,而访问控制、最小化和审计性则存在于其他地方。 这就产生了一种明显的失败模式:向量数据库可以为问题检索到正确的 chunk,但对用户来说却是错误的 chunk。 ContextGuard 就是该边界的控制平面: - **租户隔离** - `acme` 用户绝不应该接收到 `contoso` 的上下文。 - **角色和分类策略** - 销售人员可以使用公开/内部文档,但不能使用机密的并购(M&A)笔记。 - **数据最小化** - PII 和密钥可以在组装 prompt 之前进行掩码处理。 - **间接注入防御** - 被投毒的文档被视为风险信号,而不是受信任的指令。 - **证据胜于承诺** - 每次查询都会记录检索到了什么、允许了什么、脱敏了什么、拦截了什么,以及触发了哪条策略。 ContextGuard 并不想成为一个更好的检索器或更智能的模型。它是围绕上下文窗口构建的一个小型、明确的执行层。 ## 使用模式 ContextGuard 围绕两种使用模式设计: 1. **核心库** - 一个零基础设施的 Python 防护层,它接收 `UserContext`、查询和候选 chunk,然后返回允许、脱敏和拦截的 chunk 以及证据记录。这是主要的产品面。公开包发布计划在包命名和分发阶段完成后进行。 2. **本地演示堆栈** - 一个包含 FastAPI、pgvector、Ollama 和 Vue 仪表板的参考 RAG 系统,用于端到端地演示具备策略感知的检索、证据和泄露预防。 ## 最新发布 最新的稳定源码版本是 [`v1.0.0`](https://github.com/Szesnasty/ContextGuard/releases/tag/v1.0.0)。 默认分支跟踪当前的开发进度;带版本号的标签是稳定的快照。 在 Python 包发布到公共包索引之前,请从 GitHub 发布页面安装 1.0.0 的 wheel 包: ``` uv venv uv pip install \ https://github.com/Szesnasty/ContextGuard/releases/download/v1.0.0/contextguard_contracts-1.0.0-py3-none-any.whl \ https://github.com/Szesnasty/ContextGuard/releases/download/v1.0.0/contextguard_policy_dsl-1.0.0-py3-none-any.whl \ https://github.com/Szesnasty/ContextGuard/releases/download/v1.0.0/contextguard-1.0.0-py3-none-any.whl ``` 如需完整的本地演示,请克隆此仓库并使用 `make demo`。 ## 项目文档 - [更新日志](CHANGELOG.md) - 发布历史和重要变更。 - [安全策略](SECURITY.md) - 漏洞范围和报告指南。 - [贡献指南](CONTRIBUTING.md) - 开发规则和本地工作流。 - [路线图](ROADMAP.md) - 计划中的评估、集成和生产强化工作。 - [基准测试报告](BENCHMARK.md) - 确定性的泄露预防检查。 - [红队报告](RED-TEAM.md) - 对抗性 prompt 和检索案例。 ## 产品导览 仪表板清晰地展示了安全边界:检索可以找到一个 chunk,但策略决定该 chunk 是否可以针对此身份到达模型。 ### RAG 控制台 ![RAG 控制台显示了支持身份、跨租户 prompt 以及允许/脱敏/拦截的来源数量。](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/9c5557a576220058.png) 提出一个普通的 RAG 问题,查看上下文防火墙总结发生了什么:在生成答案之前,有多少来源被允许、脱敏或拦截。 ### 证据决策流 ![证据查看器显示检索到的 chunk 通过策略门,进入允许、脱敏、拦截和 prompt 结果。](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/0d957d6fbc220103.png) 以证据记录的形式重放查询。该流程使不变式变得可见:检索到的 chunk 在组装 prompt 之前必须通过策略门。 ### 上下文差异与强制决策 ![证据查看器显示对模型隐瞒的上下文,以及每个被拦截或脱敏的 chunk 背后的策略决策。](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/5df932c8c0220108.png) 检查确切的上下文差异:被隐瞒的 chunk 会单独显示,脱敏的 PII 会被掩码处理,并且每个强制执行的决策都可以追溯到某条策略规则。 ## 核心库快速入门 核心被设计为作为 Python 库运行。它在此仓库内运行时无需 Docker、数据库、模型或网络访问。在完成包命名和分发阶段后,计划进行公共包发布。 ``` from contextguard import ContextGuard from contextguard.core.types import Chunk, Classification, UserContext guard = ContextGuard.from_policy("data/policies/example.yaml") user = UserContext( sub="sales@acme", tenant="acme", role="sales", purpose="support", ) chunks = [ Chunk( id="public-faq", doc_id="faq", tenant="acme", classification=Classification.PUBLIC, text="Refund requests are handled by support.", ), Chunk( id="secret-mna", doc_id="mna-falcon", tenant="acme", classification=Classification.CONFIDENTIAL, text="Project Falcon acquisition target is Initech for 1.2B.", ), ] result = guard.guard(user, "Are we acquiring anyone?", chunks) print([chunk.id for chunk in result.allowed_chunks]) print(guard.last_evidence()) ``` ## 演示快速入门 前置条件: - Docker Desktop - Python 3.12 - Node 20+ - `uv` - `pnpm` 可选的本地配置: ``` cp .env.example .env ``` 如果默认端口空闲,你可以跳过此步骤。如果存在 `.env` 文件,`make demo` 会自动读取它。 运行本地演示: ``` make demo ``` 该命令会启动本地堆栈,准备数据库,为植入的租户语料库注入种子数据,启动 FastAPI 后端,并启动 Vue 仪表板。 打开仪表板: ``` http://localhost:5173 ``` 在仪表板中: 1. 为 `sales@acme` 生成一个开发 token。 2. 提问: ``` Are we acquiring any company soon, and for how much? ``` 3. 打开来源/证据抽屉。 4. 寻找机密的收购 chunk:它可能会被检索到,但它会被保留而不发送给模型,并归因于拦截它的策略规则。 针对运行中的 API 运行快速演示冒烟测试: ``` make e2e ``` 如果本地端口与另一个堆栈冲突,请覆盖它们: ``` POSTGRES_PORT=55432 \ DATABASE_URL=postgresql://contextguard:contextguard@localhost:55432/contextguard \ REDIS_PORT=6380 \ REDIS_URL=redis://localhost:6380/0 \ LANGFUSE_PORT=3002 \ OLLAMA_PORT=11435 \ OLLAMA_BASE_URL=http://127.0.0.1:11435 \ API_PORT=8008 \ WEB_PORT=5174 \ make demo ``` 然后运行: ``` API_BASE=http://127.0.0.1:8008 make e2e ``` ## 演示展示了什么 植入的演示语料库包含普通的产品/支持文档以及故意的泄露面: - 一份机密的 `acme` 并购(M&A)备忘录, - 一个跨租户的 `contoso` chunk, - 包含 PII 的支持文本, - 一个包含密钥的运行手册 chunk, - 一个间接 prompt 注入文档。 对于 `sales@acme` 身份,ContextGuard 演示了: - 检索来源, - 针对每个 chunk 的 `allowed`、`redacted` 和 `blocked` 决策, - 防火墙开启前后的 token 减少, - 策略原因,例如 `tenant-isolation` 和 `sales-no-confidential`, - 一份查询级别的证据记录。 重要的安全不变式: **被拦截的 chunk 文本不会到达模型,也不会作为原始检索文本被 `/v1/query` 返回。** ## 工作原理 ``` flowchart LR U["User query + signed identity"] --> A["FastAPI adapter"] A --> R["Hybrid retriever
pgvector kNN + BM25"] R --> C["Candidate chunks"] C --> E1 E3 --> P["Allowed + redacted chunks"] P --> PB["Prompt builder
cited context only"] PB --> L["LLM gateway
Ollama by default"] L --> O["Grounded answer"] E3 --> E["Evidence record"] subgraph Guard["Context firewall"] E1["Enrich
PII, secrets, injection signals"] E2["Policy
tenant, role, classification"] E3["Redact / block / allow"] E1 --> E2 --> E3 end ``` ### 决策流水线 ``` flowchart TD Q["Query"] --> K["Top-k retrieval"] K --> C1["Chunk: public/internal"] K --> C2["Chunk: confidential"] K --> C3["Chunk: cross-tenant"] K --> C4["Chunk: PII or secret"] K --> C5["Chunk: injection risk"] C1 --> A["Allowed"] C2 --> B["Blocked
sales-no-confidential"] C3 --> T["Blocked
tenant-isolation"] C4 --> D["Redacted
redact-pii / redact-secrets"] C5 --> I["Blocked
block-injection"] A --> P["Prompt context"] D --> P B --> X["Withheld from model"] T --> X I --> X P --> M["Model answer"] A --> EV["Evidence"] B --> EV T --> EV D --> EV I --> EV ``` ### 仓库架构 ``` flowchart TB Web["apps/web
Vue dashboard"] --> API["contextguard.api
FastAPI adapter"] API --> Query["/v1/query
retrieve -> guard -> prompt -> LLM"] API --> Scan["/v1/guard
scan-only verdict"] Query --> Retrieval["retrieval
pgvector kNN + BM25"] Query --> Core["contextguard.core
zero-infra guard"] Query --> Prompt["prompt builder
allowed chunks only"] Prompt --> LLM["llm gateway
Ollama by default"] Scan --> Core API --> Metrics["/metrics
Prometheus format"] Core --> Contracts["packages/contracts
Pydantic models + JSON Schema"] Core --> Policy["packages/policy-dsl
YAML policy evaluator"] Core --> Evidence["EvidenceSink protocol
in-memory / JSONL default"] API --> PgEvidence["optional Postgres JSONB evidence
EVIDENCE_SINK=postgres"] PgEvidence --> Evidence Eval["packages/eval-harness
benchmarks + red-team corpus"] --> Core Data["data/
tenants, users, policies, attacks"] --> Retrieval Data --> Eval Compose["compose.yaml
Postgres, Redis, Ollama, Langfuse"] --> API ``` ## 策略示例 策略是声明式 YAML。规则按优先级评估。第一个匹配的规则生效;如果没有规则匹配,则应用 `default_effect`。 演示策略默认是宽松的,以便于比较植入的示例: ``` version: 1 default_effect: allow roles: manager: inherits: [sales] rules: - id: tenant-isolation effect: deny priority: 100 when: - { field: chunk.tenant, op: neq, ref: user.tenant } - id: sales-no-confidential effect: deny priority: 50 when: - { field: user.roles, op: contains, value: sales } - { field: chunk.classification, op: gte, value: confidential } - id: redact-pii effect: redact priority: 30 when: - { field: chunk.pii_count, op: gte, value: 1 } ``` 对于生产级别的安全态势,从默认拒绝开始,并在更严格的拒绝/脱敏规则之后添加明确的允许规则: ``` version: 1 default_effect: deny rules: - id: tenant-isolation effect: deny priority: 100 when: - { field: chunk.tenant, op: neq, ref: user.tenant } - id: allow-safe-context effect: allow priority: 10 when: - { field: chunk.tenant, op: eq, ref: user.tenant } ``` 请参见 [`data/policies/example.yaml`](data/policies/example.yaml) 和 [`data/policies/strict.yaml`](data/policies/strict.yaml)。 ## 验证点 当前的基准测试和红队报告都是确定性的。它们不使用 LLM 评判器。 | 产物 | 结果 | |---|---| | `make test` | 336 个 Python 测试 + 18 个前端测试通过 | | `make lint` | Python 和前端 lint 检查通过 | | `make types` | mypy + Vue 类型检查通过 | | `make benchmark` | 在植入的演示语料库上:策略关闭时 100% 泄露率,策略开启时 0% 泄露率 | | `make red-team` | 在提交的对抗性语料库上:6/6 个案例通过,0% 泄露率,0 次重放不匹配 | | `make e2e` | 快速本地演示冒烟测试 | 请参见: - [BENCHMARK.md](BENCHMARK.md) - [RED-TEAM.md](RED-TEAM.md) ## 独特之处 ContextGuard 不是通用的 LLM 防火墙。它专注于上下文边界: | 类别 | 典型关注点 | ContextGuard 关注点 | |---|---|---| | LLM 防火墙 | prompt/输出内容过滤 | 生成前允许哪些上下文 | | RAG 检索工具 | 相关性和排名 | 具备策略感知的检索与最小化 | | 可观测性工具 | 链路追踪、成本、评估 | 将证据作为可审计的产品契约 | | 数据治理工具 | 静态数据 | RAG 查询热路径 | 产品理念特意保持狭窄: **此上下文是否被允许出现在这里,并且我们能证明它吗?** ## ContextGuard 不是什么 ContextGuard 不是: - 你的检索器的替代品, - 身份或 ACL 映射的替代品, - 安全源系统权限的替代品, - 通用的 LLM 防火墙, - 合规认证, - 保证绝对不会发生数据泄露的承诺。 ## 项目布局 ``` . ├── apps/ │ └── web/ # Vue dashboard + frontend README ├── packages/ │ ├── contextguard/ # Python core, API adapter, retrieval, evidence │ ├── contracts/ # Pydantic contracts + JSON Schemas + OpenAPI │ ├── policy-dsl/ # YAML policy schema and evaluator │ └── eval-harness/ # benchmarks and red-team runner ├── data/ │ ├── tenants/ # planted demo corpus │ ├── policies/ # demo + strict policies │ └── red-team-corpora/ # golden adversarial cases ├── docs/ │ └── img/ # README screenshots ├── compose.yaml # local stack ├── CHANGELOG.md # release notes ├── CONTRIBUTING.md # contribution guide ├── ROADMAP.md # next milestones ├── SECURITY.md # vulnerability reporting scope ├── Makefile # canonical dev/demo commands └── README.md ``` ## 状态 ContextGuard 1.0.0 是第一个正式的 MVP 版本,采用开源方式构建。它已准备好在本地演示产品理念: - 具备策略感知的上下文过滤, - 脱敏与拦截, - 证据记录, - 红队与基准测试产物, - 一个用于审查查询、来源、策略和证据的仪表板。 它不是合规认证、法律意见或生产部署模板。真正的生产环境使用仍然需要强化的身份验证、连接器级别的 ACL 映射、保留策略、部署强化以及更全面的安全审查。 ## 许可证 ContextGuard 采用 Apache License 2.0 授权。请参见 [LICENSE](LICENSE)。 ## 法律声明 ContextGuard 不构成法律建议,它本身也不能使系统符合 GDPR、欧盟 AI 法案(EU AI Act)、DORA 或任何其他法规的要求。它是一个工程控制和证据层,旨在支持更强大的 AI 数据流治理。
标签:AI安全, AI风险缓解, Chat Copilot, DLL 劫持, RAG, Streamlit, 大语言模型, 提示注入防御, 搜索引擎查询, 数据脱敏, 测试用例, 源代码安全, 自定义请求头, 访问控制, 请求拦截, 逆向工具