AI Security
Logging External API Calls from AI Tools: A Practical Guide for Small Businesses
TL;DR: Record every API request and response that an AI tool makes, strip or hash any secrets, store logs in an immutable, access‑controlled sink, and map the data to NIST and OWASP controls so you can prove compliance and investigate incidents.
Which events need to be logged when an AI tool calls an external API?
At a minimum, capture the following fields for each outbound request and inbound response:
- Timestamp (UTC)
- AI agent identifier (name, version, deployment ID)
- Calling user or session ID
- Endpoint URL (redacted to domain only if privacy‑sensitive)
- HTTP method and status code
- Request payload hash (e.g., SHA‑256) – never raw PII or secrets
- Response payload hash
- Correlation ID for multi‑step workflows
- Outcome classification (success, throttled, error, policy‑blocked)
This mirrors the OWASP GenAI recommendation to log “all external interactions with sufficient context to reconstruct the transaction without exposing data” [OWASP GenAI].
How can I capture request/response data without leaking secrets?
Never write raw API keys, passwords, or user‑provided PII to logs. Use one of these patterns:
- Pre‑masking: Before the request leaves the agent, replace any field matching a secret‑pattern with
***REDACTED***. - Hashing: Compute a deterministic hash of the payload (excluding known secret fields) and store the hash. This lets you detect duplicate content without seeing the raw text.
- Envelope logging: Log only metadata (size, MIME type) and a reference to the encrypted payload stored elsewhere with strict ACLs.
OpenAI’s Agents SDK includes a logRequests hook that you can wrap with your own redaction logic [OpenAI Agents]. Claude Managed Agents expose a similar logging configuration [Claude Docs].
What log format and storage practices support auditability and privacy?
Use a structured, machine‑readable format such as JSON Lines. Example entry:
{
"timestamp": "2026-06-30T12:34:56Z",
"agent_id": "sales‑assistant-v1",
"user_id": "u_12345",
"endpoint": "api.stripe.com/v1/charges",
"method": "POST",
"status": 200,
"request_hash": "a1b2c3...",
"response_hash": "d4e5f6...",
"outcome": "success",
"correlation_id": "c9f8e7"
}
Store logs in an immutable bucket (e.g., AWS S3 with Object Lock, Azure Immutable Blob) or a write‑once SIEM. Set retention based on regulatory needs (often 90‑180 days) and enforce least‑privilege IAM policies.
How do these logging practices map to NIST AI RMF and OWASP controls?
NIST’s AI Risk Management Framework calls for “traceability of AI system actions” (Governance, Functionality, and Data categories). Your log entries provide that traceability.
OWASP’s Top‑10 for LLM Applications lists “Logging & Monitoring” as a critical control. By logging every external call, you satisfy the “record‑keeping” sub‑control and enable rapid detection of anomalous usage.
Sample logging configuration for popular agent platforms
OpenAI Agents (Python)
import os, hashlib, json, logging
from openai import OpenAI
logger = logging.getLogger("ai_api_logger")
logger.setLevel(logging.INFO)
handler = logging.FileHandler("/var/log/ai_api.log")
handler.setFormatter(logging.JSONFormatter())
logger.addHandler(handler)
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
def log_request(response, **kwargs):
request = response.request
payload = request.body or ""
payload_hash = hashlib.sha256(payload.encode()).hexdigest()
logger.info({
"timestamp": response.headers.get("date"),
"agent_id": "customer‑assistant",
"user_id": kwargs.get("user_id"),
"endpoint": request.url.split("?")[0],
"method": request.method,
"status": response.status_code,
"request_hash": payload_hash,
"response_hash": hashlib.sha256(response.text.encode()).hexdigest(),
"outcome": "success" if response.ok else "error",
"correlation_id": response.headers.get("x-request-id")
})
client.add_hook("response", log_request)
Claude Managed Agents (YAML)
logging:
level: info
destination: s3://my‑logs/ai‑calls/
format: json
redaction:
fields: ["api_key", "access_token"]
placeholder: "***REDACTED***"
Replit Agents (JavaScript)
import crypto from "crypto";
import { writeFile } from "fs/promises";
export async function fetchWithLog(url, options, context) {
const reqBody = options.body || "";
const reqHash = crypto.createHash("sha256").update(reqBody).digest("hex");
const res = await fetch(url, options);
const resBody = await res.text();
const resHash = crypto.createHash("sha256").update(resBody).digest("hex");
const entry = {
timestamp: new Date().toISOString(),
agent_id: context.agentId,
user_id: context.userId,
endpoint: new URL(url).origin,
method: options.method || "GET",
status: res.status,
request_hash: reqHash,
response_hash: resHash,
outcome: res.ok ? "success" : "error",
correlation_id: res.headers.get("x-correlation-id")
};
await writeFile("/var/log/ai_api.log", JSON.stringify(entry) + "\n", { flag: "a" });
return res;
}
These snippets illustrate a repeatable pattern: hash payloads, redact secrets, and push a structured entry to an immutable sink.
Putting it all together – a checklist for launch
- Define the log schema (timestamp, agent, user, endpoint, hashes, outcome).
- Implement redaction or hashing at the SDK level for each platform you use.
- Configure a write‑once storage target with proper IAM segregation.
- Map log fields to NIST AI RMF “Traceability” and OWASP “Logging & Monitoring” controls.
- Run a test run: trigger a known API call, verify the log entry, and confirm no secret appears.
- Schedule a weekly audit (e.g., query for any
status != 200or unexpected domains).
Following this checklist gives you a defensible audit trail without slowing down the AI workflow.
FAQ
- Do I need to log successful calls, or only failures? Log both. Successes prove normal operation; failures reveal abuse or misconfiguration.
- Can I store raw request bodies for debugging? Only in a separate, encrypted vault with strict access controls, and retain for a short period (e.g., 24‑48 hours).
- How do I handle third‑party SaaS that already logs internally? Correlate their log IDs with your own via a shared correlation header (e.g.,
X-Trace-ID). - What if an AI agent streams data? Log the start and end of the stream, and hash each chunk; avoid persisting the full stream.
- Is JSON Lines the only format? No, but it is widely supported by SIEMs and log parsers; CSV or protobuf can be used if your stack requires it.
Need help tailoring a logging pipeline for your AI agents? AISecAll can review your design and implement secure, compliant logging without disrupting your workflow.
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.