Szesnasty/ContextGuard
GitHub: Szesnasty/ContextGuard
面向 RAG 系统的上下文防火墙,在检索与生成之间执行租户隔离、数据脱敏、访问控制和提示注入防御,并为每次决策生成可审计的证据记录。
Stars: 0 | Forks: 2
# ContextGuard
[](https://github.com/Szesnasty/ContextGuard/actions/workflows/ci.yml)
[](https://github.com/Szesnasty/ContextGuard/releases/latest)
[](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 问题,查看上下文防火墙总结发生了什么:在生成答案之前,有多少来源被允许、脱敏或拦截。
### 证据决策流

以证据记录的形式重放查询。该流程使不变式变得可见:检索到的 chunk 在组装 prompt 之前必须通过策略门。
### 上下文差异与强制决策

检查确切的上下文差异:被隐瞒的 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 数据流治理。
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, 大语言模型, 提示注入防御, 搜索引擎查询, 数据脱敏, 测试用例, 源代码安全, 自定义请求头, 访问控制, 请求拦截, 逆向工具