Your scan data never leaves your network. Here is exactly what does.

Most security pages assert "we don't send your data." We list every request the binary can make, when it fires, what is inside it, and how to stop it, including the one that goes to a third party rather than to us. Read the ledger below, then verify it yourself with tcpdump.

What this tool protects against, and what it doesn't

Honest scope. The product is narrow on purpose: it finds PII in files you point it at, and it does that locally. It is not an EDR, a DLP suite, or a magic compliance button.

What we protect against
  • Your scan data being read or stored by a third-party SaaS provider
  • PII matches landing in cloud logs, search indices, or backups outside your control
  • A breach of Eligian Labs exposing your customers
  • Vendor lock-in or service deprecation cutting off your ability to scan
What is out of scope
  • Files written to disk by other software on the same machine
  • Operating-system-level keyloggers, rootkits, or compromised hardware
  • A malicious actor with shell access to the machine running PII Crawler
  • Network monitoring by your own infrastructure team (which you can configure)
Who you have to trust
  • Yourself: you choose what to scan and where the report lands
  • Your filesystem and OS, as with any tool that reads files
  • Eligian Labs to deliver a code-signed binary that does what this page says
  • Sentry, our error-tracking provider, if you leave crash reporting on. SENTRY_DSN="" removes them from the list
  • Not a SaaS. Not a cloud account. Not an API key.

Every request the binary can make

Four requests. Two of them only if you ask for them. None of them carry your scan data. The exact payloads are below.

Method Endpoint When Status
purpose

Starts email verification, so we can send you the link that unlocks the license.

note

Sent by piicrawler register, by the terminal UI's register screen, and by the web UI's. Form-encoded, not JSON. Nothing else in the product calls it.

skip it entirely
drop a license.lic file in ~/.piicrawler
Request body, application/x-www-form-urlencoded
email=you%40example.com
purpose

Collects the issued license once your email is verified, and activates the binary.

note

Not a single request: while it waits for you to click the link in the email, PII Crawler polls this endpoint every few seconds until the license comes back or you give up. The web UI's Refresh license button calls it again. The OS and CPU architecture are sent so we hand back a license for the build you are running.

skip it entirely
drop a license.lic file in ~/.piicrawler
Request body, application/x-www-form-urlencoded
email=you%40example.com
&product_id=piicrawler
&arch=x86_64
&os=linux
purpose

Tells piicrawler update whether a newer build exists. You decide whether to fetch it.

note

There is no background update check, no check at launch and no check from the UI: this request happens when, and only when, you run the update subcommand. A static JSON. No body sent, no cookies. If you then confirm the upgrade, a second GET fetches the archive named in url and its SHA-256 is checked against the sha256 here before anything is swapped in.

disable with
don't run `piicrawler update`
Response (no request body is sent), the live file as of today
{
"version": "210deec-1788631254-2026-09-05"
"build_date": "2026-09-05"
"sha256": "f0a8aca327cb16…"
"size": 67940246
"url": "https://downloads.eligian.com/piicrawler-cli-linux.tar.gz"
}
purpose

Helps fix crashes. Never sent on a run that finishes.

this one is a third party

Crash reports do not go to Eligian's own servers. They go to Sentry (Functional Software, Inc., United States), the error-tracking service we use, over the Sentry SDK's own protocol. If your policy requires that no telemetry leave for a third-party processor, turn it off with the variable below; everything else on this page is unaffected.

note

The payload is a Sentry event, and it carries more than the exception: the product version, the machine's hostname, the OS name, version and kernel version, the CPU architecture, and the on-disk path of the PII Crawler binary and of every shared library it had loaded, which on a normal install is a path under your home directory. An error message can name a file path too (the database file that would not open, say) and that path is sent as written. File contents, scan results and anything a scan matched are not put into error messages and are not sent.

disable with
SENTRY_DSN="" piicrawler …
A real event captured off the wire: abridged, nothing added
{
"platform": "native",
"release": "26.0905.2157",
"environment": "production",
"server_name": "alices-macbook.local",
"contexts": { os: Linux 7.1.3 / kernel …, device: x86_64, rust: 1.98.0 },
"exception": [
{ "type": "SqliteFailure", "value": "file is not a database" }
],
"debug_meta": { images: [
"/home/alice/.local/bin/piicrawler",
"/lib/x86_64-linux-gnu/libc.so.6", …
] }
}

That is the whole list. There is no analytics endpoint. Neither the CLI nor the web UI reports feature usage anywhere, and the web UI loads no third-party script. The one other address the binary can post to is the webhook you configure with piicrawler watch --webhook, which goes wherever you point it and carries the policy name, the file path and a masked value. If we ever add an endpoint, this page changes first.

A scan makes no calls at all

There is no --air-gapped flag, because scanning needs no flag: scan, report, export, findings, dsar and watch open no outbound connection. Two things have to be arranged once, and then the host can stay off the network for good.

