Series 5 - Bài 2: Audit Log Design

Audit log trong agent system không phải debug tool — là compliance và accountability record. Thiết kế sai từ đầu, không thể fix sau. Bài này phân tích anatomy của audit record đúng.

Nghe bài viết này dưới dạng podcast

Developers thường implement audit log như afterthought — thêm vào sau khi system đã chạy, khi có compliance requirement. Với agent system, đây là sai lầm đắt giá.

Agent thực hiện actions có real-world consequences: ghi file, chạy commands, gọi APIs. Khi có vấn đề — và sẽ có — bạn cần biết chính xác: ai yêu cầu action, agent đã decide gì, action nào được thực thi, kết quả là gì.

Audit log không phải debug tool. Đó là accountability record.

Sự khác biệt: Debug log vs Audit log

Debug Log:
  Mục tiêu: giúp developer hiểu bug
  Audience: developer
  Retention: ngắn (7-30 ngày)
  Format: human-readable, flexible
  Mutable: có thể xóa, compress

  "ERROR: read_file failed - ENOENT at path /src/x.ts"

Audit Log:
  Mục tiêu: record actions có consequences
  Audience: compliance, security team, legal
  Retention: dài (1-7 năm tùy jurisdiction)
  Format: structured, machine-queryable
  Immutable: không được sửa hay xóa

  {
    "action": "write_file",
    "actor": { "user": "linh@msb.com", "agent": "coding-agent-v2" },
    "resource": "src/loan/loan.service.ts",
    "authorized_by": "user_confirmation",
    "result": "success",
    "timestamp": "2025-05-25T10:30:15.234Z"
  }

Anatomy của một Audit Record

{
  // Identity fields
  audit_id: "aud_01ABC",           // unique, immutable
  session_id: "sess_xyz789",       // link to session
  timestamp: "2025-05-25T10:30:15.234Z",

  // Who
  actor: {
    user_id: "linh@msb.com",       // human initiator
    agent_id: "coding-agent-v2",   // which agent version
    agent_turn: 7,                 // turn trong session
    on_behalf_of: "user"           // agent acting FOR user
  },

  // What
  action: {
    type: "tool_execution",
    tool: "write_file",
    input: {
      path: "src/loan/loan.service.ts",
      // KHÔNG log full content — chỉ log metadata
      size_bytes: 8240,
      operation: "overwrite"
    }
  },

  // Authorization
  authorization: {
    method: "user_confirmation",   // how was this authorized
    confirmed_at: "2025-05-25T10:30:14.800Z",
    confirmation_text: "Write to src/loan/loan.service.ts?"
  },

  // Result
  result: {
    status: "success",
    duration_ms: 52,
    output_summary: "287 lines written"
    // Không log full output — chỉ summary
  },

  // Context
  context: {
    task_description: "Refactor processLoan for edge case",
    llm_decision_span_id: "span_abc123"  // link to reasoning
  }
}

Bảy quy tắc Audit Log

Rule 1: Immutable

Audit records không được sửa hay xóa.

Implementation options:
  Append-only database (event sourcing)
  Write-once storage (S3 Object Lock)
  Cryptographic chaining (hash previous record)
  External audit service

Không đủ:
  DELETE permission bị disable
  → Admin vẫn có thể enable và delete
  → Không thực sự immutable

Rule 2: Log action, không phải intent

Bad:
  "Agent decided to write the file because..."
  → Log ý định, không thể verify

Good:
  action: "write_file"
  input: { path: "...", size: 8240 }
  result: "success"
  → Factual, verifiable

Rule 3: Actor đầy đủ — cả user lẫn agent

Agent actions xảy ra on behalf of user.
Both phải được record:

  user_id: "linh@msb.com"      → ai yêu cầu
  agent_id: "coding-agent-v2" → ai thực thi
  agent_version: "2.1.4"      → which version

Tại sao agent version quan trọng:
  Khi audit sau 6 tháng, cần biết
  agent này đã được train/configured như thế nào

