Skip to content

feat: add opt-in sensitive-data Guardrails - #4022

Draft
rmsff wants to merge 24 commits into
lidge-jun:devfrom
rmsff:feat/guardrails-refresh-248
Draft

feat: add opt-in sensitive-data Guardrails#4022
rmsff wants to merge 24 commits into
lidge-jun:devfrom
rmsff:feat/guardrails-refresh-248

Conversation

@rmsff

@rmsff rmsff commented Sep 8, 2026

Copy link
Copy Markdown

Summary

Adds opt-in sensitive-data Guardrails to the existing proxy and dashboard. Supported secrets and personal data become placeholders before provider I/O; only allowlisted successful assistant prose can restore the original values.

Relates to #3705. This is the full implementation as a reference draft, not the proposed first landing. The smaller inert core review branch has no server hooks or dashboard changes and makes no network protection claim. Its separate PR is prepared but will wait for maintainer agreement on the design. The proposed integration contract records the protocol/failure matrix, operator behavior, review split and sponsorship boundaries. Maintainer agreement on that contract and merge sponsorship is still pending. The full branch stays on its pinned base while direction is discussed.

  • Off by default, with all-provider or selected-provider protection. Excluded providers bypass the Guardrails runtime.
  • Covers the supported request fields in Responses, Chat Completions and Anthropic Messages, including JSON, SSE, WebSocket, continuation, compact, combo/fallback and sidecar paths.
  • One immutable policy per request, bounded process-local mappings, and restoration gated on successful protocol completion. Tool arguments and failed/incomplete response envelopes remain masked.
  • Settings, rules, a synthetic-value Tester, Replace import security preview and metadata-only Activity use the existing dashboard components and Management API. No separate server, database or donor UI.
  • Includes public English documentation, API/configuration references, agent guidance and license/provenance checks.

Security and coverage limits

This detects supported patterns; it is not a guarantee that arbitrary sensitive text will be found. Tool/schema definitions and binary/image content are outside the text-scanning contract. Restored streaming output can be delayed until the success terminal. If continuation mappings expire or the process restarts, unresolved placeholders stay masked. Executable tool arguments are deliberately not restored.

The registry has 266 rules from cloud-ru-tech/guardrails-llm-filter@bbd6f27467a53ff3869b59449edf4209f85ae675 (v0.1.2.1) and six OpenCodex-owned supplemental rules. Donor main is unchanged as of September 8; its open tool-definition proposal is not imported.

Direct dependencies are pinned to re2-wasm@1.0.2 and yaml@2.8.3. The latter replaces the RFC's 2.8.1 pin with the published fix for GHSA-48c2-rrv3-qjmp. YAML reads fixed package-owned rule assets; Management API imports use JSON. Package checks validate source, npm integrity, WASM hashes and shipped licenses/notices. Attribution is recorded in src/guardrails/rules/provenance.json and THIRD_PARTY_NOTICES.md.

This touches credential handling, CI wiring and dependency installation, so explicit maintainer security review and maintainer-sponsored are needed before merge. Local independent reviews do not replace that review.

GitHub Push Protection flagged 33 pattern matches in synthetic test fixtures, including duplicate detections of the same values. Each displayed match was checked against its historical test source and allowed as test data in the fork. No repository-wide scanning setting was disabled, and no commits were rewritten to evade detection.

Verification

Published head: e54048a11ef3cf97e37a4138ddb05d1ed3dfd73e, including pinned dev@29bb221c3 (development version 2.49.0). Stable at the September 8 publication check: 2.48.0.

The full suite ran on 5b624f5b52bde9feb68b78e3de1deab9af72df21. The upstream merge at 273d0fe4e changed only package.json's version and six upstream release archive documents; it was independently reviewed. The current e54048a11 adds only four documentation files/edits: the integration contract, its structure link, masked-value operator instructions and the synthetic-fixture contribution record. Runtime source, tests, dashboard source, scripts, lockfile and workflows remain byte-identical to the full-suite candidate. The new docs passed independent review, privacy scanning, 19 local-link checks and a fresh 433-page docs build.

