Files
XingHuo/app/utils/authz.py
T

77 lines
2.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""鉴权拒绝留痕公共出口(手册 P-05 双写;T-04 评审 P1-2 收口)。
背景:越权留痕原本只在 API 层(api/deps._authz_audit)实现,对话 Tool 层
归属被拒时只落 agent_tool_call,全局鉴权审计维度缺失(输入防护台账查不到
对话链路的越权尝试)。本模块把该逻辑下沉到 utils,供两方共用:
- API 层:deps.deny / _authz_audit(403)
- 对话层:tool_service.run_tool 的 blocked 分支(AUTH_403_* 归属拒绝)
放 utils 而非 api 的原因:service 层不得反向依赖 api 层(分层约束)。
降级口径(与 T-02 审计一致):写库失败仅本地 logger.exception,不改变
拒绝语义——对话不因留痕故障中断,生产可切 fail-closed(待决,已登记)。
"""
from __future__ import annotations
import logging
from typing import Any, Sequence
from app.utils.trace import current_trace, new_trace
logger = logging.getLogger(__name__)
# 四 Agent 入口(input_guard_log.agent_type 的 ENUM 仅此四值;platform 跳过)
AGENT_TYPES = ("customer", "advisor", "analyst", "risk")
def record_authz_denial(
risk_repo: Any,
*,
actor_id: str,
code: str,
roles: Sequence[str] | None = None,
customer_id: str | None = None,
agent_type: str = "risk",
trace_id: str | None = None,
) -> None:
"""越权/拒绝留痕:audit_log(authz) + input_guard_log(四 Agent 内)。
agent_type 非四 Agent(如 platform 网关)时只写 audit_log——
input_guard_log.agent_type 是 ENUM,越界写会报数据截断(T-02 同口径)。
"""
trace_id = trace_id or current_trace() or new_trace()
try:
risk_repo.insert_audit_log(
{
"trace_id": trace_id,
"event_type": "authz",
"agent_type": agent_type,
"actor_id": actor_id or "anonymous",
"customer_id": customer_id,
"rule_id": None,
"input_summary": {"roles": list(roles or []), "code": code},
"decision": "forbidden",
"risk_score": None,
"handler_id": None,
"handler_result": None,
"handler_comment": None,
}
)
if agent_type in AGENT_TYPES:
risk_repo.insert_input_guard_log(
trace_id=trace_id,
agent_type=agent_type,
actor_id=actor_id or "anonymous",
guard_type="illegal_param",
action="blocked",
raw_excerpt=code,
)
except Exception:
logger.exception(
"authz audit failed (degraded): code=%s agent=%s actor=%s",
code,
agent_type,
actor_id,
)