ADORSYS-GIS / ADORSYS-GIS/ai-helm
[Epic]: PII redaction on the AI data path — censgate/redact front proxy
- Vorherrschende Sprache
- Go Template
- Sterne
- 3
- Forks
- 1
- Ø Merge
- 19 Std. 24 Min.
- Gemergte PRs (30 T.)
- 80
Beschreibung
### Executive Summary
We want **PII redaction and blocking applied to AI traffic**, so that sensitive data does not leave our boundary in prompts and does not come back in completions.
This is the only project on the governance roadmap that **mutates the inference data path**. Every AI request would traverse it, with `failOpen: false`. It goes last, and it gets its own ADR.
### Strategic Intent
Stop sensitive data crossing the AI boundary — and do it with an off-the-shelf Rust proxy, without forking the AI Gateway, unless a measurement proves we must.
### Problem Statement
- **Users:** nothing today prevents a prompt containing credentials, customer data or personal information from reaching a third-party model provider.
- **Security / compliance:** no redaction, no blocking, and no metrics on how much sensitive data is being trimmed — which is itself a requirement, not a nice-to-have.
- **Operations:** the naive implementation is a new mandatory hop in front of every AI request. Done carelessly, it is a single point of failure for the whole platform.
### Desired Outcome
- Sensitive content is redacted or blocked before it reaches a provider.
- We can report **how much** was trimmed, per request — the metrics are part of the requirement.
- The mechanism fails **closed** in production, and there is a rehearsed rollback.
- Streaming traffic is handled correctly, because streaming is the normal case here.
### Scope (In / Out)
#### In Scope
- Deploying [`censgate/redact`](https://github.com/censgate/redact) — Rust, Apache-2.0 — specifically its **`redact-gateway`**, an OpenAI-compatible proxy that already exists.
- Redaction metrics (how much was trimmed, per request).
- A canary path on the internal gateway before any external traffic.
- Fail-closed behaviour and a rehearsed rollback drill.
- **The SSE/streaming decision, inside the MVP.**
#### Out of Scope
- **Writing our own redaction engine.** `redact-gateway` exists, in Rust, with OTel metrics. `redact-core` is the library seam if the ext_proc variant is ever wanted. (Rewriting it ourselves stays a *fallback*, consistent with staying Rust/Go-only — not the plan.)
- **Forking Envoy AI Gateway — unless measured.** See below.
- Per-tenant redaction policy. Wanted eventually; the infrastructure should allow it, but the MVP does not need it.
### Two findings that reorder the source spec
**Finding 1 — SSE is not a post-MVP item, it is the gate.**
Our traffic is overwhelmingly streaming: opencode and LibreChat both stream by default, and the whole of ai-helm **ADR-0034** exists because long streaming generations were being cut mid-stream. A redaction hop that only handles buffered responses cannot go to production here. **The SSE strategy — incremental vs. buffered-for-sensitive-profiles — must be settled during the MVP and proven on one real streaming client**, not deferred to "post-MVP item #1".
**Finding 2 — do not budget the fork before measuring the ordering.**
The spec hedges that a custom processor "*may* not" be positionable before AIEG's ext_proc on EG v1.8.2 / AIEG v1.0.0, and jumps to a pinned fork. That hedge is doing a lot of work. Four configurations should be tried and `/config_dump` read before anyone agrees to maintain a fork.
And the reason the hedge may never matter: **`redact-gateway` sidesteps the question entirely** —
```
client → redact-gateway (off the shelf) → core-gateway (authorino → AIEG → provider)
```
No ext_proc protocol, no filter ordering, no fork, no new code. **Deploy the front proxy first**; it delivers redaction, blocking and metrics while deferring the ordering/fork question indefinitely. Run the ordering spike later, only if a real requirement — a per-route policy the front proxy cannot express — actually appears.
> ⚠️ The original roadmap justified the ordering spike as shared between this project and the dynamic-budget work. **It is not**: the budget epic chose discrete tiers (option A) and needs no data-path component at all. The spike now serves exactly **one** feature, which makes a maintained fork substantially harder to justify.
### Source of truth (links)
- Roadmap: ADORSYS-GIS/ai-helm#872, §3 (this is the only 🔴 row) and §4 Wave 5
- Full plan: `plans/censgate-redact-extproc.md` in that PR — §0 findings, §1 (what forking AIEG actually costs)
- Upstream: https://github.com/censgate/redact
- Why streaming is the hard case here: ai-helm ADR-0034
- Upstream issue referenced by the ordering question: envoyproxy/envoy-gateway#8789
### Stakeholders
- Product Owner / Technical Lead / Security: @stephane-segning
### Key Assumptions
1. **`redact-gateway` is usable off the shelf** as an OpenAI-compatible front proxy. Validate early — the whole "no fork" argument rests on it.
2. **The 54 pattern-based recognisers cover the MVP.** Validate against real traffic samples.
3. **A front proxy is acceptable latency** inside a `failOpen: false` hop. Measure; do not assume.
4. **There is a non-streaming production client to canary with.** ⚠️ If there is not, SSE moves into the MVP as a hard requirement rather than a parallel workstream — this is a Wave 0 spike question.
### Constraints
- **`failOpen: false` in production** (decision 10). This is a deliberate availability trade: redaction unavailable means requests are refused, not passed through.
- Rust/Go only. No Python.
- Redaction metrics are a requirement, not optional.
- Goes **last** on the roadmap; nothing else waits on it, so it can be deferred or dropped on its own merits.
### Risks
| Risk | Probability | Impact | Mitigation |
|---|---|---|---|
| **New mandatory hop becomes a platform-wide SPOF** | Medium | 🔴 Critical | Front proxy first, canary on the internal gateway, rehearsed rollback before external traffic |
| **`failOpen: false` turns a redaction outage into a full AI outage** | Medium | 🔴 Critical | Accepted deliberately; needs alerting and a documented break-glass |
| Streaming handled incorrectly → generations cut mid-stream | **High** if deferred | High | Settle SSE inside the MVP; prove on a real streaming client |
| Maintaining an AIEG fork | Low (front proxy avoids it) | High | Do not fork before the spike; price it honestly if the spike says so |
| Redaction interacts with billing (redacted tokens still billed) | Certain | Low | Documented consequence; no change (decision 9) |
| Recogniser coverage insufficient | Medium | Medium | Validate against real samples before enforcing |
### Success metrics
| Metric | Current | Target | Source |
|---|---|---|---|
| Sensitive data reaching providers | unmeasured | measured, then reduced | redaction metrics |
| Redaction volume per request | not collected | collected | OTel metrics from redact-gateway |
| Added p99 latency on the AI path | 0 | measured and accepted before rollout | gateway metrics |
| Streaming requests broken by redaction | n/a | **0** | canary |
| AIEG forks maintained | 0 | **0** unless the spike proves otherwise | repo |
### Child User Stories
- Spike: filter ordering on EG v1.8.2 / AIEG v1.0.0 — four configurations, read `/config_dump`
- Spike: is there a non-streaming production client to canary with?
- Deploy `redact-gateway` as a front proxy, internal canary only
- SSE / streaming strategy — decided and proven in the MVP
- Redaction metrics → Mimir + a dashboard
- Fail-closed behaviour, alerting, and a rehearsed rollback drill
- ADR: redaction placement, fail-closed, and the billing interaction
### Human accountable owner
@stephane-segning
### AI Usage Declaration
Drafting, Research, Ticket decomposition, Technical proposal
### Human verification completed
- [x] Intent checked against source of truth
- [x] Risks reviewed
- [x] I am the accountable owner and accept responsibility for this epic.
Beitragsleitfaden
Bewertung
Dieses Issue wurde noch nicht bewertet.