Check Result
bun run test --parallel=2 22,085 passed, 40 existing platform/runtime skips, 0 failed; 1,165 files, all 36 official lanes
Guardrails subset within that run 245 passed, 0 skipped, 0 failed; 20 files
GUI bun test tests 1,994 passed, 0 failed; unchanged GUI tree 4e71450701e055fc14d4f1a9a7c2360ce59fbc1f
bun run typecheck, lint:gui:if-changed, privacy:scan, doctor:gui:if-changed Passed separately as the remaining prepush stages
Root and GUI bun audit, no severity filter No reported vulnerabilities; 145 and 81 packages
bun run prepublishOnly, bun run verify:guardrails-package Passed
Docs bun install --frozen-lockfile, bun run build Passed; 433 pages
273d0fe4e checkpoint: four version/release test files 39 passed, 0 failed
273d0fe4e checkpoint: bun run privacy:scan, bun run prepublishOnly Passed, including audit:high, typecheck, GUI build and package/provenance verification

These runs used Bun 1.4.0 on macOS arm64. The final version checks were bun test tests/ci-workflows/version-line.test.ts tests/ci-workflows/bump-dev-version.test.ts tests/ci-workflows/release-version-line.test.ts tests/ci-workflows/compatibility-version.test.ts.

The earlier literal bun run prepush hit an unchanged Desktop lifecycle child-process timeout under host contention. That file passed 46 tests in isolation and then passed in the complete two-worker run above. No test filters, added skips or timeout overrides were used. This is a staged prepush-equivalent pass, not a claim that the earlier command succeeded. The existing GUI bundle-size warning remains. Native Linux/Windows and GitHub PR CI results are separate and are not claimed here.

Manual dashboard checks used isolated proxies, temporary homes, synthetic local providers and separate ports. They covered default-off, selected-provider persistence, Tester draft simulation, Activity, Replace preview and desktop/mobile navigation. Protected-provider wire data contained placeholders; excluded-provider wire data was unchanged, and eligible successful client prose was restored. Test proxies were stopped afterward; the primary proxy was untouched.

Screenshots

Captured on the same GUI source tree before the version-only 2.49.0 bump; the visible badge therefore says 2.48.0. All values are synthetic.

Desktop settings and inline save feedback:

Guardrails desktop settings

Mobile layout, Replace security preview and draft Tester

Guardrails mobile feedback

Replace import security preview

Synthetic draft Tester

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.
  • All CI tests are green on my local testing.

  • I pushed my PR to the latest dev commit.

  • I resolved all correct Codex and CodeRabbit findings.

  • My PR is ready for review.

Kept as a reference draft pending repository checks, agreement on the split and maintainer security sponsorship. Prepared with OpenAI Codex assistance.

rmsff added 23 commits September 5, 2026 21:00
@coderabbitai

coderabbitai Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the intake: hygiene-blocked Deterministic PR hygiene checks failed label Sep 8, 2026
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

⚠️ Deterministic hygiene checks failed.

  • unsponsored_surface — This changes an authentication, workflow, release-automation, or dependency surface. MAINTAINERS.md requires security review for these; ask a maintainer to apply maintainer-sponsored once they have reviewed it. Paths: .github/workflows/ci.yml, bun.lock, package.json, src/server/management-api.ts.

@github-actions github-actions Bot added the enhancement New feature or request label Sep 8, 2026
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

⏳ DRAFT

  • hygiene: unsponsored_surface.

What to do

  • Fix unsponsored_surface — This changes an authentication, workflow, release-automation, or dependency surface. MAINTAINERS.md requires security review for these; ask a maintainer to apply maintainer-sponsored once they have reviewed it. Paths: .github/workflows/ci.yml, bun.lock, package.json, src/server/management-api.ts.
  • Tick all four boxes in the PR description once you're done (currently 0/4).

