模块 1 · 双栈鉴权

JWT 双栈:
模块鉴权(deps.py)与宿主网关鉴权(gateway/auth_deps.py)各管一线

模块 API 走模块鉴权(app/api/deps.py)(get_auth_context / get_platform_auth_context); 宿主 Wave 0 网关走宿主网关鉴权(app/gateway/auth_deps.py)。 模块禁止 import gateway——指挥 AI 改鉴权时,先确认改的是哪条栈。

两套鉴权表(背下来少踩坑)

通道入口函数X-Agent-Type典型路由
Agent / 对话get_auth_contextJWT 通道必填 + 准入矩阵/api/chat, /api/risk/*, simulate
平台只读get_platform_auth_context不要/api/customers/*, /api/analyst/*
宿主网关宿主网关鉴权(gateway/auth_deps.py)· get_auth_context宿主口径Wave 0 四件套(模块不 import)
debug 头兜底: 仅 APP_ENV=development 且无 RS256 公钥时,可用 X-Debug-Role + X-Debug-Actor 冒充身份——pytest 和部分演示 SOP 依赖此通道;生产一律 Bearer JWT。
模块鉴权(deps.py)· 对话线
agent_type = request.headers.get("X-Agent-Type")
if not agent_type:
    raise ApiError(401, "AUTH_401_MISSING_AGENT_TYPE")
assert_agent_access(auth, agent_type, ...)

# 平台线 — 无上述检查
def get_platform_auth_context(request):
    """不要求 X-Agent-Type"""
白话

对话线:验完 JWT 还要读 Agent 头,并对照 AGENT_ACCESS_MATRIX。

例如客户 token 不能带 X-Agent-Type: risk,否则 403。

平台线:验 JWT 就放行到归属断言,不问你走哪条 Agent。

宿主网关鉴权(gateway/auth_deps.py)栈是宿主合并用,和模块鉴权(deps.py)双栈并存,别在模块里混 import。

准入矩阵速览

customer仅 customer 角色
advisoradvisor / compliance / ops
analystanalyst / compliance
riskrisk_officer / risk_manager / service_risk

customers.py 的 Depends 应该从哪 import?