AI Security

Structured Logging Blueprint for AI‑Powered Tools that Invoke External APIs

TL;DR: Capture every AI‑initiated external request in a structured, immutable log that records who, what, when, and why. Store logs in a tamper‑evident location, apply retention policies, and enable automated alerts for anomalous patterns. This blueprint shows how to do it with minimal code, using Cloudflare Workers AI as an example.

Why Structured Logging Matters for AI‑Driven API Calls

AI agents often act as glue between internal data and third‑party services (e.g., CRM, payment gateways, SaaS analytics). Each call can expose sensitive identifiers or trigger costly actions. Without a reliable log you lose:

What Data Should Be Captured

Record the following fields for every outbound request initiated by an AI workflow:

{
  "timestamp": "2024-09-01T12:34:56Z",
  "request_id": "c3f9a1b2-...",
  "agent_name": "lead‑gen‑assistant",
  "user_context": "[email protected]",
  "api_endpoint": "https://api.stripe.com/v1/charges",
  "http_method": "POST",
  "request_payload_hash": "sha256:abcd1234...",
  "response_status": 200,
  "response_body_hash": "sha256:efgh5678...",
  "duration_ms": 342,
  "risk_score": 12,
  "notes": "Triggered by user prompt ‘create invoice’"
}

Key considerations:

Choosing a Log Format and Transport

JSON lines (one JSON object per line) is the de‑facto standard for structured logs. It works with most SIEMs and cloud log services.

Transport Options

Secure Storage and Tamper‑Evidence

Store logs in a location that provides:

Example: Cloudflare Workers AI can forward logs to a Cloudflare R2 bucket with immutability enabled.

Retention, Rotation, and Deletion

Follow the principle of least‑privilege data retention:

  1. Keep detailed logs for 90 days for active monitoring.
  2. Archive compressed JSON‑L files for up to 2 years for compliance.
  3. Purge logs older than the regulatory window using lifecycle rules.

Never delete logs manually; rely on automated policies to avoid accidental loss.

Automated Alerting for Anomalous API Usage

Feed the structured logs into a simple rule engine (e.g., Cloudflare Workers KV + Cron) that raises alerts when:

Send alerts to Slack, email, or PagerDuty via webhook.

Sample Implementation with Cloudflare Workers AI

The snippet below shows a minimal Worker that wraps an AI call, logs the request, and forwards the log to an R2 bucket.

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
  const start = Date.now()
  const requestId = crypto.randomUUID()
  const body = await request.json()

  // Call the AI model (simplified)
  const aiResponse = await fetch('https://api.cloudflare.com/client/v4/accounts/.../ai/run', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body.prompt)
  })

  const duration = Date.now() - start
  const logEntry = {
    timestamp: new Date().toISOString(),
    request_id: requestId,
    agent_name: 'sales‑assistant',
    user_context: body.user,
    api_endpoint: 'https://api.stripe.com/v1/charges',
    http_method: 'POST',
    request_payload_hash: await crypto.subtle.digest('SHA-256', new TextEncoder().encode(body.prompt)).then(h => Buffer.from(h).toString('hex')),
    response_status: aiResponse.status,
    response_body_hash: await aiResponse.clone().text().then(t => crypto.subtle.digest('SHA-256', new TextEncoder().encode(t)).then(h => Buffer.from(h).toString('hex'))),
    duration_ms: duration,
    risk_score: assessRisk(body.prompt), // custom function
    notes: 'AI‑generated invoice request'
  }

  // Store log in R2 (bucket named "ai-logs")
  await AI_LOGS.put(`${requestId}.jsonl`, JSON.stringify(logEntry) + "\n", {
    httpMetadata: { contentType: 'application/json' },
    customMetadata: { immutable: 'true' }
  })

  return new Response(JSON.stringify({ success: true }), { status: 200 })
}

function assessRisk(prompt) {
  // Very naive risk estimator – replace with your own model
  return /\bdelete\b|\bdrop\b/i.test(prompt) ? 80 : 5
}

Replace AI_LOGS with your R2 binding. The log is written once and cannot be overwritten, satisfying tamper‑evidence requirements.

Key Takeaways

Need a practical AI security review?

AISecAll reviews prompts, tool permissions, document flows, and agent behavior so small teams can use AI without guessing where the risk sits.

Book a call Discuss a project