关于 Lomberk
Lomberk 是面向使用 AI Agent 团队的 PostgreSQL 网关,让 SQL 经过策略检查,而非向 Agent 提供数据库凭据。它会拦截破坏性语句、暂缓指定写入以待人工批准,并记录变更以便撤销,包括外键级联变更。
主要功能
- 01Agent 写入的 SQL 策略关卡
- 02拦截破坏性 SQL 命令
- 03暂缓高风险写入以待批准
- 04记录变更行并撤销写入
- 05查看检查点和 Agent 历史
适用场景
- 01让 Agent 更新 PostgreSQL 而不持有数据库凭据
- 02要求受保护表的写入先获批准
- 03批准前检查暂缓写入的影响
- 04撤销已执行写入及其级联变更
MCP 相关
Lomberk 向 MCP 客户端提供 SQL 执行、表结构说明、等待批准、检查点状态和变更列表等工具。它支持 Streamable HTTP 和本地 stdio 运行模式。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
uvx lomberkLOMBERK_CONFIGAbsolute path to the lomberk.yaml that `lomberk setup` wrote. The connection strings and keys are read from the .env beside it.LOMBERK_AGENT_DSN密钥Connection string for the low-privilege role the agent's SQL runs as. Only needed when the .env beside lomberk.yaml doesn't set it.LOMBERK_ADMIN_DSN密钥Connection string for the control role that owns the lomberk schema (checkpoints, undo, ledger). Only needed when the .env beside lomberk.yaml doesn't set it.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Lomberk
每次 Agent 写入,都可撤销。 Lomberk 是一个面向 PostgreSQL 的 MCP 网关。AI Agent 通过它发送 SQL,而不是持有数据库凭据。它会阻止破坏性命令,将大量或敏感写入暂存以供人工审核,记录每一行变更,并可撤销任何已执行的写入,包括外键级联操作。
只想给 Claude Code 装个安全带? Lomberk Seatbelt 是一个免费插件,可在执行 DROP、TRUNCATE、不带 WHERE 的 DELETE、prisma migrate reset、dropdb 等操作前要求 Agent 先询问。两条命令即可安装。
快速开始(60 秒)
你需要 uv 和 PostgreSQL 14+ 数据库所有者的连接字符串(一个可创建角色的角色:在 Supabase、Neon 和 RDS 上为 postgres)。
uvx lomberk setup # asks for the owner connection string; what you type stays out of your shell history
在脚本中,改为设置 LOMBERK_INSTALL_DSN 并添加 --yes。
安装程序会创建两个使用生成密码的最小权限角色、安装 Lomberk、列出你的表并将你选择的表设为可撤销,然后写入 lomberk.yaml 和私有 .env(模式为 600),并对它们运行 lomberk doctor。它不会更改任何已存在的角色或文件。所有者连接字符串只会使用一次,不会保存。最后,它会输出 MCP 客户端所需的配置行,例如:
claude mcp add lomberk -e LOMBERK_CONFIG=/path/to/lomberk.yaml -- uvx lomberk serve
Cursor、Claude Desktop、VS Code 和 Codex 也会获得相应的配置片段。然后让你的 Agent 修改一些内容:
lomberk log # what your agents changed, newest first
lomberk undo cp_… # put it back, cascades included
lomberk approve cp_… # let a held write run (or: lomberk reject cp_…)
lomberk doctor # check the setup any time
Supabase、Neon、RDS、Railway:请参阅 docs/hosted-postgres.md。在 Supabase 上,请使用会话池化器连接字符串(IPv4);安装程序会从中派生 lomberk_agent.<project-ref> 登录名。
Agent 可使用的工具
| 工具 | |
|---|---|
execute_sql | 通过硬性关卡、策略和捕获机制执行一条语句。响应包含检查点(cp_…)、APPROVAL REQUIRED,或拒绝原因 |
describe_tables | 列出它可使用的表、表的列(隐藏机密列),以及哪些写入需要人工审核 |
wait_for_approval | 等待人员批准或拒绝暂存的写入,同时报告进度,随后说明写入是否已执行 |
checkpoint_status | 查看其某次写入的状态:等待中、已执行、已拒绝或已撤销 |
list_my_changes | 列出它最近的写入及其令牌,以便告知你要撤销哪项写入 |
Agent 无法批准或撤销任何操作。此类操作需要管理员密钥、CLI,或(Pro 版)Slack、SSO 或控制面板。
9 秒删除数据库演示
2026 年 4 月,一个自主编码 Agent 在 9 秒内删除了生产数据库(通过权限过大的基础设施令牌)。Lomberk 关上了另一扇门:Agent 自身的数据库访问。以下展示了一个恶意 Agent 的 SQL 通过 Lomberk 时,它能做什么、不能做什么。

1. 启动服务栈
git clone https://github.com/ege-usta/lomberk && cd lomberk
docker compose up -d --build
curl localhost:8000/readyz # {"status":"ready"}
这会启动一个演示用的 pocketos 数据库(users ← payments,带有 ON DELETE CASCADE),使用两个最小权限角色安装 Lomberk,注册这两个表,并启动网关。
2. 连接 Agent(它只会获得一个 URL 和一个密钥,不会获得其他内容)
claude mcp add --transport http lomberk http://localhost:8000/mcp \
--header "Authorization: Bearer demo-agent-key"
任何支持 Streamable HTTP 的 MCP 客户端都可以用同样的方式工作。
3. Agent 开始失控
| Agent 发送 | Lomberk |
|---|---|
DROP TABLE public.users | 已拒绝:DDL 在结构上被禁止 |
DELETE FROM public.users | 已拒绝:写入语句缺少 WHERE |
DELETE FROM public.users WHERE id > 0 | 已暂缓:public.users 受保护 → 需要审批。令牌:cp_… |
UPDATE public.payments SET amount = 0 WHERE id > 0 | 已执行,并创建了检查点:未受保护的表中有 2 行。调用一次撤销即可恢复原来的金额 |
在受影响行数超过 max_rows_without_approval(演示中为 10 行)的情况下执行相同写入 | 已暂缓:语句已执行、已计数并已回滚,现在等待人工处理 |
4. 人工决定(管理员密钥,绝不提供给 Agent)
H="X-API-Key: demo-admin-key"
curl -H "$H" localhost:8000/v1/checkpoints/pending
curl -H "$H" "localhost:8000/v1/checkpoints?status=applied" # recent writes, to find the cp_ to undo
curl -H "$H" -X POST localhost:8000/v1/checkpoints/cp_…/approve # or /reject
curl -H "$H" -X POST localhost:8000/v1/checkpoints/cp_…/undo # users AND cascaded payments come back
待处理请求会在 agent.approval_timeout_minutes 后过期。请先通过 GET /v1/checkpoints/cp_… 或 lomberk show cp_… 查看确切的 SQL。
查看数据行,而不只是 SQL。 写入被暂缓时,Lomberk 会执行一次,记录变更并回滚,让审批者在决定前看到影响,包括级联变更:
$ lomberk show cp_… # the agent sent: DELETE FROM public.users WHERE id = 1
would change: 2 row(s) in public.users (1), public.payments (1) (dry run when held)
delete public.users {"id": "1"}: {"id": 1, "name": "Alice CEO", "plan": "enterprise", "email": "[email protected]", …}
delete public.payments {"id": "1"}: {"id": 1, "amount": 1000.0, "status": "success", "user_id": 1}
Web 面板和 API 中也会显示相同的预览;Slack 只会显示计数。敏感列会被遮蔽,Agent 角色不可见的列也不会显示。若暂缓的写入会失败(例如主键重复、缺少父级记录),系统会立即拒绝,而不是等待人工处理。预览是写入被暂缓时的快照。如果表自身的触发器会执行无法通过回滚撤销的操作,请设置 approvals.preview: false。
配置(lomberk.yaml)
limits:
max_rows_without_approval: 10 # larger writes are rolled back and held
statement_timeout_ms: 15000
protected_tables: # any write, or FK cascade, reaching these is held
- public.users
sensitive_columns: # like `password`: never shown to the agent, hidden by the DB on register
- pass
- settings # a JSON column that holds secrets
agent:
approval_timeout_minutes: 30
未知键会导致启动失败,因此拼写错误绝不会悄悄关闭保护。网关会读取 ./lomberk.yaml;如果从其他位置启动(MCP 客户端通常会从其他目录运行 lomberk serve),请将 LOMBERK_CONFIG 设为该文件的绝对路径。如果该文件不存在,启动会被拒绝;若缺少 ./lomberk.yaml,则只会打印警告,并使用默认配置运行(没有受保护的表)。
环境变量:LOMBERK_CONFIG(lomberk.yaml 的路径)、LOMBERK_ADMIN_DSN(控制角色)、LOMBERK_AGENT_DSN(Agent 角色)、LOMBERK_API_KEY(Agent)、LOMBERK_ADMIN_KEY(审批者)、LOMBERK_AUDIT_LOG(JSONL 路径)、LOMBERK_LICENSE_KEY(Pro)、LOMBERK_METRICS_KEY(启用 /metrics)。密钥必须包含至少 32 个随机字符(openssl rand -hex 32);除非设置 LOMBERK_ALLOW_WEAK_KEYS=true(仅用于笔记本电脑演示),否则网关会拒绝弱密钥或演示密钥。
在自己的数据库上安装
pip install lomberk # Slack and SSO: pip install "lomberk[pro]"; or: docker build -t lomberk .
export LOMBERK_INSTALL_DSN=postgresql://owner@db/app # used only for install
# first, as that owner: CREATE ROLE lomberk_control LOGIN PASSWORD '...'; CREATE ROLE lomberk_agent LOGIN PASSWORD '...';
lomberk init --control-role lomberk_control --agent-role lomberk_agent
lomberk register public.orders --agent-role lomberk_agent # repeat per table (and FK children)
lomberk verify-ledger # tamper-evidence check
了解 Agent 无法执行哪些操作,以及 20 种真实攻击的确切拒绝信息:docs/attack-gallery.md。
针对 Supabase、Neon、Amazon RDS 和 Railway 的分步指南(角色、连接字符串、RLS、updated_at 触发器):docs/hosted-postgres.md。
采用 Lomberk 前的常见问题:docs/faq.md。
无需服务的本地单用户开发:lomberk serve(stdio MCP)。请勿将此模式用于可访问 shell 的 Agent。请参阅 SECURITY.md。
团队功能(Solo 和 Pro)
Web 面板和审计导出包含在 Solo 和 Pro 中;Slack 审批、审批者 SSO 和双人规则则属于 Pro。
Slack 审批和审批者 SSO 需要额外的库:pip install "lomberk[pro]",或 uvx --from "lomberk[pro]" lomberk serve。Docker 镜像已包含这些库。若未安装,网关会拒绝启动并说明需要安装什么。
在 Slack 中审批(Pro)
根据 slack/app-manifest.json 创建应用(仅需 chat:write bot 权限范围,并启用 Socket Mode,因此无需公共 URL),将 bot 邀请到审批频道,然后:
slack:
channel_id: C0123APPROVALS
team_allowlist: [T0123]
admin_allowlist: [U0ALICE, U0BOB] # only these users' clicks count
include_sql: false # default: SQL never leaves for Slack
LOMBERK_SLACK_ENABLED=true LOMBERK_SLACK_APP_TOKEN=xapp-… LOMBERK_SLACK_BOT_TOKEN=xoxb-…
每个被暂缓的请求都会以带有「批准/拒绝」按钮的消息发布,消息会更新为最终状态。审批者的 Slack ID 会写入审计日志。
审批者 SSO(Pro)
审批者使用公司的身份提供商(Okta、Microsoft Entra ID、Google、Keycloak 或任何 OIDC 颁发者)登录,并发送其 ID token。这样,审计日志记录的就是具体人员(oidc:[email protected]),而不是共享密钥。
sso:
issuer: https://corp.okta.com # keys are discovered from the issuer
audience: lomberk-approvals # the client ID registered for Lomberk
allowed_groups: [db-approvers] # and/or allowed_identities: [[email protected]]
# allow_admin_key: true # the shared key is OFF once SSO is on; CLI stays as break-glass
curl -H "Authorization: Bearer $ID_TOKEN" -X POST localhost:8000/v1/checkpoints/cp_…/approve
仅接受由非对称算法(RS/PS/ES)签名、适用于此颁发者和受众的 token,且 token 必须未过期。使用默认的 identity_claim: email 时,token 必须标记该电子邮件已验证。Entra ID 不会发送此标记,因此在使用 Entra ID 时,请将 identity_claim 设为 upn 或 oid。
网页审批面板(Pro)
打开 https://<gateway>/panel/,即可查看等待审批的写入操作、显示每项操作审批者的历史记录、一键撤销以及导出内容。审批者可通过 SSO 或管理员密钥登录。要提供“使用 SSO 登录”选项,请在 IdP 中将 <panel_url>/panel/sso/callback 注册为重定向 URI:
sso:
# ...the SSO settings above, with audience = the panel's client ID
panel_url: https://lomberk.corp.com # public https URL of this gateway
如果 IdP 要求该客户端提供客户端密钥,请设置 LOMBERK_SSO_CLIENT_SECRET。
双人规则(Pro)
approvals:
required: 2 # a held write runs only after two different people approve it
只有经过验证的身份才计入人数:N 人必须全部通过 SSO(面板或 API)审批,或全部通过 Slack 审批。混用系统不计入,因为同一个人可能同时拥有两种身份。管理员密钥和 CLI 审批会被记录,但不计入,因为它们无法证明身份。任何一人拒绝都会取消写入操作。每项审批都会存储在仅追加的 lomberk.approvals 表中。
审计导出(Pro)
curl -H "X-API-Key: $ADMIN_KEY" "localhost:8000/v1/audit/export?format=csv&since=2026-01-01" > audit.csv # or format=jsonl
每个检查点都包含其 SQL、Agent、状态、行数、审批者以及账本哈希。面板也提供相同的导出功能,可通过按钮操作。
许可证密钥
网页面板和审计导出需要设置 LOMBERK_LICENSE_KEY,并使用 Solo 或 Pro 密钥;Slack 审批、SSO 和双人规则需要 Pro。配置了 Pro 功能却使用 Solo 密钥时,程序会拒绝启动,并说明哪些功能需要 Pro。密钥还决定撤销操作可追溯的时间范围:不使用密钥时为 24 小时,使用 Solo 或 Pro 时为 30 天,使用 Enterprise 时则没有限制。时间从写入操作执行时开始计算(对于暂缓的写入操作,则从最后一次审批时开始计算)。超出时间范围的检查点会返回 expired(HTTP 403),并保持原样。
在定价页面购买密钥:购买后会立即通过电子邮件发送,并随订阅续订。网关会在启动时通过 Polar(api.polar.sh)检查密钥一次。此调用会发送密钥;如果是 Pro 密钥,还会发送此数据库的随机标识(lomberk.license_activation),因此一个 Pro 密钥最多可用于 3 个数据库。可在 Polar 的客户门户中释放名额。仅当检查点时间超过 24 小时时,lomberk undo 才会向 Polar 发起请求。如果 Polar 无法访问(无响应,或重试三次后仍收到 5xx 或 429 回复),Pro 功能会保持启用;如果 Polar 完全没有响应,启动过程最多可能耗时约一分钟。数据库的首次激活不会重复发送:超时或收到 5xx 后不会重试(Polar 可能已经占用了名额),下次启动时会再次尝试。任何其他非有效授权回复都会被视为无效密钥。如果密钥无效、已取消,或已在 3 个数据库上使用,网关会拒绝启动已配置的 Pro 功能,并说明原因。密钥会在启动时检查,因此取消订阅后,Pro 功能会在下次重启时关闭。
工作原理
- AST 硬性门禁:PostgreSQL 自带的解析器(
pglast)允许一条SELECT/INSERT/UPDATE/DELETE(或普通的EXPLAIN)、带WHERE的模式限定写入,以及约 190 个纯内置函数:窗口函数、JSON、全文搜索、gen_random_uuid(),以及 Agent 日常编写的其他内容。 - 策略:受保护的表、外键级联范围,以及通过在事务内执行并回滚来强制实施的行数限制。
- 捕获:
SECURITY DEFINER行触发器会记录每项变更(包括级联变更),并绑定到一次性能力令牌。 - 撤销:按符合外键约束的顺序执行(先恢复父级,再恢复子级),并检查冲突和模式漂移。旧行以 Postgres 自带的文本形式保存,因此所有类型(包括 JSON
null和键顺序)都会原样恢复。若之后有其他写入,它会拒绝操作,而不是触碰这些行。 - 有界读取:读取以只读方式在
statement_timeout下运行,通过服务器端游标流式传输,最多返回 100 行(每个值 4,000 个字符,总计 100,000 个字符),并告知 Agent 是否还有更多结果。 - 账本:仅追加记录、由 SHA-256 哈希链连接的检查点。
监控
/healthz(进程正常运行)和 /readyz(两个数据库角色均可访问)无需密钥。设置 LOMBERK_METRICS_KEY 即可为 Prometheus 启用 /metrics:按事件统计决策数(denied、held、applied、undone 等)、等待处理的暂缓写入数量,以及最早一项暂缓写入的等待时长,方便在审批积压时触发告警。它只包含计数,绝不包含 SQL、行或名称。
scrape_configs:
- job_name: lomberk
authorization: { credentials: "<LOMBERK_METRICS_KEY>" }
static_configs: [{ targets: ["lomberk:8000"] }]
**当前限制:**每个已注册的表都必须有主键(单列或多列;lomberk register 会从表中读取主键)。支持分区表:注册分区表及其所有分区后,包括之后新增的分区,都会受到保护;移至其他分区的行也会恢复到原来的位置。带有规则或传统继承的表不允许写入,带有自身触发器的分区表也不允许写入。带有自身触发器的表,其写入需要等待人工处理;除非使用 --allow-triggers 注册该表(适用于只更改行本身的 updated_at 等触发器,或 Lomberk 也会保护的表)。撤销时会关闭这些触发器再恢复行,因此行会原样恢复。JSON 键必须写成字面量(->>'theme');对 JSON 内部内容的脱敏尽力而为,因此请在 sensitive_columns 中列出可能包含机密信息的 JSON 列。DDL 会被阻止,且不可撤销。完整列表请见 SECURITY.md。
开销
在本机对比 Postgres 16 测得(运行 200 次,p50 / p95):
| 路径 | 延迟 |
|---|---|
| 硬性门禁 + 策略(无 DB) | 0.1 / 0.1 ms |
| 通过 Lomberk 读取 | 5.4 / 6.2 ms |
| 通过 Lomberk 捕获、可撤销的写入 | 18.3 / 23.9 ms |
| 新连接上的普通写入(基准) | 4.8 / 6.0 ms |
Agent 的每轮交互需要数秒,因此实际使用中的开销可以忽略不计。大部分开销来自建立新连接;远程/TLS 数据库的连接池已列入路线图。
已在 PostgreSQL 14、15、16、17 和 18 上测试,CI 中的完整测试套件会在每个版本上运行。
定价
| 免费版 | Solo | Pro | Enterprise | |
|---|---|---|---|---|
| 适用对象 | 尝试使用、个人项目 | 一位开发者 | 一个团队 | 多个数据库 |
| 价格 | $0 | $49/月(即将开放结账) | $199/月 或 $1,990/年 | 联系我们 |
硬性拦截、暂挂、捕获、账本、远程 MCP、API/CLI 审批、lomberk log | ✓ | ✓ | ✓ | ✓ |
| 可撤销的追溯时限 | 24 小时 | 30 天 | 30 天 | 不限 |
| Web 面板、审计导出 | ✓ | ✓ | ✓ | |
| Slack 审批、审批者 SSO、双人规则 | ✓ | ✓ | ||
| 每个许可证密钥可用的数据库数 | 1 | 最多 3 个 | 不限 | |
| 付款方式 | 银行卡、自助服务 | 银行卡、自助服务 | 年度发票 | |
| 帮助 | GitHub issues | GitHub issues | GitHub issues | 优先答复;协助填写安全问卷 |
购买 Pro:密钥会立即通过电子邮件发送。对于 Enterprise,请发起一条讨论,说明你拥有的数据库和审批者数量,我们会回复报价。付款、发票和销售税由登记商家 Polar 负责处理。
Lomberk 可自托管,你的数据绝不会传到我们这里。我们不提供电话支持或值班服务;文档和 lomberk doctor 的设计让你能够独自完成设置。
开发
uv sync --all-groups
PYTHONPATH=src uv run pytest tests/ # needs Docker (testcontainers)
变更记录:CHANGELOG.md。贡献指南:CONTRIBUTING.md。
许可证
开放核心。src/lomberk/ee/ 以外的所有内容均采用 Apache-2.0 许可证:硬性拦截、策略、捕获、撤销、账本、远程 MCP 和 API/CLI 审批。你可以免费运行完整的安全流程。
src/lomberk/ee/(Slack 审批、审批者 SSO、Web 面板、审计导出和许可证检查)以Elastic License 2.0(ELv2)提供源代码;Elasticsearch 使用的也是同一许可证。你可以阅读、运行和修改它。使用这些功能需要 Solo、Pro 或 Enterprise 密钥;ELv2 禁止移除或绕过密钥检查,也禁止将软件作为托管服务提供。双人规则属于核心代码,但启用它需要密钥。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。