friskme

Sensitive data

Every scan checks all the text in your sessions for secrets and personal data:

  • what you typed
  • tool input and output
  • the agent’s replies
  • subagent runs

On a month of history (about 95M characters) this takes a few seconds. It runs locally, and nothing is sent anywhere for it.

Rules (always on):

  • Secrets: about 45 provider rules derived from the gitleaks defaults (MIT), including AWS, Google, Azure, GitHub, GitLab, Slack, Stripe, OpenAI, Anthropic, Hugging Face, npm, Linear, Vault, private keys, JWTs and credentials in URLs. Placeholders, doc examples and local dev passwords (postgres:postgres@localhost) are ignored.
  • Personal data: recognizers modeled on Presidio’s (MIT), each with a validator:
    • emails
    • credit cards (Luhn checked; published test cards are ignored)
    • IBANs (mod-97)
    • US SSNs (only with a context word)
    • phone numbers (formatted, or with a context word)
    • public IP addresses
    • crypto wallets

--pii-model (opt-in): names and places need a model, so friskme can also run bert-base-NER (MIT) on your machine.

  • Download: the first run asks before downloading about 190 MB. Most of it is the model (109 MB, from huggingface.co); the rest is the ONNX Runtime package from registry.npmjs.org, of which only your platform’s library (~30 MB) and its Node binding (~0.3 MB) are kept. It’s available on macOS (Apple silicon or Intel) and Linux x64. Every file is checked against a SHA-256 pinned in friskme, and a mismatch deletes the file and stops. It installs into ~/.frisk/models (set FRISK_MODELS_DIR to move it), and later runs work offline.
  • Scope and speed: by default it reads what you typed and the agent’s replies, about 1.3M characters, in under a minute (roughly 6k tokens/s on an Apple M-series laptop). --pii-model-scope all adds tool input and output and subagents; that can take tens of minutes on a month of history. Results are cached per chunk, so re-runs only scan new text.
  • What it reports: names with two or more words, at high confidence. Places are listed in report.json only.
  • Effect on the analyzer: names it finds are also masked in the cards sent for labeling.
  • Management: friskme models list shows the size and verifies every hash; friskme models remove deletes the model.

What the report shows:

  • Values are always masked: ghp_…(40), j•••@a•••.io, •••• 1486, J. D..
  • Each value has a salted fingerprint, so repeats are counted without being stored. The salt is random per install, in ~/.frisk/salt.
  • By default, no raw value is written to report.html, report.json, the cache or the terminal.
  • --reveal shows the real values in report.html and report.json, so you can check each finding:
    • Both files are written readable by you only (0600).
    • The report opens with a warning not to share it, and the terminal says so too.
    • Raw values still never go into the cache: names the model found earlier are recovered from the text being scanned, by matching fingerprints.
  • Low-confidence matches (generic key = … assignments, bare IPs, places) are listed in report.json only.

A secret listed under Rotate appeared in a session, so it was sent to the model provider with the rest of that conversation. Treat it as exposed.