Repository navigation
File DLP uploads, phase 1: the upload inspection proxy (#344) - #373
Merged
Merged
Conversation
Uploads go with option C (#335): a local TLS-inspecting proxy. This is phase 1 from #344, the explicit proxy: a client pointed at it has its uploads to the hosts in scope decrypted and each uploaded file decided by the file policies (channel file.upload); everything else is tunnelled untouched. No OS redirect yet, and the service doesn't run it. - uploadproxy.CA: a per-device ECDSA CA, its key a root-only file written atomically, never leaving the device; renewed before expiry; MaxPathLenZero. 24-hour host certificates, cached. - uploadproxy.Proxy: CONNECT (HTTP/1.1 and HTTP/2 to the client and the server) and plain-HTTP proxying. Servers are verified with the system roots (a test forbids InsecureSkipVerify). It never chains to an environment proxy. A request on an intercepted connection can't be steered to another host (400). HostScope lists hosts and *.subdomains on 443/80. - uploadproxy.Inspector: the body goes to a root-only spill file up to max_file_bytes (taken from the same policy the scanner uses). Multipart file parts are decided one by one and plain fields together, other bodies whole, and the request is forwarded byte for byte. A body over the limit is decided as too large and the rest streams on unread. Scanning is by the sandboxed workers (the proxy only splits multipart parts). - filedlp.Decider.Decide returns a verdict. It blocks only when the hook can (the Linux monitor can't), the module isn't audit-only, and a matching policy says block (or on_unscannable/on_timeout do). The event action is then blocked; the user sees the block message with detector ids, never matches. Uploads skip the verdict cache (spill inodes are reused). Events carry destination.host. - sentinelgo dlp proxy -hosts …: runs it by hand for testing (loopback only, -ca-out to export the CA, events as JSON lines). Refs #344 #335 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
neamul602
enabled auto-merge
November 2, 2026 10:40
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the
|
Windows has no Unix modes, so the CA key file was readable by anyone the config directory let in (CI caught it: -rw-rw-rw-). The key's temp file now gets winsec's ACL (SYSTEM, Administrators, the service's account) before the key is written, and creating the CA fails if it can't be restricted. The spill directory gets the same ACL, inherited by its files. Mode checks in the tests are Unix-only; winsec has its own tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
This was referenced Nov 2, 2026
Merged
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.




Uploads go with option C, a local TLS-inspecting proxy (decision on #335, go-ahead on #344 from @Warhammer4000). This is phase 1 from #344: the explicit proxy. A client pointed at it has its uploads to the hosts in scope decrypted, and each uploaded file is decided by the file policies on channel
file.upload. Everything else is tunnelled untouched. No OS redirect yet, and the service doesn't run it. It runs by hand withsentinelgo dlp proxy.Design
uploadproxy/ca.go):MaxPathLenZero: it can sign host certificates only;proxy.go):InsecureSkipVerifyis forbidden by a test, and an untrusted server gets nothing (502).HostScopetakes exact hosts and*.subdomains, on 443/80 only.inspect.go):max_file_bytes(the same limit the scanner applies).on_unscannable,allowby default), and the rest streams on unread.filedlp.Decider.Decide):block(oron_unscannable/on_timeoutsayblock).blocked, and the client gets HTTP 403 with the block message, naming detector ids, never matches.destination.host, never the URL.sentinelgo dlp proxy -hosts H1,*.h2 [-listen 127.0.0.1:3129] [-ca-out FILE]: loopback only (it refuses other addresses); empties the spill directory at start; prints events as JSON lines. As root on Linux it scans in the sandboxed workers; otherwise in-process, with a warning (a manual tool, never the service).Not in this phase
Test plan
blocked, host, file name) is right;monitoredevent;on_unscannable: block;0600, reloaded, renewed near expiry, and an unreadable CA is rejected; host certificates verify, are cached, and IP hosts work.Decideblocks only when it may (hook can't block, audit-only, monitor action, fail modes); block message.curlthrough it:example.com(in scope) got 403 and never left the machine;example.comgot 200 with its real certificate verified;sentinelgo-scan, and no spill files were left.make verify-crossand the changelog check pass.Refs #344 #335
🤖 Generated with Claude Code