SOWA Privacy for Developers

Install from source

SOWA Privacy is shipped via the Chrome Web Store as a binary, but the source is open for inspection and personal use under the Source-Available licence in LICENSE. To build and load it locally:

git clone https://github.com/Sowa-Privacy/sowa-privacy-chrome-extension.git
cd sowa-privacy-chrome-extension
npm install
npm run build

Then open chrome://extensions/, enable Developer mode, and click Load unpacked on the dist/ folder.

Three heavy vendor bundles

Built once with esbuild before Vite runs, so the production build is fully self-contained:

  • web-llm.bundle.js – ~5.4 MB – local LLM inference (optional, opt-in).
  • transformers.bundle.js + onnx-wasm/* – ~32 MB – NER pipeline runtime (optional, opt-in).
  • file-parsers.bundle.js + pdf.worker.min.mjs + xlsx-worker.bundle.js – ~2 MB – PDF, DOCX, XLSX parsing for the file-upload interceptor.

What's inside

manifest.json                 Chrome MV3 manifest (single source of truth for version)
contentScript.js              MV3 content script entrypoint
service_worker.js             MV3 service worker (stateless)
offscreen.js                  Offscreen doc for NER inference

lib/
  constants.js                DEF_CONFIG, PRESET_PATTERNS, NER_MODELS,
                              WEBLLM_MODELS, INDUSTRY_BLACKLISTS
  pii-core.js                 detectPII, mergeDetectionHits, blacklist + regex pipeline
  ner-detector.js             NER pipeline + diagnostic state surface
  ui-utils.js                 shouldUseRegex / NER / LLM helpers, theme, debounce
  ui_i18n.js                  t() + RESOURCES (4 locales) + applyI18n
  cs/
    owl-guardian.js           Owl widget Shadow DOM, continuous scan, badge counter
    upload-interceptor.js     File drag/drop / file input intercept
    host-matcher.js           contentIntegration.entries pattern matching

tests/unit/                   688 unit tests – keep green
scripts/                      esbuild bundle + zip packaging

Privacy guarantees

These are the rules enforced in code, not just promises in marketing copy:

  • No telemetry, no analytics, no first-party server calls – with one narrowly-scoped exception: the user's own entitlement check (a single auth'd POST to /api/entitlements/me that returns nothing but the user's plan flags). Cached for an hour. No PII, no prompts.
  • NER defaults OFF, opt-in only – the NER model is a 65 MB third-party download (HuggingFace). It never starts loading until the user explicitly checks the toggle in Settings.
  • Local LLM defaults OFF, opt-in only – same rule. WebLLM models are large; downloading one is the user's decision.
  • Owl is site-scoped – the content script registers on <all_urls> for lifecycle hooks, but detection, model pre-warm, and the owl widget only run on the seven hosts in contentIntegration.entries (ChatGPT, OpenAI, Claude, Gemini, Copilot, Grok, x.ai).
  • CSP forbids dynamic code execution'wasm-unsafe-eval' for ONNX is allowed; 'unsafe-eval' is not. No Function-from-string, no eval-driven plugins.
  • Promises only for chrome.* APIs – no callback shape that obscures error handling.
  • Stateless service worker – MV3 terminates aggressively; persistence lives in chrome.storage, not in module globals.

Tests

Tests are the primary correctness gate. As of v1.2.5.x: 688 of 689 passing in 17 suites. New code must keep this green.

npm run test:unit:nocov   # fast loop during development (~3s)
npm run test:unit          # CI gate with coverage
npm run typecheck          # tsc --noEmit
npm run lint               # eslint

Bug fixes follow a TDD shape: write the failing test first, fix the bug, the test stays as a regression guard. Real example shipped in tests/unit/lib/ner-detector.test.js – the "detect-counter does NOT reset on subsequent init successes" test was written before its corresponding fix and caught a bad first attempt at the implementation.

Contribute

Contributions back to the official repository are welcome under the licence terms. Open an issue or submit a pull request following the engineering standards in CONTRIBUTING.md:

  • Branch from main. One logical change per PR.
  • Commit message convention: type(scope): description (vX.Y.Z.W).
  • Update MIGRATION_LOG.md for non-trivial changes (new modules, contract changes, architectural shifts).
  • Pre-submit checklist for PRs touching detection or networking: no new fetch() to a first-party server, no new telemetry, no heavyweight component auto-enabled, anything you store goes into the migration log, any new permission is justified for the Chrome Web Store reviewer.

Responsible disclosure

For security vulnerabilities, please do not open public GitHub issues. Email a detailed report to security@sowaprivacy.ai:

  • Clear description of the vulnerability.
  • Steps to reproduce.
  • Affected version (the version field in manifest.json).
  • Impact assessment if you have one.
  • Suggested fix if applicable.

We commit to acknowledging your report within 72 hours, providing a status update within 7 days, crediting you in the release notes (unless you prefer anonymity), and coordinating public disclosure timing with you.

The published scope, examples of what we consider a vulnerability, and a Hall of Fame are in SECURITY.md at the root of the repository.