Skip to content

feat(tools): add Deaf Guard pre-execution command classification - #394

Closed
loog4j wants to merge 1 commit into
vxcontrol:mainfrom
loog4j:feat/deaf-guard
Closed

loog4j wants to merge 1 commit into
vxcontrol:mainfrom
loog4j:feat/deaf-guard

Conversation

@loog4j

@loog4j loog4j commented Aug 20, 2026 •

Copy link
Copy Markdown

Summary

  • Adds Deaf Guard, an optional pre-execution classifier on terminal tool calls. Commands are matched against a 9-tier regex table (log / warn / block) before they run in the sandbox.
  • Operators can set DEAF_GUARD_ENABLED / DEAF_GUARD_MODE in env, toggle them at runtime in Settings → Security, and watch live classifications on a Deaf Guard tab in the flow view.
  • Default posture is log (classify and record only). warn blocks BLOCK-tier commands; enforce blocks BLOCK and WARN. Runtime UI/API changes apply to the next flow, not already-running ones.

This is offered as an opt-in safety layer for autonomous pentest runs. Config defaults stay on observation (enabled=true, mode=log) so existing workflows are not blocked unless an operator tightens the mode.

Test plan

  • cd backend && go test ./pkg/tools/deafguard/ ./pkg/config/
  • cd frontend && pnpm exec tsc -b and pnpm exec vitest run src/features/flows/deaf-guard/lib.test.ts src/lib/routes.test.ts src/components/layouts/settings/settings-sidebar.test.tsx
  • Confirm Settings sidebar shows Security, and a running flow shows the Deaf Guard tab between Agents and Searches
  • GET/PUT /api/v1/deafguard/config updates {enabled, mode}; a new flow picks up the change, an already-running flow does not
  • In log mode a BLOCK-tier command still executes and appears in the tab; in warn/enforce it returns BLOCKED by Deaf Guard ... without running

Intercept terminal tool calls with a 9-tier classifier, Settings → Security controls, and a live flow tab so operators can log, warn, or block risky sandbox commands before they run.
@khunwav

khunwav commented Sep 12, 2026

Copy link
Copy Markdown

Summary

  • Adds Deaf Guard, an optional pre-execution classifier on terminal tool calls. Commands are matched against a 9-tier regex table (log / warn / block) before they run in the sandbox.
  • Operators can set DEAF_GUARD_ENABLED / DEAF_GUARD_MODE in env, toggle them at runtime in Settings → Security, and watch live classifications on a Deaf Guard tab in the flow view.
  • Default posture is log (classify and record only). warn blocks BLOCK-tier commands; enforce blocks BLOCK and WARN. Runtime UI/API changes apply to the next flow, not already-running ones.

This is offered as an opt-in safety layer for autonomous pentest runs. Config defaults stay on observation (enabled=true, mode=log) so existing workflows are not blocked unless an operator tightens the mode.

Test plan

  • cd backend && go test ./pkg/tools/deafguard/ ./pkg/config/
  • cd frontend && pnpm exec tsc -b and pnpm exec vitest run src/features/flows/deaf-guard/lib.test.ts src/lib/routes.test.ts src/components/layouts/settings/settings-sidebar.test.tsx
  • Confirm Settings sidebar shows Security, and a running flow shows the Deaf Guard tab between Agents and Searches
  • GET/PUT /api/v1/deafguard/config updates {enabled, mode}; a new flow picks up the change, an already-running flow does not
  • In log mode a BLOCK-tier command still executes and appears in the tab; in warn/enforce it returns BLOCKED by Deaf Guard ... without running

This was referenced Sep 12, 2026
@khunwav

khunwav commented Sep 12, 2026

Copy link
Copy Markdown

Summary

  • Adds Deaf Guard, an optional pre-execution classifier on terminal tool calls. Commands are matched against a 9-tier regex table (log / warn / block) before they run in the sandbox.
  • Operators can set DEAF_GUARD_ENABLED / DEAF_GUARD_MODE in env, toggle them at runtime in Settings → Security, and watch live classifications on a Deaf Guard tab in the flow view.
  • Default posture is log (classify and record only). warn blocks BLOCK-tier commands; enforce blocks BLOCK and WARN. Runtime UI/API changes apply to the next flow, not already-running ones.

This is offered as an opt-in safety layer for autonomous pentest runs. Config defaults stay on observation (enabled=true, mode=log) so existing workflows are not blocked unless an operator tightens the mode.

Test plan

  • cd backend && go test ./pkg/tools/deafguard/ ./pkg/config/
  • cd frontend && pnpm exec tsc -b and pnpm exec vitest run src/features/flows/deaf-guard/lib.test.ts src/lib/routes.test.ts src/components/layouts/settings/settings-sidebar.test.tsx
  • Confirm Settings sidebar shows Security, and a running flow shows the Deaf Guard tab between Agents and Searches
  • GET/PUT /api/v1/deafguard/config updates {enabled, mode}; a new flow picks up the change, an already-running flow does not
  • In log mode a BLOCK-tier command still executes and appears in the tab; in warn/enforce it returns BLOCKED by Deaf Guard ... without running

@khunwav khunwav left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bed2891b02f89d4471e42e74bd9ded7e29189041

@codeCraft-Ritik codeCraft-Ritik left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When a tool execution passes a compound command line (e.g. ls -la && dangerous_cmd || echo done), does the classifier tokenize individual pipeline segments, or does it evaluate the regex across the entire command string?

If a command contains multiple sub-commands evaluated across different tiers (e.g., one LOG, one WARN, one BLOCK), what is the tier resolution logic? Confirm that it resolves to the most restrictive tier encountered (e.g., max(tier)) across all compound expressions.

@loog4j

loog4j commented Sep 16, 2026

Copy link
Copy Markdown
Author

When a tool execution passes a compound command line (e.g. ls -la && dangerous_cmd || echo done), does the classifier tokenize individual pipeline segments, or does it evaluate the regex across the entire command string?

If a command contains multiple sub-commands evaluated across different tiers (e.g., one LOG, one WARN, one BLOCK), what is the tier resolution logic? Confirm that it resolves to the most restrictive tier encountered (e.g., max(tier)) across all compound expressions.

Yes. Compound lines are split, then the worst action wins.

classifyCommand (backend/pkg/tools/deafguard/deafguard.go:137-154) classifies the raw string and each splitCommand segment (;, &&, ||, | outside quotes). So ls -la && dangerous_cmd || echo done is the full line plus ls -la, dangerous_cmd, and echo done.

Mixed LOG / WARN / BLOCK → BLOCK. That is max(actionSeverity) (BLOCK=3, WARN=2, LOG=1) at deafguard.go:151-153 and deafguard.go:283-294, not max(tier). Tiers run the other way (1 most severe, 9 least).

@sirozha

sirozha commented Sep 23, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the patch. We are not taking this: the regex filter is bypassable by encoding or substitution, and the runtime setting can be turned off by any user with settings access. Closing this PR.

@sirozha sirozha closed this Sep 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants