maisecrets menu

maisecrets / Why you can trust it

Why you can trust it

High-precision detection of personal data. No language model required. On four labelled datasets, maisecrets 0.8.6 made the fewest wrong masks of four open-source tools, and it had a higher F1 than Preserve on all four. It finds a name after a label, or when you put the name on a term list. Tools with a language model find more names. The charts show both sides.

Personal data: precision, recall and F1 against three tools

Four open-source tools on the same documents of four labelled datasets: maisecrets on 31 October 2026, the other tools on 21 October 2026. No maisecrets rule was written from these documents. The tools work in different ways:

  • maisecrets 0.8.6: rules and labels, and the names on your term list. No language model, no name dictionary.
  • Preserve: rules plus a name dictionary and word frequencies (default configuration, no model).
  • pii-anon: regular expressions only (the regex-oss engine).
  • Presidio: rules plus the spaCy language model en_core_web_lg (NER).

maisecrets made the fewest wrong masks on every dataset. Presidio found more personal data on three of them. Most of that difference is names: 74 to 92 % of the values that maisecrets missed are names. maisecrets ships no language model.

Precision against recall: maisecrets has the highest precision on every dataset; with its opt-in NER, it finds the most and has the best F1

Higher: fewer wrong masks. Further right: more values found. The dashed curves join points of equal F1. Benchmark V3, maisecrets 0.8.6 with and without NER on 31 October 2026, the other tools on 21 October 2026.

Choose a dataset
Precision against recall: maisecrets has the highest precision on every dataset; with its opt-in NER, it finds the most and has the best F1: Nemotron Nemotron, Nemotron-PII, 834 documents, 2,781 values. Presidio (RULES + LANGUAGE MODEL): recall 72.2 %, precision 92.8 %, F1 0.812; Preserve (RULES + NAME DICTIONARY): recall 66.0 %, precision 82.5 %, F1 0.733; pii-anon (REGEX): recall 76.6 %, precision 29.7 %, F1 0.428; maisecrets (RULES): recall 61.7 %, precision 99.6 %, F1 0.762; maisecrets + NER (RULES + NER (OPT-IN)): recall 85.9 %, precision 99.3 %, F1 0.921. 0 0 25 25 50 50 75 75 100 100 F1 0.2 F1 0.4 F1 0.6 F1 0.8 Found (recall, %): more values masked whole → Right when flagged (precision, %) → PresidioR 72.2 % · P 92.8 % PreserveR 66.0 % · P 82.5 % pii-anonR 76.6 % · P 29.7 % maisecretsR 61.7 % · P 99.6 % maisecrets + NERR 85.9 % · P 99.3 % Precision against recall: maisecrets has the highest precision on every dataset; with its opt-in NER, it finds the most and has the best F1: Nemotron 0 0 25 25 50 50 75 75 100 100 F1 0.2 F1 0.4 F1 0.6 F1 0.8 Found (recall, %): more values masked whole → Right when flagged (precision, %) → PresidioR 72.2 %P 92.8 % PreserveR 66.0 %P 82.5 % pii-anonR 76.6 %P 29.7 % maisecretsR 61.7 %P 99.6 % maisecrets + NERR 85.9 %P 99.3 %
Precision against recall: maisecrets has the highest precision on every dataset; with its opt-in NER, it finds the most and has the best F1: Mendeley Mendeley, Mendeley financial, 362 documents, 2,084 values. Presidio (RULES + LANGUAGE MODEL): recall 67.7 %, precision 89.5 %, F1 0.771; Preserve (RULES + NAME DICTIONARY): recall 66.6 %, precision 81.3 %, F1 0.732; pii-anon (REGEX): recall 61.0 %, precision 65.8 %, F1 0.633; maisecrets (RULES): recall 70.6 %, precision 98.8 %, F1 0.824; maisecrets + NER (RULES + NER (OPT-IN)): recall 93.7 %, precision 86.3 %, F1 0.899. 0 0 25 25 50 50 75 75 100 100 F1 0.2 F1 0.4 F1 0.6 F1 0.8 Found (recall, %): more values masked whole → Right when flagged (precision, %) → PresidioR 67.7 % · P 89.5 % PreserveR 66.6 % · P 81.3 % pii-anonR 61.0 % · P 65.8 % maisecretsR 70.6 % · P 98.8 % maisecrets + NERR 93.7 % · P 86.3 % Precision against recall: maisecrets has the highest precision on every dataset; with its opt-in NER, it finds the most and has the best F1: Mendeley 0 0 25 25 50 50 75 75 100 100 F1 0.2 F1 0.4 F1 0.6 F1 0.8 Found (recall, %): more values masked whole → Right when flagged (precision, %) → PresidioR 67.7 %P 89.5 % PreserveR 66.6 %P 81.3 % pii-anonR 61.0 %P 65.8 % maisecretsR 70.6 %P 98.8 % maisecrets + NERR 93.7 %P 86.3 %
Precision against recall: maisecrets has the highest precision on every dataset; with its opt-in NER, it finds the most and has the best F1: Gretel Gretel, Gretel finance, 334 documents, 1,141 values. Presidio (RULES + LANGUAGE MODEL): recall 45.3 %, precision 27.3 %, F1 0.340; Preserve (RULES + NAME DICTIONARY): recall 41.6 %, precision 24.6 %, F1 0.309; pii-anon (REGEX): recall 42.9 %, precision 27.7 %, F1 0.337; maisecrets (RULES): recall 31.2 %, precision 90.4 %, F1 0.464; maisecrets + NER (RULES + NER (OPT-IN)): recall 51.3 %, precision 91.8 %, F1 0.658. 0 0 25 25 50 50 75 75 100 100 F1 0.2 F1 0.4 F1 0.6 F1 0.8 Found (recall, %): more values masked whole → Right when flagged (precision, %) → PresidioR 45.3 % · P 27.3 % PreserveR 41.6 % · P 24.6 % pii-anonR 42.9 % · P 27.7 % maisecretsR 31.2 % · P 90.4 % maisecrets + NERR 51.3 % · P 91.8 % Precision against recall: maisecrets has the highest precision on every dataset; with its opt-in NER, it finds the most and has the best F1: Gretel 0 0 25 25 50 50 75 75 100 100 F1 0.2 F1 0.4 F1 0.6 F1 0.8 Found (recall, %): more values masked whole → Right when flagged (precision, %) → PresidioR 45.3 %P 27.3 % PreserveR 41.6 %P 24.6 % pii-anonR 42.9 %P 27.7 % maisecretsR 31.2 %P 90.4 % maisecrets + NERR 51.3 %P 91.8 %
Precision against recall: maisecrets has the highest precision on every dataset; with its opt-in NER, it finds the most and has the best F1: Privy Privy, Privy, 2,816 documents, 1,076 values. Presidio (RULES + LANGUAGE MODEL): recall 47.3 %, precision 52.7 %, F1 0.498; Preserve (RULES + NAME DICTIONARY): recall 20.5 %, precision 41.5 %, F1 0.275; pii-anon (REGEX): recall 28.6 %, precision 93.6 %, F1 0.438; maisecrets (RULES): recall 23.7 %, precision 99.2 %, F1 0.383; maisecrets + NER (RULES + NER (OPT-IN)): recall 66.4 %, precision 93.5 %, F1 0.776. 0 0 25 25 50 50 75 75 100 100 F1 0.2 F1 0.4 F1 0.6 F1 0.8 Found (recall, %): more values masked whole → Right when flagged (precision, %) → PresidioR 47.3 % · P 52.7 % PreserveR 20.5 % · P 41.5 % pii-anonR 28.6 % · P 93.6 % maisecretsR 23.7 % · P 99.2 % maisecrets + NERR 66.4 % · P 93.5 % Precision against recall: maisecrets has the highest precision on every dataset; with its opt-in NER, it finds the most and has the best F1: Privy 0 0 25 25 50 50 75 75 100 100 F1 0.2 F1 0.4 F1 0.6 F1 0.8 Found (recall, %): more values masked whole → Right when flagged (precision, %) → PresidioR 47.3 %P 52.7 % PreserveR 20.5 %P 41.5 % pii-anonR 28.6 %P 93.6 % maisecretsR 23.7 %P 99.2 % maisecrets + NERR 66.4 %P 93.5 %

