Skip to content
CertaMeshPublic

About

Reversible PII pseudonymization runtime for agentic LLM workflows.

Resources

Code of conduct

Contributing

Security policy

Stars

12 stars

Watchers

0 watching

Forks

Latest commit

 

History

1,574 Commits

Folders and files

Gaze

Crates.io License docs.rs Tests GitHub stars

Gaze replaces personal details with placeholders before an AI model sees them, then restores them in the reply. The model sees <Name_N>; your server keeps the originals in a restore manifest. The goal is zero PII bytes reaching the model outside that contract.

Pre-1.0: the API is stabilizing. Older minor-version manifests restore on newer minors (UPGRADE.md).

Gaze replaces personal details before the model and restores them after; the manifest stays on your server.

Gaze controls outbound PII. It does not defend against prompt injection or filter unsafe content. Tool-call JSON carries placeholders too; Gaze restores them before the tool runs (integration).

How good is it

The v0.17.0 measurements pass the accepted own-policy numeric and external F2 criteria. Strict own-policy identity remains not_comparable, and TRACE's original net-byte gate fails. Results and limits retain the measured source and provenance. The own-corpus panel includes tagged v0.17.0. Fresh external byte-micro results appear first; historical external character panels keep their measured version labels.

The tagged-release benchmark panels compare the gaze setup policy with Presidio, DataFog, scrubadub, GLiNER and OPF on their declared configurations. “Leaked” counts PII bytes still reaching the model. The target is zero.

One byte-micro F2 panel per dataset, Gaze v0.16 and v0.17 with measured competitors; leaked PII bytes under each bar.

Gaze v0.17.0 leaks 9,717 PII bytes on our holdout under contract v4 (byte-micro F2 0.901). All five panels use byte-micro F2 and leaked bytes. † marks competitor results awaiting receipt regeneration. Measurements, setups and limits.

How does it work

Steps 1 to 4, normalize, recognize, resolve and swap, are the deterministic floor. Step 5, the safety net enabled by the gaze setup policy, and step 6, the output check, give a second opinion. The AI model sees placeholders only, and step 7 restores the reply.

  1. Bundled rules find structured details using formats, checksums and cues.
  2. NER finds names and places.
  3. The resolver picks one candidate per span; Gaze emits a placeholder and manifest entry. Each session has its own placeholder namespace. Placeholders trace to rules or recognizers.
  4. The gaze setup policy runs local Nym to find missed PII and tokenize it.
  5. Restore replaces issued placeholders with originals. Unknown placeholders are refused.

Gaze fails closed on missing configured models and unknown rules. Unresolvable safety-net suspects become one-way [REDACTED:<class>] markers or cause refusal. Only tolerant development mode lets them through.

How Gaze works covers the seven steps, a support ticket and safety-net modes.

Quickstart

With Rust and jq installed, clean and restore a synthetic contact. Setup needs network access to download the pinned models:

cargo install gaze-cli --version 0.17.0
gaze setup --non-interactive
printf 'From: %s %s <%s@%s>' Ada Example ada example.invalid | gaze clean --policy gaze.toml > clean.json
jq -r .clean_text clean.json
jq '{session_blob, text: .clean_text}' clean.json | gaze restore | jq -r .text

The first line is model input; the second is restored output. For publication, sed removes session prefixes and replaces @ with [at].

$ jq -r .clean_text clean.json | sed -E 's/<[0-9a-f]{8}:([A-Za-z]+)_[0-9]+>/<\1_N>/g'
From: <Name_N> <<Email_N>>
$ jq '{session_blob, text: .clean_text}' clean.json | gaze restore | jq -r .text | sed 's/@/ [at] /'
From: Ada Example <ada [at] example.invalid>

gaze setup verifies pinned NER and Nym bundles, writes gaze.toml with Nym on, and checks both detectors. It prints Nym's MIT model licence and the open training-data licence review. Use gaze setup --safety-net none for NER only. OPF stays opt-in.

gaze setup --dob-judge installs a SHA-pinned local GLiNER bundle and enables cue-less birth-date judgments. It stays opt-in while its bundle is 352 MB: the benchmark reduces leaked DOB bytes from 810 to 725, adds no false-positive bytes, and adds 664 MiB peak memory (mechanism arms). --dob-model-dir <path> selects its directory. Setup checks a synthetic birth date before writing the policy.

Send only clean_text to the model. Keep clean.json and its session_blob on your server: the blob contains originals and is needed for restore.

Where next

Install

Install the CLI from crates.io:

cargo install gaze-cli --version 0.17.0

Or build from source (latest main, or to enable extra features):

git clone https://github.com/CertaMesh/gaze.git
cd gaze
cargo install --path crates/gaze-cli

Pre-built binaries are attached to each GitHub release, with a matching .sha256 file:

Platform Artifact
Apple Silicon macOS gaze-aarch64-apple-darwin
Linux x86_64, glibc 2.39+ gaze-x86_64-linux-gnu
Linux arm64, glibc 2.39+ gaze-aarch64-linux-gnu

Use the arm64 Linux binary in arm64 containers, including containers on Apple Silicon. Other targets: cargo build --release -p gaze-cli.

For the LLM API proxy, after the quickstart:

gaze proxy start --policy gaze.toml
export OPENAI_BASE_URL=http://127.0.0.1:8787/v1
export ANTHROPIC_BASE_URL=http://127.0.0.1:8787

Claude Code also needs an explicit beta allowlist. See proxy setup for the flags, supported request shapes, and documented refusals.

From a source checkout, for MCP hosts (Claude Code, Claude Desktop, Cursor):

cargo install --path crates/gaze-cli --features mcp
gaze mcp install --client=claude-code
gaze mcp doctor

The MCP server exposes gaze_read_file and gaze_read_text, returning tokenized content plus a manifest_id for authorized restore flows. It uses bundled rules, without the NER or Nym models from gaze setup. Client config paths: crates/gaze-cli/README.md.

For library use, see Use the gaze setup policy from Rust.

Workspace and crates.io

Choose from the 15 published crates in the crate map. For the Rust runtime (package gaze-pii, library name gaze):

cargo add gaze-pii

The core has no rusqlite dependency; SQLite auditing lives in gaze-audit. Document codec extensions.

Contributing

See CONTRIBUTING.md for local gates and signed DCO commits (git commit -S -s, no CLA). Governance: docs/explanation/governance.md.

License

Dual-licensed under either of Apache-2.0 or MIT, at your option.

About

Reversible PII pseudonymization runtime for agentic LLM workflows.

Resources

Code of conduct

Contributing

Security policy

Stars

12 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages