Docs · Privacy masking

Privacy masking

magpie can mask what your agents send before it leaves this computer. API keys, passwords and tokens, and when you ask, emails, phone numbers and words of your own, go to the vendor as placeholders such as {{API_KEY_es6eu6jk}}. In the reply each placeholder turns back into its value, so your agent and your files keep the real thing and the vendor never sees it. It runs on this computer, in magpie’s gateway, and is off by default.

It covers what goes through magpie. An agent connected to magpie sends its requests through the gateway, and they are masked whichever provider or account answers. An agent that calls a vendor directly, not through magpie, is not covered.

Turn it on

  1. Open the pageGo to Settings → Privacy.
  2. Mask secretsUnder What to mask, set Mask secrets to On: API keys, private keys, tokens and passwords.
  3. Personal data, if you want itSet Mask personal data to On for emails, phone numbers, ID and bank card numbers. Each further kind of personal data then gets its own switch below it.
  4. Your own wordsIn Masked words, list names, codenames or hosts to keep from vendors, separated by commas. Masked words in any case makes Nightjar mask NIGHTJAR too. A secret magpie doesn’t know, such as your gateway’s own keys, goes under Masking rules: what it starts with, or a regular expression.
  5. Try itPaste a text into Try it to see exactly what the vendor would get. What you paste there isn’t kept.

It applies from the next request, with no restart and nothing to change in your agent. The work is done by the built-in plugin Privacy masking (redact, in Settings → Plugins), which is on whenever any masking is asked for.

There is no CLI command for it. Without the window (magpie serve, Docker), open the same page with magpie web, or set it in ~/.config/magpie/settings.json (/config/magpie/settings.json in Docker). The masker reads the file on every request:

settings.json
{
  "redact": true,
  "redactPersonal": true,
  "redactWords": ["Nightjar", "db.acme-corp.cn"]
}

What is masked

SwitchWhat it finds
Mask secretsPrivate key blocks (-----BEGIN … PRIVATE KEY-----). API keys by their shape: sk-… (OpenAI, Anthropic, OpenRouter), ghp_/github_pat_, glpat-, AIza…, xox…-, sk_live_, AKIA/ASIA, hf_, gsk_, xai-, npm_, pypi-, dop_v1_, SG., and relay keys like oc_sk_…. JWTs. The password in user:password@host. The value of a field named for a secret, as .env files and configs have them: DB_PASSWORD=…, api_key: …, client_secret, token, credential. Your own Masking rules.
Mask personal dataEmails, mainland China mobile numbers, Chinese ID numbers and bank card numbers whose checksum adds up. Also on by default: US Social Security numbers, passport numbers (after passport, 护照 or パスポート), IBANs, birthdays (next to birthday, DOB or 生日), MAC addresses and serial numbers (after S/N). Off until you turn them on, since agents send them in nearly every request: the user name in home folders, user and computer names (user@host), public IP addresses and cloud storage buckets.
Masked wordsEach word you listed, exactly, as {{TERM_…}}.
Find with a local modelUnder How it’s found. A model on this computer (OpenAI’s Privacy Filter, a 1.6 GB download) finds what no rule can: a name or an address in free text. It needs Mask secrets or Mask personal data on, and finds under the same switches.

A placeholder is the kind plus eight characters of a keyed hash. The same value gets the same placeholder every time, so the conversation reads the same turn after turn and the vendor’s prompt cache stays valid. The values are held in memory only.

An example

With Mask secrets and Mask personal data on and Nightjar in Masked words, your agent sends:

Your agent sends
Deploy Nightjar with OPENAI_API_KEY=sk-proj-8fK2mQx7Lp4Rt9Vw3Yz6Ab1Cd, then mail li.wei@acme-corp.cn or call 13800138000.
The vendor gets
Deploy {{TERM_5hmsrhdc}} with OPENAI_API_KEY={{API_KEY_srhjgvja}}, then mail {{EMAIL_eh5um6mb}} or call {{PHONE_uf7iy2qq}}.

When the model answers “I set OPENAI_API_KEY to {{API_KEY_srhjgvja}} in .env”, your agent reads the real key there, in streamed text and tool-call arguments alike, so the file it writes has the real key. A placeholder the model rewrote a little (spaces inside the braces, another case) is still turned back.

Check that it works

The records are kept in ~/.config/magpie/masking for 30 days: the agent, provider, model, and each placeholder’s kind, length and first characters, never the value.

When a value is found

Under When a value is found, choose per kind:

A value the task needs as it is, such as a team address or a test key, goes in Never mask: it is sent as written wherever it is found whole.

What it leaves alone, and limits

See also Privacy for everything magpie sends by itself. The code is internal/redact and internal/masking.