Citadel + AGT 集成架构:Foundry Citadel 四层治理与 Agent Governance Toolkit 的边界协作实战指南
【免费下载链接】agent-governance-toolkitAI Agent Governance Toolkit — Policy enforcement, zero-trust identity, execution sandboxing, and reliability engineering for autonomous AI agents. Covers 10/10 OWASP Agentic Top 10.项目地址: https://gitcode.com/GitHub_Trending/ag/agent-governance-toolkit
本文是 Agent Governance Toolkit(AGT)与微软 Foundry Citadel 平台集成架构的技术指南。Citadel 提供面向基础设施边界(网关、身份、安全、可观测性)的 AI 治理分层架构,而 AGT 负责代理运行时内逐动作、逐消息的细粒度策略执行;两者互补而非竞争。读完本文,你将掌握两者在四层架构中的职责切分、Policy Bundle 与 Access Contract 的绑定机制、治理事件导出到 Azure Event Hub / Application Insights 的完整数据流,以及 APIM 网关侧治理元数据的透传与关联实现,并可直接运行仓库中的端到端示例验证整套流程。
定位:两种互补的强制边界
Citadel 与 AGT 治理的是不同的强制边界,两者是互补关系而非竞争关系。Citadel 站在"基础设施外沿"(gateway perimeter),AGT 站在"代理运行时内部"(agent runtime)。二者对同一代理动作的治理粒度、身份模型、审计目标各不相同:
| 关注点 | Citadel(网关) | AGT(代理运行时) |
|---|---|---|
| 治理对象 | 基础设施边界处的模型/工具/代理访问 | 单个代理动作、工具调用、代理间消息 |
| 强制点 | APIM 网关(集中式) | 代理运行时 sidecar / 库(本地) |
| 延迟模型 | 经过网关的一次网络跳转 | 进程内亚毫秒级评估 |
| 策略粒度 | 粗粒度:限流、内容过滤、配额、JWT 校验 | 细粒度:逐动作 allow/deny、能力模型、调用方限制 |
| 身份模型 | Entra ID / 订阅密钥 | Ed25519 / SPIFFE 密码学身份 |
| 审计目标 | Event Hub / App Insights / Log Analytics | 哈希链审计日志(可导出至 Azure Monitor) |
这一分工的核心判断依据是:网关无法理解代理的意图与内部状态,而运行时无法替代网关的容量与合规边界。因此合理的设计是让两者各守边界、通过协议与元数据协作,这正是本文后续各节展开的内容。
AGT 如何映射到 Citadel 的四层
AGT 并不局限于 Citadel 的某一层,而是横跨整个架构,在每一层都有对应的协作点:
┌─────────────────────────────────────────────────────────────────┐ │ Foundry Citadel Platform │ │ │ │ Layer 4: Security Fabric (Defender, Purview, Entra) │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ AGT trust scores surface as risk labels in Defender │ │ │ │ AGT data_classification aligns with Purview labels │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ Layer 3: Agent Identity (Agent 365 / Entra) │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ AGT agent identities federate with Entra agent IDs │ │ │ │ Entra = enterprise identity, AGT = runtime credentials │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ Layer 2: AI Control Plane (Foundry Control Plane) │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ AGT exports governance evidence and traces │ │ │ │ Policy decisions enrich Foundry/OTEL traces │ │ │ │ Fleet-wide compliance visibility via Azure Monitor │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ Layer 1: Governance Hub (APIM Gateway) │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ Access Contracts reference AGT policy bundles │ │ │ │ AGT metadata headers pass through APIM for correlation │ │ │ │ Gateway = coarse rules, AGT = action-level rules │ │ │ └─────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘Layer 1:Governance Hub(APIM 网关)
Citadel 的 APIM 网关强制基础设施级控制:代理可以访问哪些模型、以什么速率、经过哪些内容安全过滤器。AGT 通过Access Contract 策略包绑定(Access Contract policy bundle binding)接入:当 Citadel Access Contract 部署代理环境时,它引用一个 AGT 策略包的 ID/版本;代理运行时在启动时加载该策略包(由 PolicyBundleResolver 负责解析,详见下文"Policy Bundle Binding"一节)。
策略优先级:网关规则(限流、内容过滤器、JWT)首先在 APIM 层强制;AGT 的动作级策略其次在代理运行时内强制。两层都必须通过,动作才能继续执行。
Layer 2:AI Control Plane(Foundry 控制平面)
AGT 在 Layer 2 的核心贡献是治理证据与追踪增强。CitadelAuditExporter 将策略决策、信任分变化、动作拦截事件发送到 Azure Event Hub 和 Application Insights。这些事件携带关联 ID(correlation ID),把 AGT 决策与 APIM 请求追踪、Foundry 执行追踪串联起来,从而支撑统一的可观测性仪表盘。从源码看,导出器通过CorrelationContext数据结构携带apim_request_id、foundry_trace_id、agt_decision_id、session_id四类 ID(见 citadel_exporter.py),App Insights 侧则以agt.*/citadel.*前缀的 span attributes 写入,确保跨系统关联。
Layer 3:Agent Identity(代理身份)
Entra ID / Agent 365 仍是企业级代理身份与生命周期管理的权威来源;AGT 的 Ed25519/SPIFFE 身份仍是运行时密码学凭据的权威来源。集成方式是联邦(federation),而非替换(replacement):AGT 信任分(0-1000)作为遥测中的风险标签(risk label)呈现,而不是作为 Entra 的主元数据。EntraIdentityBridge专门负责这种映射(见下文"Entra 身份联邦"一节)。
Layer 4:Security Fabric(安全织网)
AGT 策略上的data_classification标签与 Purview 敏感度标签对齐;AGT 信任分可作为 Defender for AI 中的风险信号。该集成主要通过遥测管道(Layer 2 导出)实现,而非直接 API 集成。
数据流
Agent Runtime Citadel Gateway Azure Monitor ┌──────────────────┐ ┌──────────────────┐ ┌──────────────┐ │ │ │ │ │ │ │ Agent Code │ LLM │ APIM Gateway │ │ App Insights│ │ ┌────────────┐ │ request │ ┌────────────┐ │ │ │ │ │ AGT Policy ├──┼──────────►│ │ Rate Limit ├──┼────►LLM │ Event Hub │ │ │ Engine │ │ │ │ Content │ │ │ │ │ │ │ │ │ │ JWT Auth │ │ │ Log │ │ │ Decision: │ │ │ └────────────┘ │ │ Analytics │ │ │ allow/deny │ │ │ │ │ │ │ └─────┬──────┘ │ └──────────────────┘ └──────┬───────┘ │ │ │ │ │ ┌─────▼──────┐ │ ┌──────────────────┐ │ │ │ Citadel ├──┼──────────►│ Event Hub / │───────────────┘ │ │ Audit │ │ events │ App Insights │ │ │ Exporter │ │ └──────────────────┘ │ └────────────┘ │ └──────────────────┘一次完整请求的治理闭环包含以下 5 步:
- 代理动作触发 AGT 策略评估(进程内、亚毫秒级)。
- 若允许,请求通过 Citadel APIM 网关。
- APIM 强制网关级策略(限流、内容过滤器、JWT)。
- AGT 审计导出器将治理事件发送到 Azure Event Hub / App Insights。
- 事件携带关联 ID,将 AGT 决策与 APIM 请求追踪串联。
其中第 4 步的实现细节值得展开:CitadelAuditExporter(citadel_exporter.py)支持批量缓冲、异步 flush 与优雅降级——事件先进入本地缓冲区,达到batch_size(默认 50)或flush_interval_seconds(默认 10 秒)后自动刷出;发送失败的事件进入_failed_buffer待重试,不会丢失。from_env()工厂方法从环境变量读取全部配置(见 citadel_exporter.py):
| 环境变量 | 作用 | 默认值 |
|---|---|---|
CITADEL_EVENTHUB_CONNECTION_STRING | Event Hub 连接串 | 空(未配置则本地记录) |
CITADEL_APPINSIGHTS_CONNECTION_STRING | App Insights 连接串 | 空 |
CITADEL_EVENTHUB_NAME | Event Hub 名称 | agt-governance-events |
CITADEL_EXPORT_BATCH_SIZE | 批量刷出阈值 | 50 |
CITADEL_EXPORT_FLUSH_INTERVAL | 最大刷出间隔(秒) | 10 |
导出器定义了 5 类治理事件(GovernanceEventType):policy_decision、policy_violation、trust_score_change、action_intercepted、bundle_loaded,每类事件还携带hash_chain_prev/hash_chain_current字段,把 AGT 哈希链审计的防篡改证据一并上送(见 citadel_exporter.py)。
Policy Bundle Binding(策略包绑定)
Citadel Access Contract 使用.bicepparam文件声明代理环境可以访问哪些资源。AGT 通过追加一个策略包引用来扩展该声明:
// In the Access Contract .bicepparam file param agtPolicyBundle object = { bundleId: 'customer-support-v2' version: '1.3.0' source: 'https://vault.azure.net/secrets/agt-policy-bundle' }在部署时,策略包被拉取并注入代理环境;AGT 运行时在启动时通过PolicyBundleResolver加载它。仓库中的完整示例见 examples/citadel-governed-agent/sample-access-contract/main.bicepparam,它给出了三个取值来源的完整注释:
param agtPolicyBundle = { bundleId: 'customer-support-v2' version: '1.3.0' source: 'keyvault' // 'keyvault' | 'file' | 'url' secretName: 'agt-policy-bundle-customer-support' // For 'file' source: filePath: './policies/agent-policy.yaml' // For 'url' source: url: 'https://policy-store.example.com/bundles/customer-support-v2' }PolicyBundleResolver 的三种来源
从源码看,PolicyBundleResolver 支持三种加载来源,并带有内存缓存(_cache,按bundle_id去重):
- 本地文件(
file):resolve_from_file()使用 PyYAML 解析 YAML 策略文件,适合开发调试; - Azure Key Vault(
keyvault):resolve_from_keyvault()通过DefaultAzureCredential+SecretClient读取 JSON 序列化的策略包,适合生产环境,需要安装azure-keyvault-secrets azure-identity; - URL(
url):resolve_from_url()支持 JSON 或 YAML 两种格式,适合集中式策略管理。
resolve()方法是入口(见 policy_bundle.py):它从 Access Contract 配置中读取agtPolicyBundle参数,根据source字段分发到对应加载器,并先查缓存。若契约参数缺失或来源未知,会抛出ValueError,保证配置错误在启动期即被暴露。
PolicyBundle 与契约校验
加载后的策略包被建模为PolicyBundle数据类,关键字段包括bundle_id、version、data_classification、allowed_actions、blocked_actions、rate_limits、requires_justification、min_trust_score、audit_config,并自动计算content_hash(对原始配置做 sort_keys 后的 SHA-256,见 policy_bundle.py)用于完整性校验。validate_against_contract()方法还负责反向校验:AGT 策略约束不能超出契约允许范围(例如 AGT 限流不应超过 Citadel 配额),ID/版本不匹配会返回警告。
配套的策略包文件 examples/citadel-governed-agent/policies/agent-policy.yaml 展示了完整的字段语义:
policy: name: customer-support-policy version: "1.3.0" data_classification: confidential # 与 Citadel/Purview 标签对齐 allowed_actions: - query_customer_database - search_knowledge_base - send_email - create_ticket - escalate_to_human blocked_actions: - delete_customer_record - modify_billing - access_internal_systems - execute_code # Citadel 在网关层限制 100 calls/hour,AGT 在动作层收紧到每动作更小限额 rate_limits: query_customer_database: max_calls: 50 window_seconds: 3600 send_email: max_calls: 10 window_seconds: 3600 requires_justification: - send_email - escalate_to_human trust: minimum_score: 400 degraded_threshold: 600 actions_when_degraded: - query_customer_database - search_knowledge_base audit: log_all_decisions: true hash_chain: true export_to_citadel: true对应的策略评估流程可以在示例引擎 examples/citadel-governed-agent/src/agent.py 中看到完整实现顺序:先查blocked_actions(命中即拒绝并扣信任分 50),再查allowed_actions白名单,随后校验信任分是否低于minimum_score、动作是否缺少必需 justification、最后检查按动作的滑动窗口限流,全部通过才放行。每次决策都会追加进 SHA-256 哈希链(genesis 起链),形成防篡改审计线索(见 agent.py)。
Coverage Boundaries(职责边界)
明确各系统处理什么,可以避免重复治理或治理真空:
| 关注点 | 由谁处理 |
|---|---|
| LLM 模型访问控制 | Citadel Layer 1(APIM products/subscriptions) |
| Token 限流 | Citadel Layer 1(APIM policies) |
| 内容安全过滤 | Citadel Layer 1(Azure Content Safety) |
| 网关侧 PII 检测 | Citadel Layer 1(Azure Language Service) |
| 逐动作策略评估 | AGT Policy Engine |
| 工具调用 allow/deny | AGT Capability Model |
| 代理间信任 | AGT Trust Layer(Ed25519、SPIFFE) |
| 信任评分(0-1000) | AGT AgentMesh |
| 哈希链审计日志 | AGT Audit System |
| 舰队可观测性 | Citadel Layer 2 + AGT Exporter |
| 代理企业身份 | Citadel Layer 3(Entra) |
| 代理运行时凭据 | AGT(Ed25519/SPIFFE) |
| 威胁检测 | Citadel Layer 4(Defender) |
| 数据治理标签 | Citadel Layer 4(Purview)+ AGT data_classification |
Failure Modes(故障模式)
理解各组件不可用时的降级行为,是生产部署的必要前提:
| 组件不可用 | 行为 |
|---|---|
| Azure Event Hub / App Insights | AGT 继续运行。事件本地排队并在重连后重试。遥测采用 fail-open。 |
| Citadel APIM 网关 | 代理无法触达 LLM/工具。AGT 策略引擎本地仍然可用。 |
| AGT Policy Engine | 代理动作在无治理状态下继续(默认 fail-open,可配置为 fail-closed)。 |
| Entra ID | AGT 使用本地密码学身份。企业身份联邦暂停。 |
第 1 行的"遥测 fail-open"在源码中有直接印证:CitadelAuditExporter.flush()在未配置 Event Hub 时会把事件降级为本地日志记录(logger.info("Governance event (local): ..."),见 citadel_exporter.py),发送失败的事件进入_failed_buffer等待下次 flush 重试,而不是抛出异常中断代理。azure-eventhub或azure-monitor-opentelemetry-exporter未安装时,也只会记录警告并跳过对应导出目标(见 citadel_exporter.py)。
Entra 身份联邦
EntraIdentityBridge将 AGT 代理身份映射到 Entra ID 代理身份,用于 Citadel Layer 3 关联。这是证明/联邦(attestation/federation),而非回写(write-back):
- Entra 仍是企业身份与生命周期的权威;
- AGT 仍是运行时凭据与信任分的权威;
- AGT 信任分作为风险标签呈现在遥测中,而不是 Entra 元数据。
from agent_os.integrations.citadel import EntraIdentityBridge bridge = EntraIdentityBridge.from_env() # Bind AGT agent to its Entra managed identity (one-time setup) binding = bridge.bind( agt_agent_id="customer-support-agent-01", agt_public_key="<base64-ed25519-pubkey>", entra_object_id="00000000-0000-0000-0000-000000000001", ) # Produce attestation (emitted as telemetry) attestation = bridge.attest(binding, trust_score=850) # attestation.risk_label == TrustRiskLabel.TRUSTED信任分阈值(源码中TrustRiskLabel.from_score()的实现,见 identity_bridge.py):
>= 700:trusted(可信)>= 400:degraded(降级)< 400:untrusted(不可信)
桥接实现的三个细节
从源码与测试可以确认该桥接的三个工程细节:
- 密钥只存指纹不存明文:
bind()对 Ed25519 公钥计算 SHA-256 指纹(agt_public_key_thumbprint)存入绑定记录,而非保存密钥本身。测试test_bind_hashes_the_public_key_rather_than_storing_it明确断言"指纹等于密钥的 SHA-256,且密钥材料不出现在绑定序列化结果中"(见 test_citadel_integration.py)。 - 阈值边界是包含下限:参数化测试
test_risk_label_boundaries验证了 700/400 是"inclusive lower bounds"——700 → TRUSTED、699 → DEGRADED、400 → DEGRADED、399 → UNTRUSTED。 - Graph 验证可选:
CITADEL_ENTRA_VERIFY=true时,bind()会通过 Microsoft Graph 校验 Entra object 是否存在(_verify_entra_object),需要azure-identity,验证失败仅告警并标记verified=False,不阻断绑定。
桥接产生的IdentityAttestation记录携带binding_id、agt_agent_id、entra_object_id、trust_score、risk_label、policy_bundle_id、policy_bundle_hash与时间戳,作为遥测事件输出(见 identity_bridge.py)。
APIM Governance Metadata(治理元数据透传)
agt-governance-metadata策略片段(policy fragment)让 Citadel 网关记录 AGT 治理态势,而无需把 AGT 放进请求热路径。这是该集成中最关键的性能设计决策:APIM不会在每个请求上都调用 AGT 的策略端点——那会带来额外网络跳转延迟、造成可用性耦合、并产生"两个系统同时做 allow/deny"的脑裂决策。相反,代理运行时本地评估策略,把结果作为咨询性元数据经由网关传递;APIM 只负责记录与关联,不做治理决策(除非显式开启可选的信任阈值拦截)。
完整流程:
- 代理运行时在发起 LLM 调用前设置
X-AGT-*请求头; - APIM 片段读取这些请求头,将其作为自定义追踪维度记录;
- 片段在转发到后端前剥离 AGT 请求头(纵深防御,防止下游泄露治理元数据);
- 响应携带
X-AGT-APIM-Request-Id供跨系统关联。
策略片段 XML、示例产品策略与部署说明见 examples/citadel-governed-agent/apim-policies/(对应文件为 agt-governance-metadata.xml 与 agt-governed-product-policy.xml)。
请求头 Schema
代理运行时在发起 LLM 调用前设置的请求头:
| Header | 类型 | 说明 |
|---|---|---|
X-AGT-Trust-Score | Integer (0-1000) | 代理当前信任分 |
X-AGT-Risk-Label | String | trusted、degraded或untrusted |
X-AGT-Policy-Bundle | String | 策略包 ID(如customer-support-v2) |
X-AGT-Policy-Version | String | 策略包版本(如1.3.0) |
X-AGT-Decision-Id | UUID | 用于关联的 AGT 策略决策 ID |
片段追加到响应中的头:
| Header | 类型 | 说明 |
|---|---|---|
X-AGT-APIM-Request-Id | UUID | 用于跨系统追踪关联的 APIM 请求 ID |
片段代码中(见 agt-governance-metadata.xml)还包含一段默认注释掉的<choose>拦截逻辑:如需在网关层做粗粒度安全兜底,可取消注释,当X-AGT-Risk-Label == untrusted时直接返回403并携带agt_decision_id;片段作者明确提示这是"粗粒度安全网,而非 AGT 细粒度策略评估的替代品"。
代理侧设置请求头
apim-policies/README.md 给出了代理代码中设置请求头并与响应关联的完整示例:
import httpx from agent_os.integrations.citadel.identity_bridge import TrustRiskLabel headers = { "X-AGT-Trust-Score": str(current_trust_score), "X-AGT-Risk-Label": TrustRiskLabel.from_score(current_trust_score).value, "X-AGT-Policy-Bundle": policy_bundle.bundle_id, "X-AGT-Policy-Version": policy_bundle.version, "X-AGT-Decision-Id": decision_id, } response = httpx.post( "https://apim-gateway.azure-api.net/openai/deployments/gpt-4o/chat/completions", headers={**auth_headers, **headers}, json=payload, ) # Read back the APIM request ID for correlation apim_request_id = response.headers.get("X-AGT-APIM-Request-Id", "")部署片段
通过 Azure CLI 将片段部署为 APIM named value(名为agt-governance-metadata):
az apim api-management named-value create \ --resource-group <rg> \ --service-name <apim> \ --named-value-id agt-governance-metadata \ --display-name "AGT Governance Metadata Fragment" \ --value "$(cat agt-governance-metadata.xml)"然后在 Access Contract 的产品策略中引用:<include-fragment fragment-id="agt-governance-metadata" />。
快速开始
- 部署 Citadel Governance Hub:参考 Citadel 的 Layer 1 参考实现(AI Hub Gateway Solution Accelerator 的 citadel-v1 分支)完成 APIM 网关与 Access Contract 基础设施部署。
- 安装 AGT:
pip install agent-governance-toolkit[full] - 配置导出器:设置
CITADEL_EVENTHUB_CONNECTION_STRING和CITADEL_APPINSIGHTS_CONNECTION_STRING两个环境变量(可选配置CITADEL_ENTRA_TENANT_ID、CITADEL_ENTRA_VERIFY)。 - 部署 APIM 片段:按上文 Azure CLI 命令部署 agt-governance-metadata.xml。
- 运行端到端示例:见 examples/citadel-governed-agent/。
本地零依赖跑通治理闭环
示例 examples/citadel-governed-agent/README.md 支持两种模式:
# 本地模式:无需任何 Azure 依赖(mock 网关 + mock 导出器) python src/agent.py --mock # 接真实 Citadel 网关(需配置环境变量) export CITADEL_GATEWAY_URL=https://your-apim.azure-api.net export CITADEL_API_KEY=your-subscription-key export CITADEL_EVENTHUB_CONNECTION_STRING=Endpoint=sb://... python src/agent.py本地模式下,agent.py 会依次演示 5 个治理场景:白名单动作放行(query_customer_database)、显式拦截(delete_customer_record)、缺少 justification 拒绝(send_email)、携带 justification 放行、未知动作拒绝(execute_code),并在摘要中输出决策总数、放行/拒绝计数、当前信任分、哈希链头与导出事件数,完整展示"策略评估 → 信任分联动 → 哈希链审计 → 事件导出"的治理闭环。
参考
- AGT 系统架构设计:AGT 整体设计
- Citadel + AGT 受治理代理示例:含代理源码、策略包、Access Contract 与 APIM 策略
- Citadel 集成模块源码:
EntraIdentityBridge、PolicyBundleResolver、TrustRiskLabel的实现 - Citadel 审计导出器:
CitadelAuditExporter与GovernanceEvent - Citadel 集成测试:信任分阈值、密钥指纹、绑定增删与契约校验的测试佐证
【免费下载链接】agent-governance-toolkitAI Agent Governance Toolkit — Policy enforcement, zero-trust identity, execution sandboxing, and reliability engineering for autonomous AI agents. Covers 10/10 OWASP Agentic Top 10.项目地址: https://gitcode.com/GitHub_Trending/ag/agent-governance-toolkit
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考