Security Considerations for Automattic/harper: Privacy-First Grammar Checking
Harper processes all text locally using WebAssembly, Rust native binaries, or language servers, ensuring user content never leaves the machine or transmits over networks.
Understanding the security considerations for Automattic/harper reveals a privacy-first architecture designed to eliminate external attack vectors. Unlike cloud-based alternatives that stream keystrokes to remote servers, Harper operates entirely within the user's environment through sandboxed WebAssembly modules, native CLI tools, and local language servers. This offline-first approach ensures complete data sovereignty while maintaining functionality across desktop applications, browser extensions, and editor integrations.
Local-Only Processing Architecture
Harper's core security guarantee rests on its local-only processing model. The grammar engine runs as a native binary via harper-cli, as a WebAssembly module in harper-wasm, or as a language server through harper-ls—all without network dependencies.
In harper-core, the Linter struct performs all text analysis in-process. The LocalLinter class in the JavaScript bindings loads the WASM module directly into the runtime environment, ensuring that sensitive documents remain in memory without external transmission. The component boundaries enforcing these isolation guarantees are documented in ARCHITECTURE.md, which details how the core engine remains separate from platform-specific I/O operations.
WebAssembly Sandbox
The harper-wasm package executes within the browser's or Node.js's WebAssembly sandbox, which provides memory isolation and prevents direct filesystem or network access. As documented in harper-wasm/README.md, this sandboxing limits the impact of potential code-execution vulnerabilities by restricting the grammar engine to a confined execution environment with no system call privileges.
No External API Dependencies
Harper does not call external APIs for spelling suggestions, language models, or analytics. This eliminates risks associated with third-party data breaches or man-in-the-middle attacks that plague services requiring cloud connectivity for core functionality.
Data Privacy and Persistence
Harper implements data isolation by design, minimizing persistent storage and eliminating telemetry entirely.
User Dictionary Storage
The only data Harper persists is the optional mutable user dictionary, stored as a plain-text file named dictionary.txt in the application's configuration directory. The implementation in harper-desktop/src-tauri/src/config.rs handles this storage without encryption requirements, as it contains only user-added words rather than full document content. No grammar rules, document text, or usage patterns are cached between sessions.
Zero Telemetry Policy
According to the README.md, Harper emits no telemetry and maintains no network requests for analytics, spelling suggestions, or language model inference. This eliminates the data exfiltration risks common in third-party grammar services that rely on external APIs for core functionality.
Platform-Specific Security Models
Different Harper distributions employ platform-appropriate security controls to maintain isolation between components.
Tauri Desktop Security
The harper-desktop application uses Tauri v2, which enforces a strict permission model between the frontend and backend. The Svelte-based UI communicates with the Rust backend via a JSON-line protocol over stdin/stdout, as implemented in harper-desktop/src-tauri/src/communication/message.rs. All messages serialize through Rust structs, preventing injection attacks that could arise from raw string parsing.
Native OS calls—such as the screen-overlay highlighter—require explicit user consent through Tauri's permission system. The highlighter subprocess communicates via newline-delimited JSON, ensuring that arbitrary code execution cannot occur through message parsing.
Browser Extension Permissions
The Chrome and Firefox extensions declare minimal permissions limited to activeTab and storage access. As documented in packages/chrome-plugin/README.md, these extensions perform linting using the locally-loaded WASM module rather than background networking, preventing cross-origin data leakage or man-in-the-middle attacks during text analysis.
Development and Supply Chain Security
Harper maintains security through dependency management and contributor policies that prevent supply chain compromises.
Dependency Auditing
The project uses cargo audit for Rust dependencies and npm audit for Node.js packages to surface known vulnerabilities. While the pnpm-lock.yaml file contains some legacy dependency warnings (such as older glob versions), the CI pipeline actively monitors these advisories. Regular updates to the lockfile ensure that development tooling does not introduce exploitable components into the build chain.
Contributor Security Policies
The AGENT_POLICY.md file establishes strict security boundaries for contributors, explicitly forbidding secret leakage, arbitrary code execution, or filesystem access outside the repository boundary. This policy integrates with CI automation to prevent malicious contributions from compromising the build artifacts distributed to users.
Implementation Examples
The following examples demonstrate Harper's privacy-preserving APIs operating entirely offline:
// harper.js – using the WASM build in a Node script
import { LocalLinter } from "harper.js";
(async () => {
const linter = await LocalLinter.create(); // loads WASM locally
const result = await linter.lint(
"Their is a mistake in this sentence."
);
console.log(result); // only local output
})();
// harper-core – calling the core library directly
use harper_core::lint::Linter;
fn main() {
let linter = Linter::new(); // pure Rust, no I/O
let diagnostics = linter.lint("She has a dog.");
println!("{:?}", diagnostics);
}
# CLI – lint a file without sending data anywhere
harper-cli lint path/to/document.txt
All three execution paths—JavaScript WASM, native Rust, and command-line interface—process text without network transmission, ensuring complete data containment within the host environment.
Summary
- Local-only processing ensures text never leaves the machine through
harper-wasm,harper-cli, orharper-lsimplementations. - WebAssembly sandboxing restricts the grammar engine's access to system resources and network interfaces.
- Minimal data persistence stores only user-defined dictionaries in
dictionary.txtviaharper-desktop/src-tauri/src/config.rs, with no document caching or telemetry. - Tauri security model isolates the desktop UI from native OS calls using structured JSON communication in
harper-desktop/src-tauri/src/communication/message.rs. - Supply chain protection relies on
cargo audit,npm audit, and theAGENT_POLICY.mdcontributor guidelines to prevent dependency vulnerabilities and malicious code insertion.
Frequently Asked Questions
Does Harper send my text to cloud servers?
No. Harper operates entirely offline without external API calls. The README.md explicitly states that no network requests occur during linting, and the harper-core library processes text in-memory without transmission. This applies to all distribution formats: CLI, WebAssembly, language server, and desktop application.
What data does Harper store locally?
Harper persists only the optional user dictionary as a plain-text file (dictionary.txt) in the configuration directory, as managed by harper-desktop/src-tauri/src/config.rs. The software does not cache documents, grammar corrections, or usage patterns. No telemetry data is collected or transmitted.
How does Harper handle security in browser extensions?
The browser extensions (Chrome/Firefox) request only activeTab and storage permissions per packages/chrome-plugin/README.md. Linting occurs within the WebAssembly sandbox using locally-loaded code, eliminating background network requests that could expose sensitive text to third parties.
What measures prevent code injection in the desktop app?
The Tauri-based desktop application uses structured JSON serialization over stdin/stdout for inter-process communication, defined in harper-desktop/src-tauri/src/communication/message.rs. This approach avoids raw string parsing vulnerabilities. Additionally, native OS access requires explicit user consent through Tauri's permission system, preventing unauthorized file system or network operations.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →