安全 SQL 护栏
只读优先、最小权限、超时、行数限制与写操作审批
数据库角色是第一道边界
CREATE ROLE agent_reader LOGIN;
GRANT CONNECT ON DATABASE commerce TO agent_reader;
GRANT USAGE ON SCHEMA app TO agent_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA app TO agent_reader;
ALTER DEFAULT PRIVILEGES FOR ROLE app_owner IN SCHEMA app
GRANT SELECT ON TABLES TO agent_reader;
ALTER ROLE agent_reader SET default_transaction_read_only = on;
ALTER ROLE agent_reader SET statement_timeout = '5s';
ALTER ROLE agent_reader SET lock_timeout = '1s';
ALTER ROLE agent_reader SET idle_in_transaction_session_timeout = '10s';凭据由 secret manager 或云身份集成配置,不要保存在迁移文件、prompt 或工具响应中。确认该角色不能 SET ROLE 到更高权限角色。
执行前策略
对模型生成的 SQL 做 parser/AST 级校验,不用正则代替解析器。默认规则:
- 只允许单条
SELECT。 - 拒绝
COPY ... PROGRAM、大对象、外部数据包装器和危险函数。 - 拒绝多个语句和注释绕过。
- 限制可访问 schema、表和列。
- 强制参数绑定;标识符只能从白名单选择。
- 对非聚合结果施加
LIMIT,同时在驱动层设置最大返回字节数。 - 执行
EXPLAIN (FORMAT JSON)做成本预检时,不能把成本估算当作时间保证。
每次读取使用只读事务
BEGIN READ ONLY;
SET LOCAL statement_timeout = '5s';
SET LOCAL lock_timeout = '1s';
SET LOCAL search_path = app, pg_catalog;
SELECT id, status, total_cents
FROM orders
WHERE customer_id = $1
ORDER BY placed_at DESC
LIMIT 100;
COMMIT;只读事务仍可能运行昂贵查询并泄露可读取的数据,所以权限、成本和结果限制缺一不可。
写操作不要开放任意 SQL
优先向 Agent 暴露领域工具:
{
"tool": "cancel_order",
"arguments": {
"order_id": 8842,
"expected_status": "pending",
"reason": "duplicate order",
"idempotency_key": "case-2026-184"
}
}应用服务验证身份与状态转换,在事务中执行参数化 SQL,并返回明确结果。批量写、DDL、GRANT、备份恢复和复制配置不应暴露给通用 Agent。
审计字段
至少记录:请求者/租户、工具名、模型与提示版本、契约版本、数据库目标、SQL 指纹(参数脱敏)、风险级别、审批者、行数、耗时、SQLSTATE、是否截断。不要把原始敏感结果复制进普通日志。
行数检查不能替代事务设计
先执行写入再发现“影响太多行”可能已经触发触发器或产生外部事件。应在受控事务里预览目标集,或通过领域 API 将可修改集合限制在查询本身。
Last updated on