How iVibe hides your secrets before anything leaves your computer
A developer's screen is full of keys. Here's how they get painted over first, and how the code makes skipping that step hard. Fix records your screen, and a developer's screen is a dangerous thing to record. There's a token in the terminal, a .env file in the next tab, and a password manager one click away. If iVibe sent those frames to a model as they are, your secrets would leave with them. So every frame is cleaned on your computer first. Here's how.
Read the screen on your device
Each frame iVibe keeps goes through OCR that runs locally, using PP-OCRv5. This turns the pixels into lines of text with positions, so iVibe knows what is on screen and where, without sending anything anywhere.
Look for the shape of a secret
OCR makes mistakes. It reads l as 1, O as 0, and sometimes _ as a space. So the rules describe what a secret looks like, not its exact characters, and they run in layers:
Known formats: Meta, Anthropic, OpenAI, AWS, GitHub, Google, Stripe and Slack keys, JWTs and private keys.
Assignments: anything like password= or api_key:. The value is hidden and the name stays, so the prompt still makes sense.
Lines from a .env file and connection strings.
Random-looking text: some keys have no fixed prefix, so long strings with high entropy are hidden too.
Password managers: if one is on screen, the whole frame is blacked out.
Paint, don't blur
Blur keeps some of the original information, and blurred text can sometimes be recovered. iVibe paints a solid black box onto a copy of the image, so those pixels are gone from anything that gets sent. $ npm run deploy $ export GITHUB_TOKEN= Error: deploy failed at step 3 An illustration: the name stays, the value is gone. The text gets the same treatment. Each secret character in the OCR lines becomes a dot, so the words sent alongside the image are safe too. When you edit selected text by voice, a secret becomes a placeholder like [[secret-1]], and the original is put back on your computer afterwards.
Make forgetting hard
A rule like “always redact first” only holds until someone forgets, so iVibe's code enforces it in two ways. Encoders and uploaders only accept a RedactedFrame, and only the redaction package can create one, so passing a raw frame fails to compile. A type cast could still get around that, so the frames that package creates are also recorded at runtime, and encoders check that record before touching a frame.
typescript /** The only frame type that encoders, the bundle writer and uploaders accept. */ export interface RedactedFrame { readonly image: ImageBitmap; readonly boxes: readonly Redaction[]; readonly [brand]: true; } /** Encoders call this too, so a type cast can't smuggle in a raw frame. */ export function assertRedacted(frame: object): asserts frame is RedactedFrame { if (!issued.has(frame)) throw new Error("unredacted frame"); }
Raw frames also stay in memory and are never written to disk. And the app's self-test plants a GitHub token on screen and fails if it isn't painted over.
What it can't promise
This is automatic, and it can miss things. It looks for secrets, so a private message or a customer's name on screen isn't hidden. Keep anything you'd never share off screen while you record. Copy code Download iVibe Read the code