Review readiness checklist

  • ⬜ All CI tests are green on my local testing.
  • ⬜ I pushed my PR to the latest dev commit.
  • ⬜ I resolved all correct Codex and CodeRabbit findings.
  • ⬜ My PR is ready for review.

0/4 boxes ticked.

This pull request was already a draft. Its draft status will be preserved after every issue above is resolved.
@rmsff Tick the boxes once your local CI is green, your branch is on the latest dev commit, and every correct Codex and CodeRabbit finding is resolved.

@lidge-jun

Copy link
Copy Markdown
Owner

리뷰 · 우선순위 33 / 80

이 PR은 이슈 #3705의 “민감 데이터를 프로바이더로 보내기 전에 placeholder로 바꾸고, 성공한 어시스턴트 문장에서만 되돌린다”는 Guardrails를 풀 구현 draft로 올린 것이다. 기본값은 꺼짐이고, 전 프로바이더 또는 선택한 프로바이더만 보호한다. Responses / Chat Completions / Anthropic Messages의 JSON·SSE·WebSocket·continuation·compact·combo/fallback·sidecar 경로를 한 번에 덮고, 대시보드 Settings·Rules·Tester·Replace 미리보기·Activity와 Management API까지 기존 GUI 위에 얹는다. 규칙 266개는 cloud-ru-tech/guardrails-llm-filter v0.1.2.1에서 가져오고 OpenCodex 소유 보충 규칙 6개가 붙는다. 직접 의존성은 re2-wasm@1.0.2, yaml@2.8.3(GHSA-48c2-rrv3-qjmp 수정본)이다.

