Skip to content

feat(auditlog): tamper-evident audit events over OTLP logs - #158

Merged
hung12ct merged 4 commits into
mainfrom
feat/auditlog-otlp
Nov 3, 2026
Merged

hung12ct merged 4 commits into
mainfrom
feat/auditlog-otlp

Conversation

@hung12ct

@hung12ct hung12ct commented Nov 3, 2026

Copy link
Copy Markdown
Owner

What & why

Adds pkg/auditlog (experimental): durable, tamper-evident "who did what" records for agent actions — tool runs, human approvals, permission verdicts, rejected requests, data and config changes — exported as OTLP log records, so the collector already running for traces and metrics carries the audit trail. Opt-in; nothing in the core imports it.

Changes

  • Eight validated event types sharing Common (tenant, actor, session, source IPs). Invalid events fail at Send with ErrInvalidEvent.
  • OTLP logs client over gRPC or HTTP/protobuf with TLS/mTLS, headers, gzip, and transient-only retry. Default ModeBlocking: Send returns after the collector acks; partial rejection is an error. ModeBatch is opt-in, with a bounded queue and counted drops.
  • Agent integrations: ToolMiddleware (per-tool levels, optional fail-closed), AuditConfirm, AuditPermissions, EventHandler. Actor via WithActor(ctx, ...).
  • Integrity: with HMACKey, argument fingerprints are keyed, and every record is sequenced and HMAC-signed; Verify reports modified, forged, renumbered, and deleted records.
  • Multi/MultiAll plus JSONLWriter for redundant destinations; self-health metrics via Config.Meter.
  • No new modules: the OTLP proto, gRPC, and protobuf deps move from indirect to direct.

Testing

  • In-process gRPC/HTTP receivers cover record shape, retries, TLS with a CA file, partial rejection, batching, and a full agent-loop audit trail. Mutation checks confirm the tests catch each key behavior.
  • Verified against a live otel/opentelemetry-collector in both modes.

Checklist

  • Title is a Conventional Commit
  • gofmt -l . prints nothing
  • make lint is clean
  • make build passes
  • make test and make test-race pass
  • Errors wrapped with a package prefix
  • CHANGELOG.md updated if this PR is cut as a release tag (at tag time)
  • No changes to pkg/llm/, pkg/history/, or pkg/telemetry/

…LP logs

- Eight event types sharing Common (tenant, actor, session, source IPs);
  Validate() enforces required fields, enums and length limits.
- Thin OTLP logs client over gRPC or HTTP/protobuf with TLS/mTLS, headers,
  gzip and transient-only retry. Send returns after the collector acks;
  partial rejection is an error.
- Records carry the ctx trace/span IDs for audit-to-trace correlation.
- ToolMiddleware, AuditConfirm, AuditPermissions and EventHandler audit tool
  runs, human approvals, policy verdicts and hook rejections; actor via
  WithActor on ctx.
- WithFailClosed refuses to run a tool whose audit record can't be written.
- Outcome records are sent on a cancellation-detached ctx.
…y levels

- HMACKey: ArgsHMAC replaces the plain SHA-256 fingerprint (brute-forceable
  for low-entropy args); every record is sequenced and HMAC-signed, and
  Verify reports modified, forged, renumbered and deleted records.
- Config.Meter: records{kind,result} and export latency, so a broken audit
  pipeline is visible.
- ModeBatch: bounded queue, batched export, drops counted and returned as
  ErrBufferFull; per-event trace context kept. Fail-closed stays synchronous.
- Multi/MultiAll and JSONLWriter for redundant destinations.
- WithPolicy/WithLevel (None/Metadata/Request/RequestResponse) replace
  WithArgs/WithFilter.
- Single-pass event encoding (~10x faster, 3 allocs).
@hung12ct
hung12ct merged commit 68342c5 into main Nov 3, 2026
2 checks passed
@hung12ct
hung12ct deleted the feat/auditlog-otlp branch November 3, 2026 11:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant