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.

5 phút đọc
Tập này đang được chuẩn bị, quay lại sau nhé.

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.