Kenya-localized, on-device PII redaction — a thin wrapper around Rampart that scrubs Kenyan identifiers (KRA PIN, M-Pesa, National ID, SHA/SHIF, phone, etc.) in the browser before data leaves the device.
# rampart-ke
**Kenya-localized, on-device PII redaction.** A thin wrapper around
Rampart (National Design Studio) that scrubs
Kenyan personal data **in the browser, before any byte leaves the device** — so it never reaches a
server, a log, or a foreign AI API.
This is built for the Kenyan Data Protection Act, 2019 reality: the only
data you can be sure stays in the country is the data that never leaves the user's device.
---
## How it works
Two layers run locally, in order:
1. **Kenyan deterministic layer** (this package) — regex/validator recognizers for structured local
identifiers. They mint friendly placeholders like `[KRA_PIN_1]`, `[MPESA_CODE_1]`.
2. **Rampart model** — the upstream 14.7 MB quantized ONNX MiniLM catches names and addresses, and
keeps coarse geography (towns / counties) for analytics.
```
user text
→ Kenyan recognizers → mask KRA PIN, M-Pesa, phone, IDs, orgs, estates …
→ Rampart guard → mask names / addresses (model) + email/URL/IP/SSN/card (heuristics)
→ placeholdered text → safe to send to an LLM or server
assistant reply
→ guard.reveal() → restores the real values, on-device, for display
```
Real values live only in an in-memory table on the client. Only placeholdered text leaves the device.
## Install
```bash
npm install rampart-ke @nationaldesignstudio/rampart @huggingface/transformers
```
## Usage
```ts
import { createKenyanGuard } from "rampart-ke";
const guard = await createKenyanGuard(); // loads the on-device model (cached after first run)
const { text, entities } = await guard.protect(
"QFT3X1AB9Z Confirmed. Ksh2,500 sent to John Ochieng 0712345678. KRA PIN A012345678Z.",
);
// text → "[MPESA_CODE_1] Confirmed. Ksh2,500 sent to [GIVEN_NAME_1] [SURNAME_1] [KE_PHONE_1]. KRA PIN [KRA_PIN_1]."
const reply = await callYourLLM(text); // the model only ever sees placeholders
const shown = guard.reveal(reply); // real values restored locally before display
```
For a quick one-off without mana …