Skip to content

feat: export audit records and diagnostics to an OTLP collector - #121

Merged
plusky merged 1 commit into
mainfrom
feat/otlp-export
Aug 18, 2026
Merged

feat: export audit records and diagnostics to an OTLP collector#121
plusky merged 1 commit into
mainfrom
feat/otlp-export

Conversation

@plusky

@plusky plusky commented Aug 18, 2026

Copy link
Copy Markdown
Owner

A configured collector is a load-bearing audit sink, not a best-effort
copy of the file. Delivery is probed at startup; a failed export engages
the same FailMode gate a failed file write does; the file can be turned
off only with the exact none sentinel. Diagnostics stay best-effort on a
separate queue.

The two ambiguous spellings refuse to start rather than silently reshape
the trail: an OTLP endpoint with no file decision, and none with no
endpoint. File write still precedes export when both run.

Configuration is the standard OTel environment surface, off unless
OTEL_EXPORTER_OTLP_ENDPOINT (or the logs-specific variant) is set;
OTEL_EXPORTER_OTLP_HEADERS is credential material under I12. The
encoder is hand-written against opentelemetry-proto logs.proto:
zero new crates, Cargo.lock unchanged. The OpenTelemetry SDK route
was built and rejected on evidence (async reqwest panic off-runtime,
appender self-feed, endpoint logged at debug).

Touches I12 (export headers; endpoint weaker bar), I15 (no MCP surface;
persist bar is file write and/or export-queue accept), I9 (guard
untouched). Fail-closed refusals reuse each tool's uniform text.

Adversarial review (three lenses)

  • Security (MERGE-SAFE): I15/I12/I9 hold; FailMode texts do not
    fingerprint OTLP vs file vs guard. NEVER_EXPORTED_TARGETS plus the
    log.target bridge kills the self-feeding debug loop. Follow-up:
    export client follows no HTTP redirects so a 3xx cannot forward
    the audit body or a non-Authorization collector credential.
  • Correctness (MERGE-SAFE): 2×2 sink matrix, exact-bytes none,
    probe-before-file, dual queues, audit-only latch clear, stdio
    SIGTERM flushes then process::exit(0). Probe refusals name the
    variables that actually won (including OTEL_EXPORTER_OTLP_LOGS_*).
  • Docs (initially NOT MERGE-SAFE): leftover file-only prose in
    README and examples/audit.toml (including a false “without that
    flag no stream is written”). Fixed; clap/man now document none and
    the two startup-error cells, and ENVIRONMENT lists the seven OTEL
    variables.

Verification: cargo fmt --check, both clippy -D warnings lines,
cargo test --workspace --all-targets --locked (local, including the
rebased tree on current main).

Closes #31

@plusky
plusky marked this pull request as draft August 18, 2026 16:12
@plusky plusky added the ai-assisted Authored or substantially written with an AI coding agent label Aug 18, 2026
A configured collector is a load-bearing audit sink: delivery is
probed at startup, a failed export engages the same FailMode gate a
failed file write does, and the file can be turned off only with the
exact `none` sentinel. Diagnostics stay best-effort on a separate
queue. The two ambiguous spellings (endpoint with no file decision,
`none` with no endpoint) refuse to start.

Configuration is the standard OTel environment surface, off unless
OTEL_EXPORTER_OTLP_ENDPOINT (or the logs-specific variant) is set;
OTEL_EXPORTER_OTLP_HEADERS is credential material under I12. The
encoder is hand-written against opentelemetry-proto logs.proto —
zero new crates, Cargo.lock unchanged.

Closes #31
@plusky
plusky marked this pull request as ready for review August 18, 2026 19:36
@plusky
plusky merged commit a2ec0b5 into main Aug 18, 2026
13 checks passed
@plusky
plusky deleted the feat/otlp-export branch August 18, 2026 19:41
@plusky plusky mentioned this pull request Aug 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-assisted Authored or substantially written with an AI coding agent

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Document shipping the audit log to an OTel collector (+ examples/otel-collector.yaml)

1 participant