license checkskipped with license.lic
update probenever runs unless you run update
error reportingoff with SENTRY_DSN=""
analyticsdoes not exist
Air-gapped setup
# 1. licence, with no round trip: put the file we issue you in place
$ mkdir -p ~/.piicrawler && cp license.lic ~/.piicrawler/
# 2. crash reporting off, for this shell and everything it starts
$ export SENTRY_DSN=""
# 3. scan. nothing else to switch off.
$ piicrawler scan ~/share --save
# prove it, in the same shell:
$ sudo tcpdump -n -i any 'not port 22' -c 1 & piicrawler scan ~/share
0 packets captured

Least privilege by default

PII Crawler runs as your user. It can only see what you can see. There is no service to start, nothing to add to sudoers.

What it has access to
  • Read access to the folders you point it at
  • Read access to the network shares and mailboxes you connect it to
  • Write access to the report directory you specify
What it does not touch
  • Root or administrator privileges
  • Access to system folders, /etc, registry, or keychain
  • Any network access at all while a scan runs
  • Access to any folder you didn't explicitly include
  • A persistent service or background daemon

The whole truth, in a grid

Every category of data, every endpoint. A dot marks something that is sent. A cross marks something that is never sent under any condition. The Analytics column is empty all the way down because there is no analytics endpoint; it is kept so the answer is on the record.

Data License Updates Errors Analytics
Email address (you provided) ●✗✗✗
Operating system & CPU arch ●✗●✗
Product version ●✗●✗
Exception message & stack trace ✗✗●✗
UI feature event namesa ✗✗✗✗
File contents ✗✗✗✗
Scan results / matches ✗✗✗✗
Discovered PII (SSN, names, addresses, emails…) ✗✗✗✗
File paths and filenamesb ✗✗●✗
Hostname or machine name ✗✗●✗
Username / loginc ✗✗●✗
Local IP addressesd ✗✗✗✗
Saved share or mailbox passwords ✗✗✗✗
Folder structure of scanned shares ✗✗✗✗
●sent under the conditions on this page ✗never sent under any condition

a. PII Crawler has no analytics endpoint at all. The column exists only so the row can say so.
b. A crash report carries the on-disk path of the PII Crawler binary and of every shared library it had loaded, and an error message can name a file the product itself was opening: its own database, a log file, a licence file. No path of a file you scanned is put into an error message.
c. Only as part of those paths: on a normal install they sit under your home directory, and a home directory is usually named after the account.
d. Nothing in the binary reads or attaches an IP address. Any server you connect to necessarily observes the address you connect from; that is true of the four requests above and of every other program on the machine.

Don't trust this page. Test it.

Four concrete checks any sysadmin can run. None take more than a few minutes, and the fourth one shows you a crash report before it is sent.

01

Run it behind a firewall

Block egress from the host, then scan. Registration is the only thing that needs the network, and a license.lic covers that; the scan itself never tries.

iptables -A OUTPUT -m owner --uid-owner piicrawler -j DROP
02

Listen with tcpdump

Capture every interface while a scan runs and inspect the pcap. There is nothing to find.

sudo tcpdump -i any -n -w scan.pcap & piicrawler scan ~/share
03

Fingerprint your download

The SHA-256 of every published build is in the same manifest piicrawler update reads, and update checks it before swapping anything in. Compare it against the file you downloaded.

curl -s https://downloads.eligian.com/piicrawler-cli-linux.json | grep sha256; sha256sum piicrawler-cli-linux.tar.gz
04

Read a crash report yourself

Crash reports go wherever SENTRY_DSN points. Point it at a listener of your own and you see the exact bytes we would have received. That is how the payload above was captured.

SENTRY_DSN=http://[email protected]:9911/1 piicrawler serve

Signed where the platform signs. Hashed everywhere.

macOS and Windows builds carry a platform signature you can check with the platform's own tool. The Linux tarball has no detached GPG signature. Its check is the SHA-256 published in the same manifest piicrawler update reads, and that is the hash update itself verifies before it swaps a binary in.

PlatformArtifactSignatureVerify it with
macOS .app in a .zip Developer ID
Signed with an Eligian Labs Developer ID certificate, submitted to Apple for notarization, and stapled.
codesign --verify --strict --verbose=2 /Applications/PIICrawler.app
Windows .exe, .msi Authenticode
Both executables and the installer are signed through Azure Trusted Signing.
signtool verify /pa /v piicrawler.exe
Linux .tar.gz SHA-256 only
No detached signature is published. Compare the hash against the platform manifest.
curl -s https://downloads.eligian.com/piicrawler-cli-linux.json | grep sha256

Find a bug? Tell us

Email the security team directly. We respond within 48 hours, work the fix with you privately, and credit you in the release notes if you'd like.

SLA
48h
initial response
7d
triage & impact assessment
30d
fix or compensating control
90d
public disclosure (with credit)