[New Plugin] peyeeye PII redaction & rehydration#1621
Open
tim-peyeeye wants to merge 1 commit into
Open
Conversation
Adds a new guardrail plugin that wraps the peyeeye PII API (https://api.peyeeye.ai). Two functions: - peyeeye/redact (beforeRequestHook): batches every text-bearing chunk of the request through POST /v1/redact, writes the placeholder-token text back via setCurrentContentPart, and caches the returned session id (or sealed skey_ blob in stateless mode) on the request id. - peyeeye/rehydrate (afterRequestHook): reads the cached session, POSTs the model output through /v1/rehydrate, swaps the original PII back in, and best-effort DELETEs the session for stateful mode. Behavioral invariants the implementation preserves (matches the peyeeye litellm guardrail, BerriAI/litellm#26546): - Length-guard: if /v1/redact returns a different number of texts than were sent, raise; never forward partially-redacted data. - Unexpected response shape raises rather than passing through. - Multimodal content list parts are handled (text parts redacted, non-text parts left untouched at their original indices). - Stateless mode (session: "stateless") returns rehydration_key (skey_...) and skips the DELETE step. 11 jest tests, all mock-only (mock post from ../utils and a local fetch mock for DELETE).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves #1620.
Summary
A new guardrail plugin that wraps peyeeye's PII redaction & rehydration API. The plugin runs a round-trip across both hooks:
beforeRequestHook—peyeeye/redact: extracts every text-bearing chunk of the request viagetCurrentContentPart, batch-POSTs to/v1/redact, writes the placeholder-token text ([EMAIL_1],[CARD_1], …) back viasetCurrentContentPart. Caches the returnedsession_id(or sealedskey_…blob in stateless mode) keyed onpeyeeye:session:${context.metadata.requestID}.afterRequestHook—peyeeye/rehydrate: pulls the cached session, POSTs the model's response text through/v1/rehydrateso end-users see the real PII values, then best-effortDELETE /v1/sessions/{id}for stateful mode and clears the cache entry. No-ops cleanly if the cache miss (so it's safe to enable on routes where redact wasn't run).The original PII never reaches the upstream LLM, but the response the gateway hands back to the user contains the original values.
Files
plugins/peyeeye/manifest.json— two functions (redact,rehydrate); credentialsapiKey(encrypted) + optionalapiBase; per-function parameterslocale,entities,sessionMode.plugins/peyeeye/globals.ts—callRedact,callRehydrate,callDeleteSession, cache-key builder, typed errors. Reusespost()from../utils; uses nativefetchfor the DELETE.plugins/peyeeye/redact.ts— pre-call handler.plugins/peyeeye/rehydrate.ts— post-call handler.plugins/peyeeye/peyeeye.test.ts— 11 mock-only Jest tests.plugins/index.ts— adds the two handler imports +peyeeye: { redact, rehydrate }entry.conf.json— adds"peyeeye"toplugins_enabled.Features
stateful(default) — peyeeye stores the token→value mapping under ases_…id;DELETEd after rehydration.stateless— peyeeye returns a sealed AEAD blob (skey_…); nothing retained server-side; no DELETE.entitiesparameter.localeknob (defaultauto).[{type:"text",text:…},{type:"image_url",…}]content list are redacted in place; non-text parts are left untouched at their original indices.Behavioral invariants
/v1/redactreturns a different count of texts than were sent, raise — never forward partially-redacted data./v1/redactraises rather than passing through silently.Tests
11 Jest tests, all mock-only (no real network). The
post()helper from../utilsis mocked viajest.mock; the DELETE path uses a per-testglobal.fetchmock. Coverage:session_id).rehydration_keyand sendssession: "stateless".skey_…sessions skip DELETE.Test plan
npm run test:plugins -- plugins/peyeeye— 11 / 11 passingnpm run test:pluginsbaseline is unchanged (other failing suites are pre-existing real-network tests against external vendor APIs)npx tsc --noEmitshows no new TS errors inplugins/peyeeye/