Repository navigation
fix(audit): flush pending audit logs before exit - #215
Open
a-palamarchuk wants to merge 1 commit into
Open
a-palamarchuk wants to merge 1 commit into
a-palamarchuk wants to merge 1 commit into
Conversation
SetupAuditor started SocketAuditor.Loop on the CLI context, which is never canceled before the process exits, and nothing waited for the loop. When the wrapped command exits, boundary returns and the process ends, so logs still queued for the next batch (up to 5 seconds or 10 requests) never reach the workspace agent or coderd, while the local log keeps them. For short commands every record is lost. SetupAuditor now also returns a close function. It cancels the loop, which already drains and flushes on cancellation, and waits up to 5 seconds for it to finish so an unresponsive agent cannot block exit. The nsjail and landjail parents defer it, so it runs after the proxy has stopped and before the CLI exits. Fixes coder/registry#1019. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes coder/registry#1019 (filed in the registry repo, but the bug is here).
Problem
SetupAuditorstartedSocketAuditor.Loopwithgo socketAuditor.Loop(ctx)on the CLI context (inv.Context()). That context is never canceled before the process exits, and nothing waited for the loop.When the wrapped command exits,
run.Runreturns and the process ends. On a non-zero child exit this goes throughos.Exitincli/cli.go.Any logs still queued for the next batch (up to 5 seconds or 10 requests) are lost. The local log keeps them, but they never reach the workspace agent or coderd.
For short commands, which are the main Agent Firewall use case, every record is lost.
Loopalready drains and flushes when its context is canceled (TestSocketAuditor_Loop_FlushesOnContextCancel). Nothing triggered that path at exit.Change
SetupAuditornow also returns a close function. It cancels the loop and waits up to 5 seconds for the final drain and flush, so an unresponsive agent cannot block exit.context.WithoutCancel), so it still works when the caller's context is already canceled.runSocketAuditorhelper owns the goroutine and its done channel.SocketAuditoritself is unchanged.RunParentfunctionsdeferthe close. It runs afterRunhas stopped the proxy, so no audit events arrive after the final flush, and before the CLI exits.SetupAuditoris exported and its signature changes. The only callers are the two parents here; coder/coder does not call it.Testing
New tests:
TestSetupAuditor_CloseSendsQueuedLogs: a real unix-socket listener. One request is audited, then close is called; the log must already be on the socket when close returns.TestRunSocketAuditor_StopIsBoundedByContext: a dial that never returns; stop returnscontext.DeadlineExceededat the deadline, then nil once the agent responds.Both fail if close does not wait (checked with a temporary mutation), and both pass 20 times under
-race.End to end with landjail, following the issue's Variant B (a denied and an allowed request back to back, then exit). The agent socket is a small listener that prints every record it decodes:
The non-zero exit path (
sh -c '...; exit 3') behaves the same: main delivers 0 of 1 records, this branch 1 of 1, and the exit code is still 3. Wall time is 208ms vs 221ms.make unit-test: all packages pass, except the two live-network proxy tests that also fail onmain(dev.coder.comnow redirects). test(proxy): serve proxy test upstreams locally #213 fixes those.make fmt-check: passes.AI disclosure
I used Claude Code to trace the bug and draft the fix and tests. I reviewed the diff and ran the tests and the reproduction above myself.