Skip to content

Repository files navigation

Atrium Browser Lite

Choose the privacy regulations and regions you want to protect against. Atrium masks the matching sensitive data before it ever reaches an AI chat — locally, with zero telemetry.

A Manifest V3 browser extension that intercepts outgoing chat requests on ChatGPT, Claude, Gemini, Microsoft Copilot, Grok, and Perplexity, replaces detected sensitive data (API keys, emails, phones, credit cards, names, and region-specific government & financial identifiers) with reversible placeholders, sends the masked prompt to the LLM, and (optionally) restores the original values when the response streams back.

Open source. No backend. Built in Jakarta — made for everywhere.

License: MIT Manifest V3 Platforms

Why

Anything you paste into an AI chat can become training data, log data, or third-party data — depending on the provider's policy that week. And depending on where you operate, leaking it can breach a privacy law: GDPR (EU), UU PDP (Indonesia), PDPA (Singapore), the Privacy Act (Australia), or HIPAA / GLBA (US), among others.

Atrium lets you pick the regions and regulations you care about, then catches the matching identifiers — national IDs, tax numbers, health and financial identifiers, names, secrets — in your browser, before they leave. The masking runs locally; this extension has no backend of its own.

Pick your regions

Open the popup and choose the regions you operate in (or a preset: ASEAN, Australia, United States, Global). Only the detectors for active regions run, so you protect against exactly the regimes you need and nothing slows down that you don't.

Region Maps roughly to Detects
Global GDPR, PCI-DSS, secrets hygiene Email, phone, credit card (Luhn), API keys
Indonesia UU PDP NIK, NPWP, names, phone
Singapore PDPA NRIC, FIN, passport, UEN, phone
Australia Privacy Act / APP Medicare, TFN, ABN, ACN, phone
United States HIPAA, GLBA, state privacy laws SSN, EIN, driver license, passport, ABA routing, bank account, health id, phone
Malaysia PDPA (MY) MyKad, phone
Thailand PDPA (TH) Thai national ID, phone
Vietnam PDPD CCCD/CMND, phone
Custom your policy any term you add — exact, case-insensitive, or regex

The regulation mapping is a practical guide, not legal advice — Atrium masks identifiers, it does not certify compliance.

What's new in v0.2

  • Regions & regulations. Detection is grouped by region with presets and per-region toggles; only active regions' detectors run.
  • More platforms. Microsoft Copilot, Grok, and Perplexity, alongside ChatGPT, Claude, and Gemini.
  • Activity log. Full searchable/filterable history in IndexedDB with JSON/CSV export (still values-free — type, platform, domain, time only).
  • Per-domain controls. Pause/enable masking per site; allowlist or blocklist mode; a "this site" quick toggle in the popup.
  • Custom dictionary. Your own always-mask terms — exact, case-insensitive, or regex — with custom placeholder labels.
  • Per-detector enable/disable and a char-class fast path for large prompts.
  • Cross-browser. Chrome/Edge/Brave + a Firefox build target (see BROWSERS.md).

Install

  1. npm install && npm run build
  2. Open chrome://extensions → enable Developer mode → Load unpacked → pick the dist/ folder.
  3. Open the popup, pick your regions (or a preset), then send a prompt on any supported platform that includes an email, an ID from one of your regions, or an API key. Open the popup — you'll see it counted.

That's it. No account, no signup, no permissions beyond the supported chat domains.

What gets detected

Region Type Implementation
Global Email Standard pattern
Global Phone Local + generic international shapes
Global Credit card 13–19 digit + Luhn check
Global API keys Generic prefixes: sk-, AKIA, AIza, ghp_, xox*-, bearer, JWT
Indonesia NIK / NPWP / Name 16-digit NIK, dotted/plain NPWP, gazetteer+trigger names
United States SSN, EIN, driver license, passport, ABA routing, bank account, health id, phone dashed-only SSN/EIN, ABA checksum, trigger-gated fuzzy ids
Singapore NRIC, FIN, passport, UEN, phone NRIC/FIN checksum, distinctive + year-prefixed UEN, trigger-gated passport
Australia Medicare, TFN, ABN, ACN, phone all four confirmed by their public checksums
Malaysia MyKad, phone dashed shape + DOB sanity; bare form trigger-gated
Thailand Thai national ID, phone mod-11 checksum
Vietnam CCCD, CMND, phone CCCD province-prefix validated; CMND trigger-gated
Custom your dictionary entries exact / case-insensitive / regex with custom labels

Detectors are grouped by region and run only when their region is active (global always runs). This is intentionally a commodity catch — fast and good enough to surprise users with how much it picks up. Atrium for Teams uses the same detection core. What it adds is organizational: team policies, audit logs, compliance reporting, governance workflows, admin controls, and company-wide visibility into AI usage.

Privacy model

  • No outbound network calls of its own. The extension does not phone home. Verify in your Network tab — you won't see anything with atrium, monago, or any analytics host.
  • Local storage only. Counters, recent activity, and toggle states live in chrome.storage.local and never leave the device.
  • In-memory placeholder map. The map from [[PERSON_1]] back to the original value lives in page-session memory only. Cleared on tab unload.
  • No values are logged. The recent-activity log stores {type, platform, timestamp} only — never the original values, because logging values would defeat the whole point.

Permissions

Permission Reason
storage Local counters and toggle state
host_permissions: chatgpt.com Content scripts on ChatGPT
host_permissions: claude.ai Content scripts on Claude
host_permissions: gemini.google.com Content scripts on Gemini

No <all_urls>. No telemetry hosts. No third-party domains.

How it works (briefly)

Each platform tab loads two coordinated content scripts:

  • A MAIN-world script runs in the page's JS context at document_start, monkey-patches window.fetch, XMLHttpRequest, and navigator.sendBeacon before the page's own code captures references to them.
  • An ISOLATED-world script handles chrome.* calls — reporting detection events to the service worker for the popup, forwarding toggle state from storage to MAIN.

When a chat-send request goes out, MAIN's per-platform Shaper:

  1. Parses the request body (JSON for ChatGPT/Claude, form-encoded for Gemini).
  2. Runs the detector on every user-text string.
  3. Replaces matches with [[TYPE_N]] placeholders and rewrites the body.
  4. Forwards the masked request to the original fetch/XHR.

The response stream is wrapped so the user can optionally see the original values restored in the rendered reply (toggle in popup).

For deeper dives — including per-platform request-body shapes and the hard-won bugs we hit along the way (Gemini's relative URLs in xhr.open, the new Request(input, init) body-disturbance trap, etc.) — see src/main/runtime.ts and src/main/shapers.ts.

Build

Requires Node 18+.

npm install
npm run build           # → dist/ (Chrome / Edge / Brave)
npm run build:firefox   # → dist-firefox/
npm run build:watch     # incremental
npm run package         # → releases/*.zip (both targets)
npm run typecheck
npm run lint
npm run bench           # detector micro-benchmark
npm run audit:privacy   # local-only / zero-outbound guard
npm run format

Edge and Brave load dist/ unchanged. See BROWSERS.md for the WebExtension API audit and the in-browser validation checklist.

Repo layout

atrium-browser-lite/
├── public/                    # static, copied into dist/ verbatim
│   ├── manifest.json
│   ├── icons/                 # 16/32/48/128 PNGs
│   └── popup/
│       ├── popup.html
│       ├── popup.css
│       └── atrium-800x800.jpg
├── src/
│   ├── shared/                # used by all entry points
│   │   ├── types.ts
│   │   ├── detectors.ts       # region-tagged detector registry + engine
│   │   ├── regions.ts         # region taxonomy + presets
│   │   ├── platforms.ts       # supported platform hosts
│   │   ├── labels.ts          # type/platform display labels
│   │   ├── names-gazetteer.ts
│   │   ├── tokenizer.ts       # mask / unmask + placeholder map
│   │   ├── storage.ts         # stats, regions, domain rules, dictionary
│   │   ├── activity-db.ts     # IndexedDB activity history
│   │   ├── bridge.ts          # MAIN ↔ ISOLATED postMessage protocol
│   │   └── messaging.ts
│   ├── main/                  # MAIN-world (page context)
│   │   ├── runtime.ts         # fetch/XHR/beacon patches + tokenizer
│   │   ├── shapers.ts         # per-platform body parsers
│   │   └── (chatgpt|claude|gemini).ts
│   ├── content/               # ISOLATED-world (chrome.* bridge)
│   │   ├── integration.ts
│   │   └── (chatgpt|claude|gemini).ts
│   ├── background/
│   │   └── service-worker.ts  # local storage gatekeeper, no network
│   ├── popup/
│   │   └── popup.ts
│   ├── activity/              # activity-log page
│   ├── settings/             # site settings + detector toggles page
│   └── dictionary/           # custom dictionary page
├── build.mjs                  # esbuild config
├── package.json
└── tsconfig.json

Contributing

PRs welcome. Some directions where help would land well:

  • Selector resilience. Platforms ship UI updates; shapers occasionally need adjusting. Open an issue if you see masking stop working.
  • More detection types — keep it commodity and locally-runnable.
  • Other platforms — Mistral chat, Poe, Perplexity, Le Chat. Each needs a new Shaper in src/main/shapers.ts plus a content script registration in the manifest.
  • Translation — popup copy is currently English. Bahasa Indonesia and others welcome.

Before opening a PR: npm run typecheck && npm run build should pass clean. Keep diffs scoped — one feature or one fix per PR.

Roadmap

Shipped in v0.2:

  • Activity log page (full history beyond the 30-event ring buffer)
  • Per-domain pause (allowlist/blocklist + quick toggle)
  • Custom dictionary (local list of strings to always mask)
  • Regional detection (ID / US / SG / AU / MY / TH / VN) with presets and per-detector toggles
  • More platforms (Copilot, Grok, Perplexity)
  • Firefox build target — runtime validation pending (see BROWSERS.md)
  • Edge / Brave (Chromium) build — runtime validation pending

What's not in scope

Lite is a single-user tool: one browser, local storage, no central anything. It does not ship team policies, audit trails, compliance reports, SSO, admin controls, or cross-user visibility. Those are organizational concerns, not client-extension concerns.

Lite protects individuals. Atrium for Teams governs organizations.

Built by Monago

Atrium Browser Lite is open source under MIT and built by Monago — an Indonesian AI infrastructure company shipping privacy-first tooling for teams using ChatGPT, Claude, Gemini, and whatever comes next.

Talk to the founder

Maintained by Husein, founder of Monago. Help, feature requests, broken selectors, or AI-privacy chat: 📧 husein@monago.io — replied to personally.

For org-wide deployment (policies, audit logs, on-prem gateway) → Atrium for Teams.

License

MIT — do what you want with this, including forking, modifying, shipping inside other products, and using commercially. Attribution appreciated but not required.

About

Catch sensitive data before it reaches AI. Open-source browser extension that masks API keys, emails, NIKs, credentials, and other sensitive information in ChatGPT, Claude, Gemini, and more.

Resources

Stars

Watchers

Forks

Releases

Contributors

Languages