Skip to content

Audit Logging

Paul edited this page Sep 9, 2026 · 3 revisions

Diagnostics and Audit Logging

Codexify has three distinct observability surfaces: ordinary lifecycle diagnostics, opt-in bounded payload previews, and a privacy-preserving append-only audit stream. Do not conflate their disclosure properties.


Three separate surfaces

Diagnostics (-v/-vv, RUST_LOG) Payload logging (--log-tool-payloads) Audit (--audit)
Purpose Debug lifecycle/context Inspect bounded request/response previews Record activity
Destination Tracing subscriber Tracing subscriber A JSONL file you choose
Payload values No Yes, bounded and redacted No, except optional command preview
Default info Off Off

Ordinary diagnostics:

  • -vcodexify=debug,rmcp=warn: tool-start events, hashed context, argument field names, duration, output accounting.
  • -vvcodexify=trace: adds a fully redacted argument-shape summary.
  • RUST_LOG overrides -v/-vv for protocol-level detail: RUST_LOG=codexify=trace,rmcp=warn codexify …

Tool payload previews

Payload logging applies uniformly to native tools and direct, gateway, or catalog-dispatched MCP calls. It is independent of -v/-vv:

# Requests and responses, with the default 2 KiB / 4 KiB limits
codexify --work-dir /path/to/project --log-tool-payloads

# Requests only, with an additional local value redacted
codexify --work-dir /path/to/project \
  --log-tool-payloads=requests \
  --tool-log-max-request-bytes 8192 \
  --tool-log-redact-env PRIVATE_REPOSITORY_TOKEN

An enabled mode emits paired start/finish events carrying the same monotonic call ID; the mode independently controls whether request and response previews are attached. Previews are compact JSON, bounded at a UTF-8 boundary, and carry explicit byte-count/truncation metadata. MCP image data and opaque resource URIs are never written verbatim. Direct and dispatched upstream calls include the resolved raw MCP server/tool identity.

Codexify redacts configured credentials and MCP env/header values, schema-marked writeOnly/password fields, signed native-file fields and URL parameters, resource capabilities, common secret-bearing environment variables and command-line forms, plus values named by toolLogging.redactEnv. This is defense in depth, not proof that arbitrary source or output contains no unknown secret. Payload logging is sensitive and remains off by default.

The toolLogging config block mirrors the payload flags:

Key Default Description
mode "off" "off", "requests", "responses", or "all".
level "info" trace, debug, info, warn, or error.
maxRequestBytes 2048 Redacted request-preview byte limit; range 6465536.
maxResponseBytes 4096 Redacted response-preview byte limit; range 6465536.
redactEnv [] Environment-variable values to remove.

CLI mode/level/byte-limit options replace the corresponding config values; repeated --tool-log-redact-env values merge with configured redactions. --log-tool-calls is only an alias for -v; it does not enable payload logging.

Turning on the audit log

codexify --work-dir /path/to/project --audit ~/.codexify/audit/tools.jsonl

The append-only JSONL stream starts with audit_started (server version, OS process, random run ID, command-preview policy), then emits schema-version-2 tool_start and tool_finish records. Each tool record carries:

  • an RFC 3339 timestamp, a monotonic call ID, the transport-session ID;
  • hashed ChatGPT conversation and project identifiers;
  • the downstream and resolved tool identity (including raw MCP server/tool names), duration, status;
  • the argument shape (only fields declared by the tool's schema; unknown keys/dynamic maps are counted but not named);
  • returned byte/token counts, truncation status when the tool reports it;
  • resident exec_command session/PID metadata.

Not written: raw conversation identifiers, project paths, scalar argument values, image data, structured output, and returned text.

Command previews (separate opt-in)

Shell commands can contain credentials, source, paths, and env values, so previews are off by default:

codexify --work-dir /path/to/project \
  --audit ~/.codexify/audit/tools.jsonl \
  --audit-command-preview \
  --audit-redact-env GITHUB_TOKEN

Before a preview is written, Codexify replaces the local MCP bearer, the configured conversation-authentication token, configured MCP-server env values, the referenced OpenAI tunnel key (when readable), values named by audit.redactEnv / --audit-redact-env, common secret-bearing env vars, and common --token, API_KEY=…, and Bearer … forms — then caps the preview at commandPreviewMaxBytes. This is defense in depth, not a proof that a command contains no secret literal. Leave previews disabled when command text itself is sensitive.

Config equivalents

The audit block mirrors the flags:

Key Default Description
logFile null JSONL destination; a relative path resolves from the launch directory. Setting it enables auditing.
includeCommandPreview false Include bounded, redacted previews.
commandPreviewMaxBytes 512 Max UTF-8 byte length of a preview; range 116384.
redactEnv [] Env-var names whose current values must be removed from previews.

--audit replaces audit.logFile; --audit-command-preview only enables previews; repeated --audit-redact-env values are merged with audit.redactEnv so a CLI invocation can't accidentally remove configured redactions.

File safety

Startup fails if an enabled audit file can't be opened safely. On Unix, newly created files use mode 0600, symlink targets are rejected, and an existing file with group/other permission bits is rejected. A later append/flush error is emitted as an error-level diagnostic without changing a tool's result.

It is a log, not a boundary

This is an operational activity log, not a tamper-evident security boundary. Model-launched commands run as the same OS user and can modify any audit file they can locate.

Keep the file outside the project access root, restrict its directory permissions, and forward it to a separately protected collector when you need independent evidence.


See also

Clone this wiki locally