Rule 4: Authorization method explicit

Authorization methods:
  auto_approved    → trong allowed list, không cần confirm
  user_confirmed   → user explicitly confirm
  implicit_consent → user biết agent sẽ làm điều này khi bắt đầu task
  system_policy    → policy cho phép auto

Tại sao quan trọng:
  Nếu action gây vấn đề:
  "auto_approved" → kiểm tra lại policy
  "user_confirmed" → user chịu trách nhiệm

Rule 5: Sensitive data không đi vào audit log

NÊN log:
  path: "src/loan/loan.service.ts"
  operation: "write"
  size_bytes: 8240

KHÔNG NÊN log:
  content: "[full file content with PII]"
  command_output: "[may contain credentials]"
  user_message: "[may contain confidential info]"

Thay thế:
  Log hash của content để verify integrity
  Log size, line count thay vì content
  Log truncated preview (50 chars) nếu cần

Rule 6: Machine-queryable format

Bad (prose):
  "User linh wrote file loan.service.ts at 10:30"
  → Không query được programmatically

Good (structured JSON):
  { actor: {user: "linh"}, action: {tool: "write_file"}, ... }
  → Query: tất cả write_file bởi linh trong 30 ngày qua
  → Aggregate: average tool calls per session
  → Alert: user X thực hiện delete > 10 files trong 1 giờ

Rule 7: Completeness trước Correctness

Nếu phải chọn giữa:
  Log đầy đủ (có thể có duplicate)
  vs
  Log chính xác (có thể miss events)

Chọn đầy đủ.

Duplicate có thể deduplicate sau.
Missed events không thể recover.

Implementation: buffer và batch write,
  nhưng đừng drop events khi buffer full.
  Backpressure thay vì data loss.

Audit Log Schema cho Agent

Minimum viable schema:

  audit_id        TEXT PRIMARY KEY
  session_id      TEXT NOT NULL
  timestamp       TIMESTAMPTZ NOT NULL
  user_id         TEXT NOT NULL
  agent_id        TEXT NOT NULL
  action_type     TEXT NOT NULL  -- tool_execution, llm_call, etc
  tool_name       TEXT           -- nếu là tool execution
  resource        TEXT           -- file path, API endpoint, etc
  authorization   TEXT NOT NULL  -- auto/confirmed/policy
  result_status   TEXT NOT NULL  -- success/failure/cancelled
  duration_ms     INTEGER
  metadata        JSONB          -- flexible extra fields

Indexes:
  (session_id, timestamp)    -- session replay
  (user_id, timestamp)       -- user activity
  (action_type, timestamp)   -- action analytics
  (tool_name, result_status) -- tool reliability

Trade-off: Granularity vs Storage

Fine-grained audit (mỗi LLM call, mỗi tool):
  + Complete picture
  + Forensic capability
  - Storage: ~5KB per agent turn
  - 1M sessions/month = 5TB audit data

Coarse-grained audit (chỉ side-effect actions):
  + Storage manageable
  - Thiếu context khi investigate

Recommendation:
  Fine-grained cho destructive actions (write, delete, execute)
  Coarse-grained cho read operations
  Session-level summary luôn luôn

Kết luận

  • Audit log không phải debug tool — là accountability record, cần design khác.
  • Mỗi record cần: identity (ai), action (làm gì), authorization (với quyền gì), result (kết quả).
  • Immutability là yêu cầu cứng — append-only storage hoặc write-once.
  • Log hành động thực tế, không phải intent. Log metadata, không phải content.
  • Cả user lẫn agent phải là actor — agent actions xảy ra on behalf of user.
  • Structured JSON để query được — audit log vô dụng nếu không thể search.
  • Completeness trước correctness — missed events không recover được.

Chưa có bình luận

Để lại bình luận

Bình luận sẽ được phê duyệt trước khi hiển thị.

Nhận bài viết mới

Mình sẽ gửi email khi có bài mới. Không spam.