Audit Log

Audit Log 是记录 AI Agent 应用中所有关键操作的日志模块,包括用户操作、工具调用、权限变更和安全事件。它是合规、排查和安全监控的基础。

#type / concept #status / evergreen #tech / backend #tech / ops

[!info] related notes

Audit Log

一句话定义

Audit Log 是记录 AI Agent 应用中所有关键操作的日志模块。它和普通日志不同,关注的是”谁在什么时间对什么做了什么操作”,用于合规审计、安全排查和问题回溯。

它解决什么问题

AI Agent 应用中有很多需要审计的操作:

  • 用户登录/登出
  • 工具调用(尤其是高风险操作如删除、支付)
  • 权限变更
  • Agent 执行的决策路径
  • 数据访问记录

没有审计日志,出了安全事件无法追溯。

核心原理

审计日志结构

type AuditEntry struct {
    ID         string    `json:"id"`
    Timestamp  time.Time `json:"timestamp"`
    UserID     string    `json:"user_id"`
    SessionID  string    `json:"session_id"`
    Action     string    `json:"action"`      // login, tool_call, permission_change
    Resource   string    `json:"resource"`    // tool_name, api_endpoint
    Detail     any       `json:"detail"`      // 参数、结果等
    IPAddress  string    `json:"ip_address"`
    UserAgent  string    `json:"user_agent"`
    Result     string    `json:"result"`      // success, failure, denied
}

需要审计的操作

操作优先级记录内容
用户登录/登出IP、设备、时间
工具调用工具名、参数、结果、耗时
高风险操作最高完整参数、审批记录
权限变更谁改了谁的权限
数据访问访问了什么数据
Agent 决策为什么选这个工具

Go 中间件实现

func AuditMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        entry := AuditEntry{
            Timestamp: time.Now(),
            UserID:    getUserID(r),
            Action:    r.Method + " " + r.URL.Path,
            IPAddress: r.RemoteAddr,
            UserAgent: r.UserAgent(),
        }

        // 包装 ResponseWriter 以捕获状态码
        wrapped := &statusRecorder{ResponseWriter: w, status: 200}
        next.ServeHTTP(wrapped, r)

        entry.Result = fmt.Sprintf("status:%d", wrapped.status)
        auditLog.Save(entry)
    })
}

常见坑

  1. 审计日志和应用日志混在一起: 无法区分
  2. 不记录请求参数: 只记录了”调用了工具”,不知道传了什么参数
  3. 审计日志可被篡改: 应该写入独立的只读存储
  4. 不做日志轮转: 日志文件无限增长

参考资料

创建于 2026/6/30 更新于 2026/7/15