지금 dev HEAD는 29bb221c3(패키지 2.49.0, tip 문서 머지 #4021)이다. 제품 tip은 여전히 #4002 계열 auth/routing이고, 출하 축은 2.48.0 기록 마감 뒤 열린 2.49 개발선이다. 이 PR은 그 tip 위의 보안·프록시 핵심 경로를 크게 늘리는 별도 열차다. 파일 약 173개, 추가가 수만 줄이고 draft이며 라벨 intake: hygiene-blocked(unsponsored_surface — 인증/워크플로/의존성 표면)와 enforce-target 실패가 있다. 작성자 본문도 “메인테이너 합의·보안 리뷰·maintainer-sponsored 전에는 merge 아님, 필요하면 쪼개겠다”고 이미 적었다. 예전에 #3705 리뷰에서 말한 “설계 합의 → spike 한 경로”보다 앞질러 전체 착륙 draft가 온 상태라, 가치는 크지만 지금 merge 점수로는 낮다.

코드가 끼는 자리는 checkout 기준으로 분명하다. 새 트리 src/guardrails/(activation, turn, scanner, sse-demask, continuations, registry, re2-runtime 등)와 src/server/management/guardrails-*.ts, GUI gui/src/pages/Guardrails.tsx + gui/src/pages/guardrails/가 본체다. 기존 서버 훅은 src/server/responses/core.ts, sse-payload-rewrite.ts, chat-completions.ts, claude-messages.ts, responses/compact.ts, ws-bridge.ts, src/images/loop.ts 쪽에 가드 호출이 붙는다. 설정은 src/config.tssrc/types/config.ts에 스키마/필드가 추가된다. 작성자가 밝힌 계약도 중요하다: 도구 인자·실패/미완료 응답은 복원하지 않고, 스트림 복원은 성공 터미널까지 늦출 수 있으며, 프로세스 재시작·continuation 맵 만료 시 placeholder가 남을 수 있다. 즉 “모든 민감 텍스트 보장”이 아니라 지원 패턴 + 성공 prose 한정 복원이다.

왜 지금 바로 안 태우나. (1) #3705에서 아직 메인테이너가 훅 지점·실패 불변식·번들/보안 영향을 공식으로 잠그지 않았다. (2) hygiene가 MAINTAINERS.md의 sponsored 표면으로 막혀 있어 CI가 초록이 될 수 없다. (3) config.ts/types/config.ts와 프록시 hot path를 한꺼번에 만져서, 지금 tip(#4002 주변)과 리베이스 충돌·리뷰 부담이 크다. (4) Push Protection이 픽스처의 합성 시크릿 33건을 잡았고, 작성자는 테스트 데이터로 allow했다고 했지만 저장소 정책·유지 비용은 메인테이너가 한 번 더 봐야 한다. 로컬 검증 영수증(2만+ 테스트, Guardrails 245 통과 등)은 성실해 보이지만, 그건 “방향 합의 후 착륙 품질” 증거이지 “지금 머지” 증거가 아니다.

라인 / 경로로 보면 이런 점이 걸린다.

src/server/responses/core.ts / sse-payload-rewrite.ts / ws-bridge.ts - 프록시 성공·실패·폴백·스트림 경계마다 마스크 유지 계약이 한 줄이라도 어긋나면 시크릿이 프로바이더로 새거나, 반대로 사용자 prose가 영구 마스크로 남는다. 경로별 불변식 표를 PR에 고정해야 한다
src/guardrails/continuations.ts / compact-continuations.ts - 프로세스 로컬 맵이 재시작·용량 한계에서 만료되면 placeholder가 클라이언트에 그대로 보인다. UX/문서에 “복원 실패 시 동작”이 운영자 언어로 있어야 한다
package.json + re2-wasm - 새 네이티브/WASM 런타임과 CI 설치 경로가 생긴다. hygiene unsponsored_surface와 맞물려 maintainer-sponsored 없이 통과 불가
src/config.ts / src/types/config.ts - 거대 config 표면에 필드가 추가된다. types/config 분할 열차와 겹치면 리베이스 대신 닫고 다시 자르는 편이 맞을 수 있다
gui/src/pages/guardrails/ - 새 워크스페이스 전체다. tip GUI 변경과 동시에 들어가면 리뷰·충돌 비용이 한 번 더 뛴다
라벨 intake: hygiene-blocked - 로컬 독립 리뷰로는 sponsored 요구를 대체할 수 없다(작성자 본문과 동일)

메인테이너의 판단이 필요한 지점

너의 추천
draft·hygiene-blocked 상태를 유지하고 지금 merge하지 마세요. 라벨은 그대로 두세요. 먼저 #3705에 짧은 설계 동결(훅 표·실패 시 마스크 유지·복원 실패 UX·sponsored 조건)을 메인테이너가 댓글로 잠근 뒤, 가능하면 runtime 코어(+테스트)만의 작은 PR로 다시 자르라고 하세요. 합의·sponsor 전에는 이 PR을 리베이스 기차에 올리지 않는 편이 dev tip을 덜 흔듭니다. 합성 시크릿 픽스처 allow 기록은 SECURITY/기여 문서에 한 줄로 남기게 하세요.

이 댓글은 grok-bot이 작성했습니다

@rmsff

rmsff commented Sep 8, 2026

Copy link
Copy Markdown
Author

I've made the author-side changes requested here:

On core head b7485442, a fresh full run passed: 21,875 passed, 40 existing skips, 0 failed, across 1,152 files and all 14 lanes. That includes 67 core tests with no skips or failures. The remaining prepush stages and package/provenance checks passed; independent review found a gap in the inert-boundary regression, which was fixed and rechecked. These are macOS arm64 / Bun 1.4.0 results, not a claim about upstream CI or Linux/Windows.

This PR's new commit changes documentation only; its runtime code is unchanged. Privacy checks and the 433-page docs build passed. This remains a draft, the labels are untouched, and I haven't rebased the full branch again. Maintainer agreement on the split and explicit security sponsorship are still needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request intake: hygiene-blocked Deterministic PR hygiene checks failed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants