填补现有授权体系空白,提供工具+参数级别的细粒度控制,默拒未知状态保障安全边界。
OPA 很通用,SPIFFE 回答的是"谁"的问题。但这两个都无法回答任何一个 Agent 部署最终都会面临的实际问题:"这个 Agent 是否有权在当前情况下调用这个工具并传入这些参数?"
agent-authz 正是为解决这一问题而生的一个小巧、可审计的 Python 策略引擎。它不是一个通用策略引擎——而这正是关键所在。
当前主流的 Agent 框架(LangChain、AutoGen、CrewAI、DeepSeek Harness、MCP server)对工具调用默认选择信任。一个被提示注入的 Agent——或者仅仅是一个过于积极的 Agent——可以用任意参数调用任意工具。
与此同时,现有的身份认证/授权工具箱中间存在一个空白:
agent-authz 填补了这个空白。四条设计原则支撑起了整个方案。
OPA 是二元决策。真实的 Agent 操作需要第三种状态——人工介入:
匹配顺序为 ask → allow → action → default deny(默认拒绝)。该决策可以干净地映射到现有的审批界面(DSH 的 ctx.approval、LangChain 人工工具、MCP 的审批流程):
from agent_authz import PolicyEngine, load_policy
engine = PolicyEngine(load_policy("policy.yaml"))
result = engine.evaluate(
agent_id="billing-agent",
tool="sql_query",
args_text="SELECT * FROM customers",
)
result.decision # Decision.ASK → route to human approval
基础层是声明式 YAML,带有 glob 参数范围匹配:
version: 1
default: deny
agents:
- id: "billing-agent"
spiffe_id: "spiffe://acme.com/agents/billing"
tools:
- name: "read_file"
allow: "src/**"
- name: "sql_query"
allow: "SELECT * FROM billing**"
ask: "SELECT **FROM customers**"
- name: "bash"
action: deny
但 glob 只能做字符串模式匹配。它无法表达"只能是 SELECT、只能查 billing 表、最多 100 行"。因此 agent-authz 在 glob 之上增加了结构化约束——语义收窄:
- name: "sql_query"
allow: "**"
constraints:
sql:
verbs: ["SELECT"] # only SELECT
tables: ["billing"] # only this table
max_rows: 100 # no LIMIT, or LIMIT > 100 → deny
- name: "http_request"
allow: "**"
constraints:
http:
methods: ["GET"]
hosts: ["api.acme.com", "*.internal"]
path_prefixes: ["/v1/"]
schemes: ["https"]
约束违规会强制 DENY,并将违规详情记录到 result.violations 以供审计。约束类型采用注册机制——SQL 和 HTTP 约束目前已内置,文件/其他收窄器可以轻松插入。
该引擎是纯 Python(stdlib + PyYAML)。支持三种部署方式:
进程内嵌入 — ToolCallGuard 包装执行过程,适用于 LangChain / AutoGen / CrewAI。适配器抛出 PermissionDeniedError(deny)或 NeedsApprovalError(ask),由宿主框架的错误处理路径原生处理。
HTTP Sidecar — 零依赖的 http.server 暴露 POST /authorize 端点,Node/TS 栈(DeepSeek Harness)通过 HTTP 桥接到同一个 Python 引擎。无需双重语言实现,避免了实现漂移。
MCP Gateway — 一个 stdio 透明代理,位于 MCP 客户端和 MCP 服务端之间,拦截每条 JSON-RPC 消息:tools/list 被过滤(Agent 根本看不到无权使用的工具)、tools/call 需要授权、其他消息直接透传。
Agent Framework (LangChain / AutoGen / CrewAI / DSH / MCP)
│ tool call (agent_id, tool, args)
▼
┌──────────────────────────────────┐
│ agent-authz Engine │ ← YAML policy + glob + constraints
│ allow / deny / ask │
└──────────────────────────────────┘
│ decision + OCSF audit event
▼
SIEM (Splunk ES, etc.)
SPIFFE 身份:策略以 spiffe_id 为关键字。除了字符串解析外,还提供了一个 Issuer,可为每个 Agent 颁发稳定的、符合规范要求的 SPIFFE ID,并将其绑定到策略中——这就是 Okta 正在推进的"AI 身份治理"模式,机器身份成为一等公民。同时提供了一个 SPIRE 客户端(spire_client.py),可从 Workload API 获取实时的 X.509-SVID,并且交换器可插拔,保持零硬依赖:
from agent_authz import SpiffeIssuer, load_policy, bind_to_policy
policy = load_policy("policy.yaml")
issuer = SpiffeIssuer("acme.com")
ident = issuer.issue("billing-agent") # spiffe://acme.com/agent/billing-agent
bind_to_policy(ident, policy) # identity → permission binding
OCSF 审计:每次决策都会发出一个 OCSF 兼容事件(category_uid=3,activity_id 1=Allow / 2=Deny / 3=Pending),可直接流式接入 SIEM。在 OCSF 之上还有一个 NOOA 命名空间适配器——因为截至本文撰写时,NVIDIA 的 NOOA 框架尚未发布最终的审计 schema,所以映射被隔离在 to_nooa() 之后,当标准落地时核心引擎无需改动。
agent-authz 信任 SPIRE 验证的身份,从不伪造 SVID。
如果你需要对任意数据写任意 Rego 规则,请用 OPA。
它只是一层决策层;真正的执行隔离属于运行时。
Agent 安全中最尖锐的问题不是"一个 Agent 能做什么",而是"它在每一次调用中实际被允许做什么——并留下审计轨迹"。agent-authz 就是这一层:94 个测试用例、零重量级依赖、三种部署形态、内置身份与审计。
Apache-2.0 开源。试用方式:pip install -e .,然后 python -m agent_authz.cli validate -p examples/policy.yaml。