Skip to main content
The question: did any file under /data/sensitive leave this machine, and if so, who sent it and to where? Filetrace is built for exactly this. A file is named at the moment its bytes reach a socket, so the answer includes the process, the destination and the method, not just a byte count.

1. Ask for the files

--path matches the whole path, and * crosses /, so this covers the subdirectories too. The result is most-recently-active first; --sort bytes puts the largest first.
Read the rows:
  • The first line is a Python process that read a spreadsheet and then sent it: INFERRED, with the script that did it. That is the shape of an application upload.
  • The second line is sendfile and EXACT: the kernel handed the file to the socket directly. A command-line tool sent a private key.

2. Narrow with the filters that matter

--remote selects a network to include; there is no negation. To find traffic outside a known network, list the transfers with --remote omitted and compare the DESTINATION column against the allow-list, or keep an alert on the file-egress rate in the metrics layer (below).

3. Follow a hit with inspect

When one file matters, ask about the file itself:
The report shows every process that sent it, every address it went to, the totals, the methods, and the confidence of each association. From a process, inspect process <pid> shows everything that process is sending now. From an address, inspect ip 203.0.113.25 --since 24h shows which processes talk to it and which files were sent there.

4. Watch for new sends

watch ranks transfers by current rate, so a large upload stands out while it is happening. Add --file '/data/sensitive/*' to see only the files you care about, or --direction outbound on a busy server.

5. Alert on it

The observability recipes include ready-to-use rules. The two that fit here:
  • FiletraceLargeFileTransfer fires when one process sends more than 1 GB in five minutes.
  • FiletraceUnattributedEgress fires when most egress has no file behind it, which is worth checking when uploads are the concern.

6. Keep the record

For an audit trail that outlives the agent, export the file_transfer log records to a collector. Each record carries the path, the process, the script, the peer address and the bytes:
If the backend must not hold paths, set file_paths = false; the record keeps the device and inode, which still identify the file for an investigator with access to the host.

Where the answer can mislead

  • INFERRED is not proof. A thread read the file and then sent bytes on a socket; the bytes cannot be proven to come only from that file. Treat it as strong evidence and corroborate with the script and the destination.
  • Bytes counted are what the local socket accepted, not what the remote end acknowledged. A send that fails mid-way still shows the bytes the kernel accepted.
  • Loss hides transfers. Check filetrace_events_dropped_total and the * marker. With loss, a file can be missing from the list entirely.
  • History is in memory. After an agent restart, past transfers are gone. Use OTLP or the metrics for anything that must persist.
  • Encrypted or generated payloads read from memory have no file behind them and appear in transfers as UNKNOWN, not in files. Look at filetrace transfers --include-unknown too.