[{"data":1,"prerenderedAt":668},["ShallowReactive",2],{"-docs-guide-data-handling":3,"-docs-guide-data-handling-surround":657},{"id":4,"title":5,"body":6,"description":647,"extension":648,"links":649,"meta":650,"navigation":651,"path":653,"seo":654,"stem":655,"__hash__":656},"docs\u002Fdocs\u002F2.guide\u002F6.data-handling.md","Data handling & privacy",{"type":7,"value":8,"toc":637},"minimark",[9,18,23,101,108,112,152,156,167,201,205,252,266,271,433,479,497,501,507,533,547,551,578,582,605,609,633],[10,11,12,13,17],"p",{},"TheSpider's differentiator versus cloud scanners: ",[14,15,16],"strong",{},"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.",[19,20,22],"h2",{"id":21},"see-what-leaves-the-machine","See what leaves the machine",[24,25,26,39],"table",{},[27,28,29],"thead",{},[30,31,32,36],"tr",{},[33,34,35],"th",{},"Data",[33,37,38],{},"Detail",[40,41,42,55,70,82,93],"tbody",{},[30,43,44,48],{},[45,46,47],"td",{},"Git metadata",[45,49,50,51,54],{},"branch, commit SHA, ",[14,52,53],{},"remote URL",", dirty flag",[30,56,57,63],{},[45,58,59],{},[60,61,62],"code",{},"changed_paths",[45,64,65,66,69],{},"file ",[14,67,68],{},"paths"," (not contents) for incremental \u002F PR scans",[30,71,72,75],{},[45,73,74],{},"Rendered prompt",[45,76,77,78,81],{},"the server-rendered ",[60,79,80],{},"prompt.md"," round-trips back on results (integrity echo)",[30,83,84,87],{},[45,85,86],{},"Raw model stdout",[45,88,89,90],{},"the findings block: ",[14,91,92],{},"titles, severities, confidence, evidence code excerpts, file paths + lines, exploit scenario, impact, recommendation, CWE\u002FCVSS",[30,94,95,98],{},[45,96,97],{},"stderr tail",[45,99,100],{},"a short tail for diagnostics",[10,102,103,104,107],{},"Storing findings-with-evidence ",[14,105,106],{},"is the product"," (as with Snyk\u002FSemgrep) — it is how triage, dedupe, cross-audit memory, and reporting work.",[19,109,111],{"id":110},"know-what-never-leaves-the-machine","Know what NEVER leaves the machine",[113,114,115,128,134],"ul",{},[116,117,118,119,122,123,127],"li",{},"The raw ",[14,120,121],{},"source tree \u002F full files"," — the model reads them locally; only the excerpts it ",[124,125,126],"em",{},"chooses to cite"," travel. Non-cited code never leaves.",[116,129,130,133],{},[14,131,132],{},"Local model credentials"," (API keys \u002F CLI auth) — used only by the local runner.",[116,135,136,139,140,143,144,147,148,151],{},[14,137,138],{},"Local absolute paths"," — ",[60,141,142],{},"target_path"," is normalized to ",[14,145,146],{},"repo-relative"," at the boundary, so usernames and directory layout (",[60,149,150],{},"\u002Fhome\u002F\u003Cuser>\u002F…",") never enter server state or the prompt bytes.",[19,153,155],{"id":154},"handle-the-sharp-edge-secrets-inside-evidence","Handle the sharp edge: secrets inside evidence",[10,157,158,159,162,163,166],{},"A secret-detection finding can ship the secret ",[124,160,161],{},"value"," inside its ",[60,164,165],{},"evidence",". Two layers guard this:",[168,169,170,184],"ol",{},[116,171,172,175,176,183],{},[14,173,174],{},"Server-side ingest scrubber — always on."," Every parsed finding runs through a pattern-based secret masker ",[14,177,178,179,182],{},"before any ",[60,180,181],{},"reports"," row is written and before fingerprinting",", so a secret value never reaches the database, the fingerprint, or the dedupe cache.",[116,185,186,193,194,196,197,200],{},[14,187,188,189,192],{},"Client ",[60,190,191],{},"--redact"," — opt-in."," The Rust agent's ",[60,195,191],{}," flag masks secret-shaped substrings and truncates stdout ",[124,198,199],{},"before upload"," — belt-and-braces for stricter shops.",[19,202,204],{"id":203},"set-retention","Set retention",[24,206,207,219],{},[27,208,209],{},[30,210,211,213,216],{},[33,212,35],{},[33,214,215],{},"SaaS default",[33,217,218],{},"On-prem",[40,220,221,235],{},[30,222,223,229,232],{},[45,224,225,226],{},"Parsed ",[14,227,228],{},"reports \u002F findings \u002F triage",[45,230,231],{},"kept indefinitely",[45,233,234],{},"customer-managed (your Postgres)",[30,236,237,243,249],{},[45,238,239,242],{},[14,240,241],{},"Slice artifacts"," (prompt\u002Foutput\u002Fstderr blobs)",[45,244,245,248],{},[14,246,247],{},"90 days"," via object-store lifecycle (per-plan override)",[45,250,251],{},"customer-managed",[10,253,254,255,258,259,261,262,265],{},"Artifacts are write-once, read-rarely ",[14,256,257],{},"provenance"," — the parsed content already lives in ",[60,260,181],{},", so expiring the blobs loses nothing load-bearing. They are ",[14,263,264],{},"content-addressed by sha256",", so identical blobs dedupe naturally.",[10,267,268],{},[14,269,270],{},"Lifecycle-rule recipe (S3\u002FR2\u002FMinIO), 90-day artifact expiry:",[272,273,282],"pre",{"className":274,"code":275,"filename":276,"highlights":277,"language":279,"meta":280,"style":281},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{ \"Rules\": [ {\n  \"ID\": \"expire-thespider-artifacts\",\n  \"Status\": \"Enabled\",\n  \"Filter\": { \"Prefix\": \"artifacts\u002F\" },\n  \"Expiration\": { \"Days\": 90 }\n} ] }\n","{ \"lifecycle.json\" }",[278],0,"json","[]","",[60,283,284,312,337,358,393,422],{"__ignoreMap":281},[285,286,289,293,296,300,303,306,309],"span",{"class":287,"line":288},"line",1,[285,290,292],{"class":291},"sMK4o","{",[285,294,295],{"class":291}," \"",[285,297,299],{"class":298},"spNyl","Rules",[285,301,302],{"class":291},"\"",[285,304,305],{"class":291},":",[285,307,308],{"class":291}," [",[285,310,311],{"class":291}," {\n",[285,313,315,318,322,324,326,328,332,334],{"class":287,"line":314},2,[285,316,317],{"class":291},"  \"",[285,319,321],{"class":320},"sBMFI","ID",[285,323,302],{"class":291},[285,325,305],{"class":291},[285,327,295],{"class":291},[285,329,331],{"class":330},"sfazB","expire-thespider-artifacts",[285,333,302],{"class":291},[285,335,336],{"class":291},",\n",[285,338,340,342,345,347,349,351,354,356],{"class":287,"line":339},3,[285,341,317],{"class":291},[285,343,344],{"class":320},"Status",[285,346,302],{"class":291},[285,348,305],{"class":291},[285,350,295],{"class":291},[285,352,353],{"class":330},"Enabled",[285,355,302],{"class":291},[285,357,336],{"class":291},[285,359,361,363,366,368,370,373,375,379,381,383,385,388,390],{"class":287,"line":360},4,[285,362,317],{"class":291},[285,364,365],{"class":320},"Filter",[285,367,302],{"class":291},[285,369,305],{"class":291},[285,371,372],{"class":291}," {",[285,374,295],{"class":291},[285,376,378],{"class":377},"sbssI","Prefix",[285,380,302],{"class":291},[285,382,305],{"class":291},[285,384,295],{"class":291},[285,386,387],{"class":330},"artifacts\u002F",[285,389,302],{"class":291},[285,391,392],{"class":291}," },\n",[285,394,396,398,401,403,405,407,409,412,414,416,419],{"class":287,"line":395},5,[285,397,317],{"class":291},[285,399,400],{"class":320},"Expiration",[285,402,302],{"class":291},[285,404,305],{"class":291},[285,406,372],{"class":291},[285,408,295],{"class":291},[285,410,411],{"class":377},"Days",[285,413,302],{"class":291},[285,415,305],{"class":291},[285,417,418],{"class":377}," 90",[285,420,421],{"class":291}," }\n",[285,423,425,428,431],{"class":287,"line":424},6,[285,426,427],{"class":291},"}",[285,429,430],{"class":291}," ]",[285,432,421],{"class":291},[272,434,438],{"className":435,"code":436,"language":437,"meta":281,"style":281},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","aws s3api put-bucket-lifecycle-configuration --bucket \u003Cbucket> --lifecycle-configuration file:\u002F\u002Flifecycle.json\n# MinIO: mc ilm rule add --expire-days 90 --prefix \"artifacts\u002F\" local\u002F\u003Cbucket>\n","bash",[60,439,440,473],{"__ignoreMap":281},[285,441,442,445,448,451,454,457,460,464,467,470],{"class":287,"line":288},[285,443,444],{"class":320},"aws",[285,446,447],{"class":330}," s3api",[285,449,450],{"class":330}," put-bucket-lifecycle-configuration",[285,452,453],{"class":330}," --bucket",[285,455,456],{"class":291}," \u003C",[285,458,459],{"class":330},"bucke",[285,461,463],{"class":462},"sTEyZ","t",[285,465,466],{"class":291},">",[285,468,469],{"class":330}," --lifecycle-configuration",[285,471,472],{"class":330}," file:\u002F\u002Flifecycle.json\n",[285,474,475],{"class":287,"line":314},[285,476,478],{"class":477},"sHwdD","# MinIO: mc ilm rule add --expire-days 90 --prefix \"artifacts\u002F\" local\u002F\u003Cbucket>\n",[10,480,481,482,485,486,489,490,492,493,496],{},"On-prem with the on-disk store: prune ",[60,483,484],{},"ARTIFACTS_DIR"," (default ",[60,487,488],{},"\u002Fdata\u002Fartifacts",") on your own schedule; ",[60,491,181],{},"\u002F",[60,494,495],{},"findings"," are unaffected.",[19,498,500],{"id":499},"rely-on-double-isolation","Rely on double isolation",[10,502,503,504,305],{},"Tenant isolation is enforced ",[14,505,506],{},"twice",[113,508,509,515],{},[116,510,511,514],{},[14,512,513],{},"Service-layer scoping"," — the first line; every query is project-scoped.",[116,516,517,520,521,524,525,528,529,532],{},[14,518,519],{},"Postgres RLS"," — the backstop. Every request runs inside a per-request transaction that sets ",[60,522,523],{},"app.current_org"," \u002F ",[60,526,527],{},"app.current_project"," and switches to a non-",[60,530,531],{},"BYPASSRLS"," role, so even a forgotten service-layer filter cannot leak across tenants.",[10,534,535,536,539,540,543,544,546],{},"On-prem is ",[14,537,538],{},"exactly one org"," (created at first boot) on ",[14,541,542],{},"your"," Postgres and ",[14,545,542],{}," object storage.",[19,548,550],{"id":549},"delete-data","Delete data",[113,552,553,559,565],{},[116,554,555,558],{},[14,556,557],{},"Per-finding \u002F per-project deletes"," cascade through foreign keys (findings → sightings, reports, triage history, fixes, false-positive records). Deleting a project removes its entire tree.",[116,560,561,564],{},[14,562,563],{},"Artifacts"," are removed by the object-store lifecycle rule above (or immediately by key).",[116,566,567,569,570,573,574,577],{},[14,568,218],{},": you hold the database and object store outright; a ",[60,571,572],{},"DROP"," \u002F bucket-empty removes everything. ",[14,575,576],{},"SaaS",": submit a deletion request for org-level erasure.",[19,579,581],{"id":580},"control-telemetry","Control telemetry",[10,583,584,585,588,589,592,593,596,597,600,601,604],{},"Telemetry is on by default in both modes; ",[60,586,587],{},"TELEMETRY=off"," turns it off entirely (air-gap safe). When on, it sends ",[14,590,591],{},"only"," ",[60,594,595],{},"{ version, deployment_mode, instance\u002Flicense id, usage rollups (counts), error counts }"," on a daily + boot cadence — and ",[14,598,599],{},"never"," any findings content (asserted in the test suite and in ",[60,602,603],{},"deploy\u002Fverify-onprem.sh",").",[19,606,608],{"id":607},"next-steps","Next steps",[113,610,611,619],{},[116,612,613,618],{},[614,615,617],"a",{"href":616},"\u002Fdocs\u002Fdeploy\u002Fdeployment-modes","Deployment modes"," — SaaS vs on-prem.",[116,620,621,139,625,628,629,632],{},[614,622,624],{"href":623},"\u002Fdocs\u002Freference\u002Fenv-vars","Environment reference",[60,626,627],{},"TELEMETRY",", ",[60,630,631],{},"LICENSE_*",", and friends.",[634,635,636],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":281,"searchDepth":314,"depth":314,"links":638},[639,640,641,642,643,644,645,646],{"id":21,"depth":314,"text":22},{"id":110,"depth":314,"text":111},{"id":154,"depth":314,"text":155},{"id":203,"depth":314,"text":204},{"id":499,"depth":314,"text":500},{"id":549,"depth":314,"text":550},{"id":580,"depth":314,"text":581},{"id":607,"depth":314,"text":608},"Exactly what crosses the machine boundary and how secrets are protected","md",null,{},{"icon":652},"i-lucide-shield-check","\u002Fdocs\u002Fguide\u002Fdata-handling",{"title":5,"description":647},"docs\u002F2.guide\u002F6.data-handling","0xPDhOHVjPrYhWbPqcUlbewCvfaIlQxPLHIwuEof6cY",[658,664],{"title":659,"path":660,"stem":661,"description":662,"icon":663,"children":-1},"PR gate","\u002Fdocs\u002Fguide\u002Fpr-gate","docs\u002F2.guide\u002F5.pr-gate","Gate pull requests without putting model runtime or secrets into CI","i-lucide-git-pull-request",{"title":617,"path":616,"stem":665,"description":666,"icon":667,"children":-1},"docs\u002F3.deploy\u002F1.deployment-modes","One Docker image runs as SaaS or on-prem — pick your mode","i-lucide-boxes",1783955419117]