Data handling & privacy

Exactly what crosses the machine boundary and how secrets are protected

TheSpider's differentiator versus cloud scanners: your source code stays on your machine; only findings sync. Models run locally under your own credentials against your local checkout; only the findings the model chose to report — with the evidence it chose to cite — travel to the server.

See what leaves the machine

DataDetail
Git metadatabranch, commit SHA, remote URL, dirty flag
changed_pathsfile paths (not contents) for incremental / PR scans
Rendered promptthe server-rendered prompt.md round-trips back on results (integrity echo)
Raw model stdoutthe findings block: titles, severities, confidence, evidence code excerpts, file paths + lines, exploit scenario, impact, recommendation, CWE/CVSS
stderr taila short tail for diagnostics

Storing findings-with-evidence is the product (as with Snyk/Semgrep) — it is how triage, dedupe, cross-audit memory, and reporting work.

Know what NEVER leaves the machine

  • The raw source tree / full files — the model reads them locally; only the excerpts it chooses to cite travel. Non-cited code never leaves.
  • Local model credentials (API keys / CLI auth) — used only by the local runner.
  • Local absolute pathstarget_path is normalized to repo-relative at the boundary, so usernames and directory layout (/home/<user>/…) never enter server state or the prompt bytes.

Handle the sharp edge: secrets inside evidence

A secret-detection finding can ship the secret value inside its evidence. Two layers guard this:

  1. Server-side ingest scrubber — always on. Every parsed finding runs through a pattern-based secret masker before any reports row is written and before fingerprinting, so a secret value never reaches the database, the fingerprint, or the dedupe cache.
  2. Client --redact — opt-in. The Rust agent's --redact flag masks secret-shaped substrings and truncates stdout before upload — belt-and-braces for stricter shops.

Set retention

DataSaaS defaultOn-prem
Parsed reports / findings / triagekept indefinitelycustomer-managed (your Postgres)
Slice artifacts (prompt/output/stderr blobs)90 days via object-store lifecycle (per-plan override)customer-managed

Artifacts are write-once, read-rarely provenance — the parsed content already lives in reports, so expiring the blobs loses nothing load-bearing. They are content-addressed by sha256, so identical blobs dedupe naturally.

Lifecycle-rule recipe (S3/R2/MinIO), 90-day artifact expiry:

{ "lifecycle.json" }
{ "Rules": [ {
  "ID": "expire-thespider-artifacts",
  "Status": "Enabled",
  "Filter": { "Prefix": "artifacts/" },
  "Expiration": { "Days": 90 }
} ] }
aws s3api put-bucket-lifecycle-configuration --bucket <bucket> --lifecycle-configuration file://lifecycle.json
# MinIO: mc ilm rule add --expire-days 90 --prefix "artifacts/" local/<bucket>

On-prem with the on-disk store: prune ARTIFACTS_DIR (default /data/artifacts) on your own schedule; reports/findings are unaffected.

Rely on double isolation

Tenant isolation is enforced twice:

  • Service-layer scoping — the first line; every query is project-scoped.
  • Postgres RLS — the backstop. Every request runs inside a per-request transaction that sets app.current_org / app.current_project and switches to a non-BYPASSRLS role, so even a forgotten service-layer filter cannot leak across tenants.

On-prem is exactly one org (created at first boot) on your Postgres and your object storage.

Delete data

  • Per-finding / per-project deletes cascade through foreign keys (findings → sightings, reports, triage history, fixes, false-positive records). Deleting a project removes its entire tree.
  • Artifacts are removed by the object-store lifecycle rule above (or immediately by key).
  • On-prem: you hold the database and object store outright; a DROP / bucket-empty removes everything. SaaS: submit a deletion request for org-level erasure.

Control telemetry

Telemetry is on by default in both modes; TELEMETRY=off turns it off entirely (air-gap safe). When on, it sends only { version, deployment_mode, instance/license id, usage rollups (counts), error counts } on a daily + boot cadence — and never any findings content (asserted in the test suite and in deploy/verify-onprem.sh).

Next steps