← Blog

AI code review18 Oct 2026

How to review an AI-written request logging change without leaking sensitive data

Inspect every log path, allowlist useful fields, and test emitted records with secret sentinels before approving.

By

A request path sends selected safe fields into a log record while a sensitive field stops at the boundary
A useful request log carries diagnostic context without copying sensitive input.

When an AI-written PR adds request logging, review the records it can emit, not just the new logger call. List the fields that leave the request, follow every success and failure path to the log sink, and run a test that puts a unique secret in the request and asserts that it never appears in the captured output. The useful outcome is a log that helps diagnose a request without copying credentials or private payloads into it.

Imagine a checkout endpoint where an agent adds middleware that logs the method, path, headers, body, duration, and thrown error. The happy-path record looks helpful. A failed payment may carry an authorization header, an address in the body, or a provider error that echoes part of the request. The review needs to follow those paths too.

Map what can reach each log sink

Start at the changed logger calls and trace the values they receive. Include framework request logging, exception handlers, retry wrappers, background jobs, and any shared serializer the PR changes. A direct call may log only requestId, while a surrounding error handler serializes the whole request or the exception object. Check the actual output format, including nested metadata and stack traces, instead of trusting a type named SafeRequest.

Write a small field inventory: which values are required for diagnosis, where each comes from, and whether the field can contain user input. Method, a route template, status, duration, and a generated request ID may be enough. A raw URL can include query parameters; headers and bodies can carry credentials or personal data. Decide on fields by meaning and source, not by whether their names look harmless.

The Intent Document can help you find where the agent made that decision. Compare problem.user_asks and approach.requirements with the anchored tour. If the request only asked for latency visibility, ask why request bodies were added. Checking scope drift is useful when the logging change grew beyond the original ask.

Allowlist useful fields before serialization

Prefer constructing a new record from explicit safe fields at the point where request data crosses into logging. This keeps a future header or body property from appearing automatically. If a field needs masking, define the transformation and test it for missing, malformed, repeated, and nested values. A blocklist that removes a few known header names can miss a token inside an error message, query string, or object added later.

Check what happens when logging itself fails. A fallback such as logger.error(error, request) can restore the exact data the main path removed. Also check whether an error library copies request details into message, cause, or stack metadata. Keep enough context to debug, such as a request ID and stable error category, without serializing the original payload.

This is an engineering choice for the service, not a claim that Review Assist sanitizes application logs. Review Assist's local validator checks likely secrets in the Intent Document. It does not inspect your service's runtime log stream. The data-flow article explains Review Assist's own boundary.

Test emitted records on success and failure

Capture the real logger output in a focused test. Send one request with a distinctive fake token in an authorization header, query parameter, body field, and nested error detail. Exercise a successful response, a validation failure, and a downstream exception or timeout. Assert that the token is absent from the serialized message and metadata in every record. Also assert the allowed fields are present, so a fix that turns logging off does not pass as useful observability.

Use fake values that look like the data the service receives, and keep the test local. If the application has multiple transports or formatters, exercise the one deployed in production or verify that they share the same serializer. A unit test of a redaction helper alone cannot show what an exception handler or transport emits.

Read verification.performed and verification.not_verified against the current PR head. Review Assist anchors changed hunks and records what the agent says it checked, but its coverage count only shows that counted hunks have tour anchors. It does not prove that logs are safe. Reviewing an untested path gives a way to turn the remaining gap into a concrete request.

Ask for evidence you can inspect

A useful review comment is: “The new middleware logs the request body on failure. Please show a captured record for a request with fake credentials in the header, query, body, and nested error. Remove those values from every transport while keeping request ID, route template, status, duration, and a stable error category. Add an assertion for the emitted record, then name any failure path the test still misses.”

Approve when the field inventory is explicit, the output is built from the allowed fields, the failure paths have been checked, and a captured-record test proves both absence of sensitive values and presence of diagnostic context. If a log destination or retention rule sits outside this PR, name its owner as an open question rather than treating code review as proof of the whole data lifecycle.

Written by Udit Khandelwal, who builds Review Assist. Every claim here is meant to match the code; if one does not, open an issue.

Review AI-written code with its intent intact

Review Assist is free, open source, and stores none of your code.

Install Review Assist