What to notice: maisecrets (orange) has the highest precision on every dataset, so its masks are wrong least often. Without NER it is further left than other tools on three datasets, because it finds fewer names.

With the opt-in NER service (blue), maisecrets finds the most and has the best F1 on every dataset. Its precision falls on Mendeley to 86.3 %, below Presidio, and on Privy it ties with pii-anon. The NER point: 31 October 2026, the image mcpgate/ner:v2.0.3573 on the same samples.

Source: Benchmark V3, bench/results/2026-10-31-v3-0.8.6 and bench/results/2026-10-21-v3/run (tag v0.8.6)
The numbers of this chart
DatasetToolHow it finds personal dataFound (recall)Right when flagged (precision)False alarmsF1
NemotronPresidiorules + language model72.2 %92.8 %1730.812
NemotronPreserverules + name dictionary66.0 %82.5 %3560.733
Nemotronpii-anonregex76.6 %29.7 %4,4370.428
Nemotronmaisecretsrules61.7 %99.6 %70.762
Nemotronmaisecrets + NERrules + ner (opt-in)85.9 %99.3 %140.921
MendeleyPresidiorules + language model67.7 %89.5 %3970.771
MendeleyPreserverules + name dictionary66.6 %81.3 %3800.732
Mendeleypii-anonregex61.0 %65.8 %1,0890.633
Mendeleymaisecretsrules70.6 %98.8 %180.824
Mendeleymaisecrets + NERrules + ner (opt-in)93.7 %86.3 %3150.899
GretelPresidiorules + language model45.3 %27.3 %2,3980.340
GretelPreserverules + name dictionary41.6 %24.6 %2,4610.309
Gretelpii-anonregex42.9 %27.7 %2,0120.337
Gretelmaisecretsrules31.2 %90.4 %390.464
Gretelmaisecrets + NERrules + ner (opt-in)51.3 %91.8 %640.658
PrivyPresidiorules + language model47.3 %52.7 %1,0600.498
PrivyPreserverules + name dictionary20.5 %41.5 %3500.275
Privypii-anonregex28.6 %93.6 %220.438
Privymaisecretsrules23.7 %99.2 %20.383
Privymaisecrets + NERrules + ner (opt-in)66.4 %93.5 %510.776

Names and the other personal data, counted apart. The table below splits the same V3 runs after the fact. The documents and the findings of each tool stay the same; only the count of found values is split by kind. It is a post-hoc analysis, not a separate benchmark. It shows two things. First, names explain a large part of the low overall recall of maisecrets: it finds 5 to 31 % of the names. Second, maisecrets also misses other personal data. On Gretel it finds only 56 % of the values that are not names, and most of these misses are postal addresses. Without names, maisecrets has the highest recall on 3 of the four datasets. On Privy, Presidio finds more: 97 % against 76 %.

Found, split into names and the rest (Benchmark V3, maisecrets 0.8.6)A post-hoc split of the same runs, not a separate benchmark: the same documents and the same findings, only the count is split by kind.
ToolOverall, %Names, %Not names, %
Nemotron834 documents, 2,781 values
Nemotron: PresidioPreservepii-anonmaisecrets+ NER Presidio: 72.2 Preserve: 66.0 pii-anon: 76.6 maisecrets: 61.7 + NER: 85.9 (highest) Presidio: 86.0 Preserve: 64.1 pii-anon: 78.7 maisecrets: 31.5 + NER: 89.1 (highest) Presidio: 62.4 Preserve: 67.4 pii-anon: 75.1 maisecrets: 83.3 + NER: 83.6 (highest)
Mendeley362 documents, 2,084 values
Mendeley: PresidioPreservepii-anonmaisecrets+ NER Presidio: 67.7 Preserve: 66.6 pii-anon: 61.0 maisecrets: 70.6 + NER: 93.7 (highest) Presidio: 95.7 Preserve: 45.7 pii-anon: 98.1 (highest) maisecrets: 19.9 + NER: 95.9 Presidio: 55.4 Preserve: 75.7 pii-anon: 44.8 maisecrets: 92.8 (highest) + NER: 92.8 (highest)
Gretel334 documents, 1,141 values
Gretel: PresidioPreservepii-anonmaisecrets+ NER Presidio: 45.3 Preserve: 41.6 pii-anon: 42.9 maisecrets: 31.2 + NER: 51.3 (highest) Presidio: 50.9 (highest) Preserve: 44.0 pii-anon: 45.2 maisecrets: 13.6 + NER: 47.9 Presidio: 37.4 Preserve: 38.3 pii-anon: 39.7 maisecrets: 56.0 (highest) + NER: 56.0 (highest)
Privy2,816 documents, 1,076 values
Privy: PresidioPreservepii-anonmaisecrets+ NER Presidio: 47.3 Preserve: 20.5 pii-anon: 28.6 maisecrets: 23.7 + NER: 66.4 (highest) Presidio: 29.8 Preserve: 18.3 pii-anon: 26.1 maisecrets: 5.2 + NER: 62.8 (highest) Presidio: 97.1 (highest) Preserve: 26.8 pii-anon: 35.7 maisecrets: 76.4 + NER: 76.4

Bold: the highest value of a column within a dataset.

+ NER (blue): maisecrets with the opt-in NER service, the same samples. It finds far more names; the rest stays almost the same.

Overall is the recall of the charts above and below. Names: values labelled as the name of a person. Not names: every other labelled kind, addresses and user names included. Wrong masks cannot be split this way, because the result files do not store the kind of a wrong mask. Precision stays one value for all personal data.

The counts of this table
DatasetToolOverall: found / labelledNames: found / labelledNot names: found / labelled
NemotronPresidio2,009 / 2,781997 / 1,1591,012 / 1,622
NemotronPreserve1,836 / 2,781743 / 1,1591,093 / 1,622
Nemotronpii-anon2,130 / 2,781912 / 1,1591,218 / 1,622
Nemotronmaisecrets1,716 / 2,781365 / 1,1591,351 / 1,622
Nemotron+ NER2,389 / 2,7811,033 / 1,1591,356 / 1,622
MendeleyPresidio1,410 / 2,084606 / 633804 / 1,451
MendeleyPreserve1,388 / 2,084289 / 6331,099 / 1,451
Mendeleypii-anon1,271 / 2,084621 / 633650 / 1,451
Mendeleymaisecrets1,472 / 2,084126 / 6331,346 / 1,451
Mendeley+ NER1,953 / 2,084607 / 6331,346 / 1,451
GretelPresidio517 / 1,141340 / 668177 / 473
GretelPreserve475 / 1,141294 / 668181 / 473
Gretelpii-anon490 / 1,141302 / 668188 / 473
Gretelmaisecrets356 / 1,14191 / 668265 / 473
Gretel+ NER585 / 1,141320 / 668265 / 473
PrivyPresidio509 / 1,076237 / 796272 / 280
PrivyPreserve221 / 1,076146 / 79675 / 280
Privypii-anon308 / 1,076208 / 796100 / 280
Privymaisecrets255 / 1,07641 / 796214 / 280
Privy+ NER714 / 1,076500 / 796214 / 280

The same results as bars, with the count of wrong masks for each tool:

Personal data: fewest wrong masks on all four datasets; with the opt-in NER, maisecrets finds the most Same documents per dataset, data no maisecrets rule was written from: maisecrets on 31 October 2026, the other tools on 21 October 2026. Both scales run from 0 to 100. Nemotron-PII · 834 documents, 2,781 values: Presidio 2.2.364 (RULES + LANGUAGE MODEL) Found 72.2 %, Wrong of 100 7.2 (173); Preserve 0.6.1 (RULES + NAME DICTIONARY) Found 66.0 %, Wrong of 100 17.5 (356); pii-anon 1.7.0rc1 (REGEX) Found 76.6 %, Wrong of 100 70.3 (4,437); maisecrets 0.8.6 (RULES) Found 61.7 %, Wrong of 100 0.4 (7); maisecrets 0.8.6 + NER (RULES + NER (OPT-IN)) Found 85.9 %, Wrong of 100 0.7 (14). Mendeley financial · 362 documents, 2,084 values: Presidio 2.2.364 (RULES + LANGUAGE MODEL) Found 67.7 %, Wrong of 100 10.5 (397); Preserve 0.6.1 (RULES + NAME DICTIONARY) Found 66.6 %, Wrong of 100 18.7 (380); pii-anon 1.7.0rc1 (REGEX) Found 61.0 %, Wrong of 100 34.2 (1,089); maisecrets 0.8.6 (RULES) Found 70.6 %, Wrong of 100 1.2 (18); maisecrets 0.8.6 + NER (RULES + NER (OPT-IN)) Found 93.7 %, Wrong of 100 13.7 (315). Gretel finance · 334 documents, 1,141 values: Presidio 2.2.364 (RULES + LANGUAGE MODEL) Found 45.3 %, Wrong of 100 72.7 (2,398); Preserve 0.6.1 (RULES + NAME DICTIONARY) Found 41.6 %, Wrong of 100 75.4 (2,461); pii-anon 1.7.0rc1 (REGEX) Found 42.9 %, Wrong of 100 72.3 (2,012); maisecrets 0.8.6 (RULES) Found 31.2 %, Wrong of 100 9.6 (39); maisecrets 0.8.6 + NER (RULES + NER (OPT-IN)) Found 51.3 %, Wrong of 100 8.2 (64). Privy · 2,816 documents, 1,076 values: Presidio 2.2.364 (RULES + LANGUAGE MODEL) Found 47.3 %, Wrong of 100 47.3 (1,060); Preserve 0.6.1 (RULES + NAME DICTIONARY) Found 20.5 %, Wrong of 100 58.5 (350); pii-anon 1.7.0rc1 (REGEX) Found 28.6 %, Wrong of 100 6.4 (22); maisecrets 0.8.6 (RULES) Found 23.7 %, Wrong of 100 0.8 (2); maisecrets 0.8.6 + NER (RULES + NER (OPT-IN)) Found 66.4 %, Wrong of 100 6.5 (51) Personal data: fewest wrong masks on all four datasets; with theopt-in NER, maisecrets finds the most Same documents per dataset, data no maisecrets rule was written from: maisecrets on 31 October 2026, theother tools on 21 October 2026. Both scales run from 0 to 100. Found: labelled values maskedwholeOf 100 things flagged, how manywere wrong? Nemotron-PII · 834 documents, 2,781 values Presidio 2.2.364 RULES + LANGUAGE MODEL 72.2 % 7.2 (173) Preserve 0.6.1 RULES + NAME DICTIONARY 66.0 % 17.5 (356) pii-anon 1.7.0rc1 REGEX 76.6 % 70.3 (4,437) maisecrets 0.8.6 RULES 61.7 % 0.4 (7) maisecrets 0.8.6 + NER RULES + NER (OPT-IN) 85.9 % 0.7 (14) Mendeley financial · 362 documents, 2,084 values Presidio 2.2.364 RULES + LANGUAGE MODEL 67.7 % 10.5 (397) Preserve 0.6.1 RULES + NAME DICTIONARY 66.6 % 18.7 (380) pii-anon 1.7.0rc1 REGEX 61.0 % 34.2 (1,089) maisecrets 0.8.6 RULES 70.6 % 1.2 (18) maisecrets 0.8.6 + NER RULES + NER (OPT-IN) 93.7 % 13.7 (315) Gretel finance · 334 documents, 1,141 values Presidio 2.2.364 RULES + LANGUAGE MODEL 45.3 % 72.7 (2,398) Preserve 0.6.1 RULES + NAME DICTIONARY 41.6 % 75.4 (2,461) pii-anon 1.7.0rc1 REGEX 42.9 % 72.3 (2,012) maisecrets 0.8.6 RULES 31.2 % 9.6 (39) maisecrets 0.8.6 + NER RULES + NER (OPT-IN) 51.3 % 8.2 (64) Privy · 2,816 documents, 1,076 values Presidio 2.2.364 RULES + LANGUAGE MODEL 47.3 % 47.3 (1,060) Preserve 0.6.1 RULES + NAME DICTIONARY 20.5 % 58.5 (350) pii-anon 1.7.0rc1 REGEX 28.6 % 6.4 (22) maisecrets 0.8.6 RULES 23.7 % 0.8 (2) maisecrets 0.8.6 + NER RULES + NER (OPT-IN) 66.4 % 6.5 (51) In brackets: the number of wrong masks. These counts depend on the size of each dataset and do not compareacross datasets.maisecrets + NER (blue): the same samples with the opt-in NER service, on 31 October 2026. It finds the most onevery dataset. It makes more wrong masks than maisecrets alone; on Gretel, a smaller share of what it flags iswrong.Each dataset labels other kinds of personal data, so a "found" value holds for its dataset only. Names are mostof what maisecrets misses: 74 to 92 % of its missed values here. It finds a name after a label, or when the nameis on your term list. Personal data: fewest wrong masks on all four datasets; with the opt-in NER, maisecrets finds the most Personal data: fewest wrong masks onall four datasets; with the opt-inNER, maisecrets finds the most Same documents per dataset, data no maisecretsrule was written from: maisecrets on 31 October2026, the other tools on 21 October 2026. Bothscales run from 0 to 100. Nemotron-PII · 834 documents, 2,781 values Presidio 2.2.364 RULES + LANGUAGE MODEL Found 72.2 % Wrong of 100 7.2 (173) Preserve 0.6.1 RULES + NAME DICTIONARY Found 66.0 % Wrong of 100 17.5 (356) pii-anon 1.7.0rc1 REGEX Found 76.6 % Wrong of 100 70.3 (4,437) maisecrets 0.8.6 RULES Found 61.7 % Wrong of 100 0.4 (7) maisecrets 0.8.6 + NER RULES + NER (OPT-IN) Found 85.9 % Wrong of 100 0.7 (14) Mendeley financial · 362 documents, 2,084 values Presidio 2.2.364 RULES + LANGUAGE MODEL Found 67.7 % Wrong of 100 10.5 (397) Preserve 0.6.1 RULES + NAME DICTIONARY Found 66.6 % Wrong of 100 18.7 (380) pii-anon 1.7.0rc1 REGEX Found 61.0 % Wrong of 100 34.2 (1,089) maisecrets 0.8.6 RULES Found 70.6 % Wrong of 100 1.2 (18) maisecrets 0.8.6 + NER RULES + NER (OPT-IN) Found 93.7 % Wrong of 100 13.7 (315) Gretel finance · 334 documents, 1,141 values Presidio 2.2.364 RULES + LANGUAGE MODEL Found 45.3 % Wrong of 100 72.7 (2,398) Preserve 0.6.1 RULES + NAME DICTIONARY Found 41.6 % Wrong of 100 75.4 (2,461) pii-anon 1.7.0rc1 REGEX Found 42.9 % Wrong of 100 72.3 (2,012) maisecrets 0.8.6 RULES Found 31.2 % Wrong of 100 9.6 (39) maisecrets 0.8.6 + NER RULES + NER (OPT-IN) Found 51.3 % Wrong of 100 8.2 (64) Privy · 2,816 documents, 1,076 values Presidio 2.2.364 RULES + LANGUAGE MODEL Found 47.3 % Wrong of 100 47.3 (1,060) Preserve 0.6.1 RULES + NAME DICTIONARY Found 20.5 % Wrong of 100 58.5 (350) pii-anon 1.7.0rc1 REGEX Found 28.6 % Wrong of 100 6.4 (22) maisecrets 0.8.6 RULES Found 23.7 % Wrong of 100 0.8 (2) maisecrets 0.8.6 + NER RULES + NER (OPT-IN) Found 66.4 % Wrong of 100 6.5 (51) In brackets: the number of wrong masks. These countsdepend on the size of each dataset and do notcompare across datasets.maisecrets + NER (blue): the same samples with theopt-in NER service, on 31 October 2026. It finds themost on every dataset. It makes more wrong masksthan maisecrets alone; on Gretel, a smaller share ofwhat it flags is wrong.Each dataset labels other kinds of personal data, soa "found" value holds for its dataset only. Namesare most of what maisecrets misses: 74 to 92 % ofits missed values here. It finds a name after alabel, or when the name is on your term list.
Source: Benchmark V3, bench/results/2026-10-31-v3-0.8.6 and bench/results/2026-10-21-v3/run (tag v0.8.6)
The numbers of this chart
GroupToolFound: labelled values masked wholeOf 100 things flagged, how many were wrong?
Nemotron-PII · 834 documents, 2,781 valuesPresidio 2.2.364 (RULES + LANGUAGE MODEL)72.2 %7.2 (173)
Nemotron-PII · 834 documents, 2,781 valuesPreserve 0.6.1 (RULES + NAME DICTIONARY)66.0 %17.5 (356)
Nemotron-PII · 834 documents, 2,781 valuespii-anon 1.7.0rc1 (REGEX)76.6 %70.3 (4,437)
Nemotron-PII · 834 documents, 2,781 valuesmaisecrets 0.8.6 (RULES)61.7 %0.4 (7)
Nemotron-PII · 834 documents, 2,781 valuesmaisecrets 0.8.6 + NER (RULES + NER (OPT-IN))85.9 %0.7 (14)
Mendeley financial · 362 documents, 2,084 valuesPresidio 2.2.364 (RULES + LANGUAGE MODEL)67.7 %10.5 (397)
Mendeley financial · 362 documents, 2,084 valuesPreserve 0.6.1 (RULES + NAME DICTIONARY)66.6 %18.7 (380)
Mendeley financial · 362 documents, 2,084 valuespii-anon 1.7.0rc1 (REGEX)61.0 %34.2 (1,089)
Mendeley financial · 362 documents, 2,084 valuesmaisecrets 0.8.6 (RULES)70.6 %1.2 (18)
Mendeley financial · 362 documents, 2,084 valuesmaisecrets 0.8.6 + NER (RULES + NER (OPT-IN))93.7 %13.7 (315)
Gretel finance · 334 documents, 1,141 valuesPresidio 2.2.364 (RULES + LANGUAGE MODEL)45.3 %72.7 (2,398)
Gretel finance · 334 documents, 1,141 valuesPreserve 0.6.1 (RULES + NAME DICTIONARY)41.6 %75.4 (2,461)
Gretel finance · 334 documents, 1,141 valuespii-anon 1.7.0rc1 (REGEX)42.9 %72.3 (2,012)
Gretel finance · 334 documents, 1,141 valuesmaisecrets 0.8.6 (RULES)31.2 %9.6 (39)
Gretel finance · 334 documents, 1,141 valuesmaisecrets 0.8.6 + NER (RULES + NER (OPT-IN))51.3 %8.2 (64)
Privy · 2,816 documents, 1,076 valuesPresidio 2.2.364 (RULES + LANGUAGE MODEL)47.3 %47.3 (1,060)
Privy · 2,816 documents, 1,076 valuesPreserve 0.6.1 (RULES + NAME DICTIONARY)20.5 %58.5 (350)
Privy · 2,816 documents, 1,076 valuespii-anon 1.7.0rc1 (REGEX)28.6 %6.4 (22)
Privy · 2,816 documents, 1,076 valuesmaisecrets 0.8.6 (RULES)23.7 %0.8 (2)
Privy · 2,816 documents, 1,076 valuesmaisecrets 0.8.6 + NER (RULES + NER (OPT-IN))66.4 %6.5 (51)

How to read these numbers

Picture texts with 100 sensitive values in them, such as passwords, e-mail addresses and IBANs, and a lot of ordinary text around them. A tool marks what it thinks is sensitive.

  • Found (recall): how many of the 100 values the tool masked completely. It masks 80 of them: 80 % found.
  • Missed (false negatives): the 20 it did not mask. If they pass through a path that the tool checks, they reach the model as they are.
  • Wrong masks (false positives): ordinary text that the tool masked anyway, such as a commit hash or a variable name. Say it masked 20 such things.
  • Of 100 things flagged, how many were wrong: the tool flagged 100 things, 80 right and 20 wrong, so 20. This is 100 minus the precision. It does not say how likely it is that any one word of your text is masked.

A second tool masks 60 of the values and 1 ordinary word: it finds 60 %, and 2 of every 100 things it flags are wrong. Neither tool is better in every way. The first finds more; the second gets in the way less.

F1, a secondary summary. F1 joins found and precision into one number from 0 to 1. It is high only when both are high. It treats a miss and a wrong mask as equal, but in an agent they have different results. Read it beside recall and precision, not instead of them.

F1 by dataset (Benchmark V3, maisecrets 0.8.6)
ToolNemotronMendeleyGretelPrivy
PresidioPreservepii-anonmaisecrets+ NER Presidio: .812 Preserve: .733 pii-anon: .428 maisecrets: .762 + NER: .921 (highest) Presidio: .771 Preserve: .732 pii-anon: .633 maisecrets: .824 + NER: .899 (highest) Presidio: .340 Preserve: .309 pii-anon: .337 maisecrets: .464 + NER: .658 (highest) Presidio: .498 Preserve: .275 pii-anon: .438 maisecrets: .383 + NER: .776 (highest)
Bold: the highest value of a dataset. With the opt-in NER service (+ NER), maisecrets has the highest F1 on all four datasets. Without it, maisecrets has the highest F1 on Mendeley and Gretel, and a higher F1 than Preserve on all four datasets (on Nemotron-PII by .029). Presidio has the highest F1 on Nemotron-PII and Privy. On Privy, pii-anon is also above maisecrets. F1 = 2PR / (P + R), from the unrounded precision and strict recall of the result files.

Why precision matters for this tool. maisecrets changes what the AI reads. Every wrong mask puts a placeholder where the agent needed the real text: a broken path, a wrong variable name, a test that fails. People then switch the tool off, and then nothing is masked. Few wrong masks are the condition for leaving it on. On these samples, Presidio made 22 to 530 times as many wrong masks as maisecrets.

F0.5, a summary that weighs precision more. F0.5 joins precision and recall like F1, but precision counts more than recall. For a tool that changes what an AI reads, it is the fairer summary. It still does not replace recall: a missed value is a risk, whatever the score.

F0.5 by dataset (Benchmark V3, maisecrets 0.8.6)
ToolNemotronMendeleyGretelPrivy
PresidioPreservepii-anonmaisecrets+ NER Presidio: .878 Preserve: .786 pii-anon: .338 maisecrets: .887 + NER: .963 (highest) Presidio: .841 Preserve: .778 pii-anon: .648 maisecrets: .915 (highest) + NER: .877 Presidio: .296 Preserve: .268 pii-anon: .298 maisecrets: .655 + NER: .793 (highest) Presidio: .515 Preserve: .344 pii-anon: .644 maisecrets: .606 + NER: .864 (highest)
Bold: the highest value of a dataset. With the opt-in NER service (+ NER), maisecrets has the highest F0.5 on Nemotron, Gretel and Privy. On Mendeley, maisecrets without NER is above it, because NER adds wrong masks. Of the four tools without NER, maisecrets has the highest F0.5 on Nemotron, Mendeley and Gretel. On Nemotron the lead is small: .887 against .878 (Presidio); on the Nemotron holdout sample, both have .883. On Privy, pii-anon is higher: .644 against .606. F0.5 = 1.25PR / (0.25P + R), from the same values as F1.

Why both errors cost something in an AI coding agent. A miss is a risk. If an undetected value passes through a path that maisecrets checks, such as your prompt or a tool result, it enters the model context: the model provider and the session transcript then have it. That is the harm maisecrets exists to prevent, and no precision value makes up for it. A wrong mask replaces text the agent needs with a placeholder: the agent cannot read the commit hash it must check, or your prompt is blocked for no reason. A coding agent reads tool results many times an hour, so a small rate of wrong masks still adds up. Many wrong masks teach a team to switch the tool off, and then nothing is masked. maisecrets is built for wrong masks to be rare.

Masked whole, or in part. The charts count a value as found only when it is masked completely. Some values are masked in part by design: maisecrets masks the password of postgres://user:password@host/db and keeps the host, so the agent can still connect. Those count as not found.

Secrets: real GitHub issues and token formats

A research team labelled the secrets that leaked in GitHub issue reports (MSR 2026 data set (opens in a new tab), CC BY 4.0). We split the set by issue and sealed one half on 25 October 2026, before any case was read. Nobody reads that half, and a run gives totals only (holdout log). Eight scanners ran on it: maisecrets on 26 October 2026, the other scanners on 25 October 2026.

GitHub issues: maisecrets masked the most secrets whole, gitleaks had the highest precision Sealed holdout half, 3,761 labelled secrets. Two levels: found per labelled value, precision per finding on a labelled candidate. maisecrets 0.8.2 Found 72.0 %, Precision 71.2 %; Betterleaks 1.9.0 Found 54.6 %, Precision 63.2 %; gitleaks 8.30.1 Found 53.2 %, Precision 88.9 %; Nosey Parker 0.24.0 Found 31.1 %, Precision 59.1 %; Kingfisher 1.113.0 Found 29.6 %, Precision 78.3 %; detect-secrets 1.5.0 Found 29.4 %, Precision 48.3 %; Kingfisher 2.11.1 Found 21.8 %, Precision 78.9 %; TruffleHog 3.99.2 Found 12.3 %, Precision 66.0 % GitHub issues: maisecrets masked the most secrets whole, gitleaks hadthe highest precision Sealed holdout half, 3,761 labelled secrets. Two levels: found per labelled value, precision per findingon a labelled candidate. Found: labelled secrets maskedwhole (span level)Precision: secret findings on atrue secret (snippet level) maisecrets 0.8.2 72.0 % 71.2 % Betterleaks 1.9.0 54.6 % 63.2 % gitleaks 8.30.1 53.2 % 88.9 % Nosey Parker 0.24.0 31.1 % 59.1 % Kingfisher 1.113.0 29.6 % 78.3 % detect-secrets 1.5.0 29.4 % 48.3 % Kingfisher 2.11.1 21.8 % 78.9 % TruffleHog 3.99.2 12.3 % 66.0 % Found counts each labelled secret: it is found when the scanner masks it whole. The set also labels candidatesthat are not a secret. Precision is the share of the secret findings on a candidate that land on a true secret.maisecrets also masks personal data, such as e-mail addresses, and this set labels secrets only. At span level,6.7 % of its masks lie on a labelled secret.Kingfisher ran in two versions: 1.113.0 is the last release with its own rule catalog. The binaries ran withtheir validation off, so no scanner sent a found value to a provider. GitHub issues: maisecrets masked the most secrets whole, gitleaks had the highest precision GitHub issues: maisecrets masked themost secrets whole, gitleaks had thehighest precision Sealed holdout half, 3,761 labelled secrets. Twolevels: found per labelled value, precision perfinding on a labelled candidate. maisecrets 0.8.2 Found 72.0 % Precision 71.2 % Betterleaks 1.9.0 Found 54.6 % Precision 63.2 % gitleaks 8.30.1 Found 53.2 % Precision 88.9 % Nosey Parker 0.24.0 Found 31.1 % Precision 59.1 % Kingfisher 1.113.0 Found 29.6 % Precision 78.3 % detect-secrets 1.5.0 Found 29.4 % Precision 48.3 % Kingfisher 2.11.1 Found 21.8 % Precision 78.9 % TruffleHog 3.99.2 Found 12.3 % Precision 66.0 % Found counts each labelled secret: it is found whenthe scanner masks it whole. The set also labelscandidates that are not a secret. Precision is theshare of the secret findings on a candidate thatland on a true secret.maisecrets also masks personal data, such as e-mailaddresses, and this set labels secrets only. At spanlevel, 6.7 % of its masks lie on a labelled secret.Kingfisher ran in two versions: 1.113.0 is the lastrelease with its own rule catalog. The binaries ranwith their validation off, so no scanner sent afound value to a provider.
Source: Extended baseline of 0.8.2, report.md
The numbers of this chart
ToolFound: labelled secrets masked whole (span level)Precision: secret findings on a true secret (snippet level)
maisecrets 0.8.272.0 %71.2 %
Betterleaks 1.9.054.6 %63.2 %
gitleaks 8.30.153.2 %88.9 %
Nosey Parker 0.24.031.1 %59.1 %
Kingfisher 1.113.029.6 %78.3 %
detect-secrets 1.5.029.4 %48.3 %
Kingfisher 2.11.121.8 %78.9 %
TruffleHog 3.99.212.3 %66.0 %

Token formats. The second test uses the built-in examples of six public rule catalogs. These examples are development data for maisecrets: we read them to write rules, and maisecrets uses the Betterleaks rules. A lead on them is expected. The GitHub-issues holdout above is the stronger test.

Secrets: share of 11,902 provider token examples masked whole Built-in examples of six public rule catalogs (Nosey Parker, Kingfisher, gitleaks, Betterleaks, TruffleHog, GitLab), each bare and after "token =". maisecrets on 26 October 2026, the other scanners on 25 October 2026. maisecrets 0.8.2 Found 61.7 %; Betterleaks 1.9.0 Found 46.1 %; gitleaks 8.30.1 Found 45.1 %; Kingfisher 1.113.0 Found 27.8 %; detect-secrets 1.5.0 Found 23.5 %; Kingfisher 2.11.1 Found 21.9 %; TruffleHog 3.99.2 Found 12.3 %; Nosey Parker 0.24.0 Found 9.8 % Secrets: share of 11,902 provider token examples masked whole Built-in examples of six public rule catalogs (Nosey Parker, Kingfisher, gitleaks, Betterleaks,TruffleHog, GitLab), each bare and after "token =". maisecrets on 26 October 2026, the other scanners on25 October 2026. Found: token examples masked whole maisecrets 0.8.2 61.7 % Betterleaks 1.9.0 46.1 % gitleaks 8.30.1 45.1 % Kingfisher 1.113.0 27.8 % detect-secrets 1.5.0 23.5 % Kingfisher 2.11.1 21.9 % TruffleHog 3.99.2 12.3 % Nosey Parker 0.24.0 9.8 % No precision: the set holds no text without a secret, so it cannot show wrong masks. Secrets: share of 11,902 provider token examples masked whole Secrets: share of 11,902 providertoken examples masked whole Built-in examples of six public rule catalogs(Nosey Parker, Kingfisher, gitleaks, Betterleaks,TruffleHog, GitLab), each bare and after "token=". maisecrets on 26 October 2026, the otherscanners on 25 October 2026. maisecrets 0.8.2 Found 61.7 % Betterleaks 1.9.0 Found 46.1 % gitleaks 8.30.1 Found 45.1 % Kingfisher 1.113.0 Found 27.8 % detect-secrets 1.5.0 Found 23.5 % Kingfisher 2.11.1 Found 21.9 % TruffleHog 3.99.2 Found 12.3 % Nosey Parker 0.24.0 Found 9.8 % No precision: the set holds no text without asecret, so it cannot show wrong masks.
Source: Extended baseline of 0.8.2, report.md
The numbers of this chart
ToolFound: token examples masked whole
maisecrets 0.8.261.7 %
Betterleaks 1.9.046.1 %
gitleaks 8.30.145.1 %
Kingfisher 1.113.027.8 %
detect-secrets 1.5.023.5 %
Kingfisher 2.11.121.9 %
TruffleHog 3.99.212.3 %
Nosey Parker 0.24.09.8 %

Names: a language model as an opt-in

A name has no fixed shape, so rules find it after a label, or when it is on your term list. A language model (NER) finds names in running text. We measured five such models as an extra layer after the detector, on one dataset (chart below, maisecrets 0.7.3).

