Repository navigation
pii_scrubber is never applied on the LLM verification path: raw evidence text is sent to OpenAI and Groq #430
Description
Activity
- addedbugSomething isn't workingSomething isn't workinghighHigh severity issuesHigh severity issuesarea:ai-serviceAI service (FastAPI) areaAI service (FastAPI) area
on Aug 19, 2026 - addedGrantFox OSSIssue tracked in GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardIssue may be eligible for a GrantFox rewardThird CampaignCampaign: Third CampaignCampaign: Third Campaign
on Aug 19, 2026 Devadakene commented
on Aug 19, 2026 ContributorMore actionsI am experienced enough to implement this issue having worked on similar issues in the past. Please assign
Hi! Nice to meet you — I’m @Flames4fun, a software engineer working mainly around AI infrastructure, security boundaries, and regression testing in open source.
I’d be very interested in taking this issue if it’s still available. I’ve worked on a closely related class of problem in
OWASP/Agent-Security-Regression-Harness#107, where I hardened the boundary between externally supplied execution data and host-owned evidence, added regression coverage for forged evidence shapes, and followed the issue through maintainer security review and merge. I’ve also contributed deterministic policy work around sensitive data and PII handling in CSL Core.For this issue, I’d treat the scrubber as an enforced preprocessing invariant rather than an optional helper: raw evidence should never reach the provider path, scrubber failure should remain fail-closed, and the tests should assert against the actual mocked provider payload so the guarantee cannot regress later. I’d also keep the persistence/audit behavior and the raw-vs-scrubbed boundary aligned with the scope described here rather than broadening the PII detector itself.
Given the security and verification semantics involved, I’d estimate about 6–8 focused hours for a PR I’m comfortable submitting, including regression tests and a full pass over the affected persistence/provider paths.
If you’re happy with that approach, I’d appreciate being assigned to the issue. Thanks, and nice to meet you!
Degentle12 commented
on Aug 20, 2026 ContributorMore actionsHi Maintainer
May I fix this issue pleasegrantfox-oss commented
on Aug 20, 2026 grantfox-ossboton Aug 20, 2026 – with GrantFox OSSMore actions🦊 GrantFox — @Degentle12 has been assigned to this issue as part of the Third Campaign campaign!
Next steps:
- Open a Pull Request referencing this issue (e.g.,
Closes #430) - Your PR will be reviewed by the ChainForgee maintainers
Good luck! Track your progress on GrantFox.
- Open a Pull Request referencing this issue (e.g.,
grantfox-oss commented
on Aug 22, 2026 grantfox-ossboton Aug 22, 2026 – with GrantFox OSSMore actions🎉 This issue has been marked as completed on GrantFox as part of the Third Campaign campaign!
@Degentle12's PR #452 was approved and merged by @kilodesodiq-arch.
🏆 @Degentle12: You earned 35 FoxPoints for this contribution! Your current tier: Explorer (376 total points). Track your full progress on GrantFox.
👏 Great work, @Degentle12! Keep contributing to ChainForgee.
Problem
The PII scrubber is only reachable as an explicit
/anonymize(and/v1/ai/anonymize) endpoint; the LLM verification path that sends free-text evidence to an external provider never calls it.HumanitarianVerificationService.verify_claimbuilds prompts from raw inputs and posts them straight to OpenAI or Groq:PIIScrubberService(app/ai-service/services/pii_scrubber.py) exists and is instantiated inmain.py, but a search for its usage inapp/ai-service/services/finds it only in its own file. Nothing inhumanitarian_verification.py,ocr.py, orfraud_detection.pyscrubs before the provider call.Consequence: the README's claim that the platform performs "PII anonymization before external LLM processing" holds only if a caller separately remembers to invoke
/anonymizefirst. On/v1/ai/humanitarian/verify,supporting_evidence— which the schema accepts as free text and which is described as recipient-provided evidence — is transmitted unredacted to a third-party LLM. Recipient names, locations, dates, ID numbers, and contact details can leave the trust boundary with no enforcement. The backend-side issue that scrubbedmetadata: Jsonfields (#213) does not cover this AI-service path, because the evidence reaches the provider from inside the AI service itself.Root cause
Anonymization is modelled as a separate, opt-in endpoint rather than as a mandatory preprocessing stage of the verification pipeline, so the pipeline and the scrubber are decoupled and the decoupling is invisible in the response.
Why this is architecturally hard
pii_scrubber.anonymizeinverify_claimis the easy part; the hard part is making it impossible to skip — e.g. a pipeline stage that runs before any provider call, with a fail-closed policy when scrubbing itself fails.pii_scrubber.pyrelies on a small regex set plus a spaCy blankenentity ruler; itsNAME_REGEXESincludes\b[A-Z][a-z]+\s+[A-Z][a-z]+\b, which matches generic capitalized phrases. Relying on it as a hard gate requires a measurable detection bar and a documented residual-risk posture.persistence/pii_decisions.pyrecords aggregate scrub metadata (never text); wiring the scrubber into the hot path must feed that store without accidentally persisting raw evidence.Proposed design
Introduce a single preprocessing step in the verification service that scrubs
aid_claim/supporting_evidence/context_factorsbefore prompt construction, with a config flag that fails closed (returns an error) when scrubbing is unavailable rather than silently sending raw text. Emit the scrub summary intopii_decisionsand expose the scrubbed/raw distinction in the response envelope so the backend can keep the raw text on the human-review side only.Acceptance criteria
Service
/v1/ai/humanitarian/verifyrequest whose evidence contains a name/phone/ID transmits only masked tokens to the provider.Tests
Documentation
Out of scope
Improving the scrubber's regex/spaCy precision and the backend metadata scrubbing (#213) are separate concerns.
Getting started
Files:
app/ai-service/services/humanitarian_verification.py,app/ai-service/services/pii_scrubber.py,app/ai-service/services/humanitarian_prompt.py,app/ai-service/persistence/pii_decisions.py.cd app/ai-service pytestGood first files to read:
services/humanitarian_verification.py(the raw-to-provider flow) andservices/pii_scrubber.py(theanonymizecontract to call).