maisecrets from 0.8.6 can ask a NER service with the model of our pick, D3. The service is opt-in and runs in the container mcpgate/ner: /maisecrets:ner local starts it on your computer (how to turn it on). maisecrets sends it tool results, with the values that the rules found as filler. maisecrets from 0.8.7 also sends your typed prompts in Claude Code to a local service, and a name there becomes a placeholder; a service on the network never gets a prompt. On the four V3 datasets, it finds names whole as follows:

  • Nemotron: 365 without NER, 1,033 with NER, of 1,159
  • Mendeley: 126 without NER, 607 with NER, of 633
  • Gretel: 91 without NER, 320 with NER, of 668
  • Privy: 41 without NER, 500 with NER, of 796

The same samples and scoring as the chart above; result files: bench/results/2026-10-31-v3-0.8.6-ner.

The model D3 (Davlan/distilbert-base-multilingual-cased-ner-hrl, AFL-3.0) and its base model (distilbert-base-multilingual-cased, Apache-2.0) have their notices in the image under /licenses.

The one we recommend is the multilingual DistilBERT (D3, Davlan/distilbert-base-multilingual-cased-ner-hrl): in our measurement, the best trade-off between names found and added false alarms (NER-EXPERIMENT.md). You can also run it on your own files and import the names it finds. maisecrets then masks those names wherever they appear.

Names: a language model finds far more, at a cost; D3 was our pick Privy test set in full: 28,843 texts, 8,121 labelled names. The released detector, then one NER layer after it. 21 October 2026. maisecrets 0.7.3 Names 312 · 3.8 %, Added FP baseline; + spaCy small (NOT SHIPPED) Names 1,593 · 19.6 %, Added FP +3,676; + spaCy large (NOT SHIPPED) Names 2,439 · 30.0 %, Added FP +4,744; + DistilBERT (D2) (NOT SHIPPED) Names 4,345 · 53.5 %, Added FP +283; + multilingual DistilBERT (D3) (OUR PICK · OPT-IN SERVICE) Names 5,157 · 63.5 %, Added FP +413; + GLiNER, threshold 0.5 (NOT SHIPPED) Names 7,812 · 96.2 %, Added FP +31,138 Names: a language model finds far more, at a cost; D3 was our pick Privy test set in full: 28,843 texts, 8,121 labelled names. The released detector, then one NER layerafter it. 21 October 2026. Names found whole (of 8,121)Added false alarms maisecrets 0.7.3 312 · 3.8 % baseline + spaCy small NOT SHIPPED 1,593 · 19.6 % +3,676 + spaCy large NOT SHIPPED 2,439 · 30.0 % +4,744 + DistilBERT (D2) NOT SHIPPED 4,345 · 53.5 % +283 + multilingual DistilBERT (D3) OUR PICK · OPT-IN SERVICE 5,157 · 63.5 % +413 + GLiNER, threshold 0.5 NOT SHIPPED 7,812 · 96.2 % +31,138 An experiment on one dataset. D3 was chosen after the results of the other layers on this dataset were known, soits result is not an independent measurement.D3 is the model of the opt-in NER service. The V3 numbers above are the check on four more datasets. Names: a language model finds far more, at a cost; D3 was our pick Names: a language model finds farmore, at a cost; D3 was our pick Privy test set in full: 28,843 texts, 8,121labelled names. The released detector, then oneNER layer after it. 21 October 2026. maisecrets 0.7.3 Names 312 · 3.8 % Added FP baseline + spaCy small NOT SHIPPED Names 1,593 · 19.6 % Added FP +3,676 + spaCy large NOT SHIPPED Names 2,439 · 30.0 % Added FP +4,744 + DistilBERT (D2) NOT SHIPPED Names 4,345 · 53.5 % Added FP +283 + multilingual DistilBERT (D3) OUR PICK · OPT-IN SERVICE Names 5,157 · 63.5 % Added FP +413 + GLiNER, threshold 0.5 NOT SHIPPED Names 7,812 · 96.2 % Added FP +31,138 An experiment on one dataset. D3 was chosen afterthe results of the other layers on this dataset wereknown, so its result is not an independentmeasurement.D3 is the model of the opt-in NER service. The V3numbers above are the check on four more datasets.
Source: docs/NER-EXPERIMENT.md, "Privy, the independent check"
The numbers of this chart
ToolNames found whole (of 8,121)Added false alarms
maisecrets 0.7.3312 · 3.8 %baseline
+ spaCy small (NOT SHIPPED)1,593 · 19.6 %+3,676
+ spaCy large (NOT SHIPPED)2,439 · 30.0 %+4,744
+ DistilBERT (D2) (NOT SHIPPED)4,345 · 53.5 %+283
+ multilingual DistilBERT (D3) (OUR PICK · OPT-IN SERVICE)5,157 · 63.5 %+413
+ GLiNER, threshold 0.5 (NOT SHIPPED)7,812 · 96.2 %+31,138

Why our own detection engine?

Detection is only half the problem. An AI agent still has to work.

maisecrets uses a small, deterministic detection engine, made for agent workflows: precise masks, the same result for the same input on your own computer, and as little disruption to legitimate content as possible.

By default it needs no NER model and no external inference service. It does not guess names in free text. This keeps false alarms low, and it misses some personal data in free text, as the split above shows. The NER service is an opt-in for users who want more names and accept more false alarms.

On four evaluated PII datasets, maisecrets had a higher precision than the three other tools. That does not make it the best detector for every task. It makes it a good choice when a wrong mask costs much.

Detection is only the start. maisecrets adds local placeholders and the vault of your operating system, and it puts the real value back only where a tool needs it: in a command, a file or an MCP call of the same session.

Choose maisecrets when your AI agent must work with sensitive data without showing more of it to the model than necessary, and without breaking the work.

Fast answers

maisecrets reads every prompt and every tool result before the model does. A slow scan would be a wait in every step of the agent. The release gate measures the CPU time of each release against the last one, on one machine: maisecrets 0.8.2 needs 0.642 ms for a short prompt and 5.3 s for 1 MB of tool text (1.07 and 1.14 times the time of 0.8.1). The detector uses the Python standard library only: no model to load, no network call. Source: release-gate.md.

A second measurement compares ten tools on our reference server (AMD EPYC 9645, 8 vCPU, 15.6 GB RAM, Debian 13), one tool after the other: maisecrets 0.8.18 and the other tools on 4 November 2026. Its times differ a little from those of the release gate. The earlier table ran on an Apple M5, which is faster per core, so do not compare the two tables. Four Python tools ran on Python 3.15.0rc3, Presidio on Python 3.11 (README.md). A warm process is already running when the text arrives. A process per run starts the binary for each text, so its time includes the start.

Time per text: maisecrets answers a short prompt in under 1 msMedian of warm runs on our reference server (AMD EPYC 9645, 8 vCPU, 15.6 GB RAM, Debian 13), 4 November 2026. Shorter is faster. Log scale: each step of the bar is ten times the time.
ToolShort prompt10 KB1 MB
Warm process
Warm process: PresidioPreservepii-anondetect-secretsmaisecrets Presidio: 18 ms Preserve: 763 ms pii-anon: 2.1 ms detect-secrets: 2.2 ms maisecrets: 0.69 ms Presidio: 524 ms Preserve: 2.1 s pii-anon: 35 ms detect-secrets: 34 ms maisecrets: 60 ms Presidio: 184.7 s Preserve: 63.2 s pii-anon: 5.4 s detect-secrets: 3.2 s maisecrets: 9.9 s
Process per run
Process per run: gitleaksBetterleaksNosey ParkerTruffleHogKingfisher 2 gitleaks: 482 ms Betterleaks: 350 ms Nosey Parker: 595 ms TruffleHog: 2.0 s Kingfisher 2: 5.5 s gitleaks: 563 ms Betterleaks: 352 ms Nosey Parker: 635 ms TruffleHog: 1.9 s Kingfisher 2: 5.6 s gitleaks: 774 ms Betterleaks: 636 ms Nosey Parker: 605 ms TruffleHog: 1.9 s Kingfisher 2: 6.0 s

Bold: the fastest tool of a column. A process per run includes the start of the binary.

The numbers of this chart
GroupToolShort prompt10 KB1 MB
Warm processPresidio18 ms524 ms184.7 s
Warm processPreserve763 ms2.1 s63.2 s
Warm processpii-anon2.1 ms35 ms5.4 s
Warm processdetect-secrets2.2 ms34 ms3.2 s
Warm processmaisecrets0.69 ms60 ms9.9 s
Process per rungitleaks482 ms563 ms774 ms
Process per runBetterleaks350 ms352 ms636 ms
Process per runNosey Parker595 ms635 ms605 ms
Process per runTruffleHog2.0 s1.9 s1.9 s
Process per runKingfisher 25.5 s5.6 s6.0 s
Memory and disk: maisecrets installs in a few MB and needs no modelPeak memory of the process tree for a short prompt and for 1 MB of text, and the install size, on our reference server (AMD EPYC 9645, 8 vCPU, 15.6 GB RAM, Debian 13). Less is better. Log scale.
ToolMemory, short promptMemory, 1 MBInstall size
Warm process
Warm process: PresidioPreservepii-anondetect-secretsmaisecrets Presidio: 767 MB Preserve: 1.9 GB pii-anon: 58 MB detect-secrets: 34 MB maisecrets: 24 MB Presidio: 4.8 GB Preserve: 2.0 GB pii-anon: 141 MB detect-secrets: 52 MB maisecrets: 330 MB Presidio: 783 MB Preserve: 302 MB pii-anon: 92 MB detect-secrets: 15 MB maisecrets: 3.7 MB
Process per run
Process per run: gitleaksBetterleaksNosey ParkerTruffleHogKingfisher 2 gitleaks: 64 MB Betterleaks: 46 MB Nosey Parker: 267 MB TruffleHog: 203 MB Kingfisher 2: 105 MB gitleaks: 69 MB Betterleaks: 61 MB Nosey Parker: 284 MB TruffleHog: 258 MB Kingfisher 2: 152 MB gitleaks: 21 MB Betterleaks: 23 MB Nosey Parker: 41 MB TruffleHog: 35 MB Kingfisher 2: 35 MB

Bold: the lowest value of a column. The install size of Presidio includes a model of 425 MB.

Source: resources.md

The numbers of this chart
GroupToolMemory, short promptMemory, 1 MBInstall size
Warm processPresidio767 MB4.8 GB783 MB
Warm processPreserve1.9 GB2.0 GB302 MB
Warm processpii-anon58 MB141 MB92 MB
Warm processdetect-secrets34 MB52 MB15 MB
Warm processmaisecrets24 MB330 MB3.7 MB
Process per rungitleaks64 MB69 MB21 MB
Process per runBetterleaks46 MB61 MB23 MB
Process per runNosey Parker267 MB284 MB41 MB
Process per runTruffleHog203 MB258 MB35 MB
Process per runKingfisher 2105 MB152 MB35 MB

With the opt-in NER service. The service adds the time of the model to each tool result, and with a local service also to each typed prompt:

With NER, a document takes about 30 to 120 ms instead of a few ms Time per document of the V3 samples, on Apple M, with the service on the same computer, 31 October 2026. Shorter is faster. Nemotron: Rules alone Median 3.1 ms, p95 15 ms; + NER Median 70 ms, p95 192 ms. Mendeley: Rules alone Median 1.9 ms, p95 16 ms; + NER Median 62 ms, p95 236 ms. Gretel: Rules alone Median 4.0 ms, p95 9.4 ms; + NER Median 121 ms, p95 166 ms. Privy: Rules alone Median 0.80 ms, p95 2.2 ms; + NER Median 34 ms, p95 99 ms With NER, a document takes about 30 to 120 ms instead of a few ms Time per document of the V3 samples, on Apple M, with the service on the same computer, 31 October 2026.Shorter is faster. Median: half of the documents arefasterp95: 95 of 100 documents arefaster Nemotron Rules alone 3.1 ms 15 ms + NER 70 ms 192 ms Mendeley Rules alone 1.9 ms 16 ms + NER 62 ms 236 ms Gretel Rules alone 4.0 ms 9.4 ms + NER 121 ms 166 ms Privy Rules alone 0.80 ms 2.2 ms + NER 34 ms 99 ms Orange: the rules alone, as maisecrets runs by default. Blue: with the opt-in NER service. With NER, a document takes about 30 to 120 ms instead of a few ms With NER, a document takes about 30to 120 ms instead of a few ms Time per document of the V3 samples, on Apple M,with the service on the same computer, 31 October2026. Shorter is faster. Nemotron Rules alone Median 3.1 ms p95 15 ms + NER Median 70 ms p95 192 ms Mendeley Rules alone Median 1.9 ms p95 16 ms + NER Median 62 ms p95 236 ms Gretel Rules alone Median 4.0 ms p95 9.4 ms + NER Median 121 ms p95 166 ms Privy Rules alone Median 0.80 ms p95 2.2 ms + NER Median 34 ms p95 99 ms Orange: the rules alone, as maisecrets runs bydefault. Blue: with the opt-in NER service.
Source: bench/results/2026-10-31-v3-0.8.6-ner
The numbers of this chart
GroupToolMedian: half of the documents are fasterp95: 95 of 100 documents are faster
NemotronRules alone3.1 ms15 ms
Nemotron+ NER70 ms192 ms
MendeleyRules alone1.9 ms16 ms
Mendeley+ NER62 ms236 ms
GretelRules alone4.0 ms9.4 ms
Gretel+ NER121 ms166 ms
PrivyRules alone0.80 ms2.2 ms
Privy+ NER34 ms99 ms

Typed prompts with NER. maisecrets from 0.8.7 also sends a typed prompt to the local service. A second measurement on 1 November 2026 used texts of prompt length from DialogPII, on an 8-core AMD EPYC 9645, the container limited to 4 CPUs and 1.5 GB, 4 requests at once. No rule was tuned on these texts.

Names in typed prompts: with NER, maisecrets finds more than half of themNames found whole in DialogPII texts cut to prompt length, maisecrets 0.8.7, 1 November 2026. Longer is better.
Tool500 characters1,000 characters
Rules alone+ NER Rules alone: 2.6 % + NER: 56.6 % Rules alone: 2.6 % + NER: 57.7 %

Time per prompt with NER on this machine: 500 characters, 54 ms median and 84 ms p95; 1,000 characters, 100 ms median and 164 ms p95. Another CPU gives other times. The run used the timeout of 0.8.7, 300 ms, and every DialogPII request got its answer in time.

Wrong masks of the service: 3.53 and 2.78 per 1,000 words in DialogPII (a lower bound, because a mask on a labelled value of another kind does not count). In developer text from GitHub issues, at most 0.54 per 1,000 words (an upper bound).

Source: bench/results/2026-11-01-v3-0.8.7-prompt-ner

The numbers of this chart
Tool500 characters1,000 characters
Rules alone2.6 %2.6 %
+ NER56.6 %57.7 %

These documents are longer than a typical tool result. The finds are the same for a service on your network, but the network adds its time. maisecrets waits at most timeout_ms (300 ms by default). After that, the rules mask alone. A slow service drops out; it does not slow the work down. The container needs about 230 to 260 MB of RAM with the int8 model, on a CPU with int8 dot-product instructions (Apple M, AMD Zen 4 and newer, Intel Xeon from Cascade Lake). On other CPUs, it uses the fp32 model and needs about 700 MB. The container selects the model by the CPU. We measured these values on 31 October 2026. The plugin itself needs nothing more.

For a short prompt, maisecrets needed the shortest time of the 10 tools: 0.69 ms. For 1 MB of tool text, 7 of the 9 other tools were faster. For 1 MB, maisecrets held up to 330 MB of memory: Presidio and Preserve needed more, the other 7 tools less. Times are the median of warm runs; memory is the peak of the process tree. Source: resources.md.

A language model for names adds to these numbers. In our NER experiment, spaCy small needed about 12 ms per document, D3 about 33 ms and 0.7 GB more memory, and GLiNER about 152 ms and 3.5 GB more memory (Apple M5, CPU only, one process, 300 documents; D3 in fp32). maisecrets ships none of them.

Where maisecrets stands

Measured, on the benchmarks above (maisecrets 0.8.6): on four labelled datasets of personal data, maisecrets had the highest precision of the four tools. Without names, it had the highest recall on 3 of the four datasets; with names, a tool with a language model finds more. It found the most on one dataset (Mendeley financial). The split by names is a post-hoc analysis of the same runs. As a secondary summary, its F1 was the highest on Mendeley and Gretel, and higher than Preserve's on all four. F0.5, which weighs precision more, was the highest on 3 of the four datasets. For secrets, on the sealed half of real GitHub issues, maisecrets masked the most secrets whole of 8 scanners, and gitleaks had the highest precision.

Where other approaches do better: a language model finds far more names in running text. Presidio has the highest F1 on Nemotron-PII and Privy and finds more personal data on three of the four datasets. pii-anon finds the most on Nemotron-PII, and on Privy its F1 is higher than that of maisecrets. Values that are not names are also missed: on Gretel, maisecrets finds 56 % of them.

What the product does beyond detection (released features, not benchmark results): the value goes into the vault of your operating system; the model sees a placeholder and the real value goes back only into a command, a file or an MCP call of the same session, under a cap per hour; prompts and tool output are checked inside Claude Code and Codex; a machine policy can fix the settings for a company. Every benchmark here can be repeated from the repository.

What we do not claim: that maisecrets is the most accurate detector, that it finds all personal data, or that a benchmark measures the protection of a real agent session.

Where your values stay

Our sealed holdout set

Rules are written from development data, so a score on that data is too kind. To check a release on data no rule was written from, we keep a sealed set of 872 synthetic texts with 828 hidden values. We made it ourselves, in a separate agent session that had no access to the code, the results or the misses of maisecrets. Its manifest was committed before the first run, and no rule is changed because of its result. It is our own measurement, not an independent or external evaluation, and no other tool was run on it.

Values maisecrets 0.8.2 masked whole, measured 26 October 2026 Secrets200 / 330 · 61 %Personal data336 / 498 · 67 % maisecrets raised 3 false alarms in all 872 texts.

The secrets masked in part. 90 of the 330 secrets are connection strings and URL credentials, and all of them were masked in part, none whole. maisecrets is designed to mask the password of such a string and keep the host, so the agent can still use the connection. Whether the password was masked in each of these 90 cases is not measured yet: the set is sealed, and it does not mark which part of a string is the secret. Of the other 240 secrets, 200 were masked whole. The overall result stays 200 of 330.

The result for each kind of value: What it detects. Since 0.7.4, most releases are measured on this set; the holdout log lists each run.

Full results and method

Benchmark V3 ran maisecrets 0.8.6 and three open-source PII tools on the same documents: the validation split of Nemotron-PII, Mendeley and Gretel, and the Privy test set. The three other tools ran on 21 October 2026. maisecrets runs again on the same documents at each release; the values on this page are from 31 October 2026 (bench/results/2026-10-31-v3-0.8.6).

  • Recall (R): the share of the labelled values that a tool masks whole.
  • Precision (P): the share of a tool's masks that lie on a labelled value. A mask in a kind of value that the dataset does not label counts neither way.
  • False alarms: masks on text that the dataset does not label as sensitive, in a kind it labels.
  • F1: 2PR / (P + R), from the unrounded P and R of the result files. The f1 field in a result file uses the precision of Benchmark V2, so this page does not use it.
  • F0.5: 1.25PR / (0.25P + R), from the same P and R. It weighs precision more than recall.
  • Level: every number on this page is at span level, and recall is strict: a value counts as found only when it is masked whole. Precision is P (V3).
  • Splits: dev is read to write rules; val is used to decide, not to tune; holdout is never read, and a release sees only its totals. The charts above use samples of the val split (1 in 25) and of Privy (1 in 10). Privy is never read, and its labels are not complete, so its precision is a weak signal.
Benchmark V3, all values per dataset and tool
ToolRecallPrecisionF1F0.5False alarms
Nemotron-PII834 documents, 2,781 values
Presidio .722.928.812.878173
Preserve .660.825.733.786356
pii-anon .766.297.428.3384,437
maisecrets .617.996.762.8877
+ NER .859.993.921.96314
Mendeley financial362 documents, 2,084 values
Presidio .677.895.771.841397
Preserve .666.813.732.778380
pii-anon .610.658.633.6481,089
maisecrets .706.988.824.91518
+ NER .937.863.899.877315
Gretel finance334 documents, 1,141 values
Presidio .453.273.340.2962,398
Preserve .416.246.309.2682,461
pii-anon .429.277.337.2982,012
maisecrets .312.904.464.65539
+ NER .513.918.658.79364
Privy2,816 documents, 1,076 values
Presidio .473.527.498.5151,060
Preserve .205.415.275.344350
pii-anon .286.936.438.64422
maisecrets .237.992.383.6062
+ NER .664.935.776.86451

Bold: the best value of a dataset (the highest, and for false alarms the lowest). Versions: Presidio 2.2.364, Preserve 0.6.1, pii-anon 1.7.0rc1 and maisecrets 0.8.6; + NER is maisecrets + NER with the opt-in NER service.

From 0.8.1 to 0.8.2, on the full splits

The release gate runs maisecrets on every document of each split, not on a sample. The holdout rows are the strongest evidence, because nobody reads that split. maisecrets only, personal data only, span level, strict recall, P (V3). No labelled value that 0.8.1 masked whole is missed by 0.8.2 (release-gate.md).

maisecrets 0.8.1 and 0.8.2 on the full splits
SplitRecallP (V3)False alarms
Nemotron-PII
val66,240 values .609 → .626 .9953 → .9953 180 → 183
holdout68,086 values .602 → .619 .9950 → .9950 196 → 198
Mendeley financial
val51,592 values .687 → .702 .9906 → .9894 338 → 391
holdout52,450 values .683 → .699 .9898 → .9887 371 → 421
Gretel finance
val25,894 values .281 → .304 .8960 → .8936 855 → 952
holdout26,718 values .279 → .304 .9054 → .9040 793 → 879
Privy
test, never read11,247 values .241 → .250 .9767 → .9771 65 → 66

Recall rises on every dataset. Precision falls a little on Mendeley and Gretel. Gretel does not label some values in key: value lines that 0.8.2 now masks, such as Italian tax codes, Swedish personal numbers, names, streets and phone numbers; they count as false alarms. On Mendeley, most new false alarms are address hits in a few sentence templates. Result files: bench/results/2026-10-25-v3-0.8.1 and bench/results/2026-10-26-v3-0.8.2.

Limits. All four PII datasets are synthetic. Nemotron-PII and Gretel leave some real values without a label, so precision there is a lower bound for every tool. The tools have different aims, so the benchmark gives no overall rank. Method: BENCHMARK-V3.md. Result files: bench/results/2026-10-21-v3/run.

Measure it yourself. You can reproduce a release benchmark in about 10 minutes and compare your result with ours case by case: docs/REPRODUCE.md. We tested the steps with v0.8.12: a fresh clone on a laptop gave the same counts as our reference server, for all 28,165 cases.

What it is tested on

The public data sets link to their source. The results link to BENCHMARKS.md in our repository, with the version, the licence and the command to repeat each measurement.

Our own sessions

The problem comes from our own work. Over 3,254 Claude Code sessions (5,260 transcripts, May to September 2026) we counted 185 real secrets: 148 never passed our MCP gateway, 27 came out of a gateway result, and 10 went into a gateway call. The same sessions held more than 1,000 e-mail addresses of people outside the company. The full count.

At the release of 0.6.17, 771 of our own typed prompts went through the hook, with no new block against 0.6.16. These prompts are not published: the number can be read, but not repeated.