Skip to content

feat(gateway): enforce abuse rule actions#3504

Open
jrf0110 wants to merge 8 commits into
mainfrom
abuse-rules-action
Open

feat(gateway): enforce abuse rule actions#3504
jrf0110 wants to merge 8 commits into
mainfrom
abuse-rules-action

Conversation

@jrf0110
Copy link
Copy Markdown
Contributor

@jrf0110 jrf0110 commented May 26, 2026

Summary

Makes our gateway enforce abuse rules-engine actions. We keep the normal request path fast by using Redis as a lightweight action cache (only identities with a cached blocking/quarantine action wait on a fresh abuse check).

  • nothing: no gateway enforcement; cached as none.
  • log: no gateway enforcement, but the action is cached so future requests stay on the nonblocking path.
  • rate-limit: return a request-local 429 rate_limit_exceeded before upstream.
  • block: return a request-local 403 abuse_blocked before upstream.
  • quarantine-1: add 2s of artificial latency, then continue normally.
  • quarantine-2: add 6s of artificial latency, then continue normally.
  • quarantine-3: add 6s of artificial latency and, for non-BYOK requests, rewrite to an auto-free model when one is available; BYOK and no-candidate cases are latency-only.

Verification

  • Ran the local abuse worker at http://localhost:5173 and the cloud web server at http://localhost:3000 with ABUSE_SERVICE_URL=http://localhost:5173, backed by local Postgres and Redis.
  • Created temporary active abuse rules through /trpc/rules.create for block, rate-limit, quarantine-1, quarantine-2, quarantine-3, and log, each matching a unique request.user_agent marker.
  • Sent direct /api/classify requests to confirm each temporary rule resolved to the expected rules_engine.resolved_action and matched the expected rule ID.
  • Sent gateway requests to /api/openrouter/v1/chat/completions and confirmed the Redis-gated behavior: the first request classified/cached, and the second request enforced cached blocking actions.
  • Confirmed block returned 403 abuse_blocked, rate-limit returned 429 rate_limit_exceeded, quarantine-1 added about 2s latency, quarantine-2 added about 6s latency, quarantine-3 added about 6s latency, and log continued without enforcement.
  • Seeded local OpenRouter model metadata, restarted the web server, and confirmed non-BYOK quarantine-3 rewrote to a free Nemotron model before proxying.
  • Deleted all temporary smoke-test abuse rules through /trpc/rules.delete, cleared Redis abuse classification cache keys, removed the seeded OpenRouter metadata cache, and restarted the web server to clear in-memory metadata.

Visual Changes

N/A

Reviewer Notes

  • block remains request-local and does not mutate kilocode_users.blocked_reason.
  • Quarantine latency is currently 2s for level 1 and 6s for levels 2/3.
  • Quarantine-3 degrades to latency-only if no auto-free candidate is available for the request API kind.
  • Redis stores only the last rules-engine action string (block, rate-limit, quarantine-*, log, or none) with no expiry, keyed by the abuse identity shape for users/fingerprints.

Comment thread apps/web/src/app/api/openrouter/[...path]/route.ts Outdated
Comment thread apps/web/src/app/api/openrouter/[...path]/route.ts Outdated
Comment thread apps/web/src/app/api/openrouter/[...path]/route.ts Outdated
Comment thread apps/web/src/app/api/openrouter/[...path]/route.test.ts Outdated
@kilo-code-bot
Copy link
Copy Markdown
Contributor

kilo-code-bot Bot commented May 26, 2026

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

Incremental review of one new commit (9ee9bf74a): pure rename/consolidation refactor — originalModelIdLowerCasedeffectiveModelIdLowerCased, and six scattered provider-context let variables (provider, userByok, bypassAccessCheck, skipProviderPin, skipKiloExclusiveModelSettings, experiment) are consolidated into a single effectiveProviderContext object. A structured console.warn('SECURITY: ...') log is added on the quarantine-3 model override path. No logic changes; all conditional paths, return points, and ordering are identical to the previous commit.

Resolved Issues (click to expand)

| File | Line | Issue | Status |
|---|---|---|
|---|
| apps/web/src/app/api/openrouter/[...path]/route.ts | 544 | Quarantine-3 model-override failure path (apiKindNotSupportedResponse) returned without applying delayMs, bypassing the quarantine penalty | ✅ Fixed |
| apps/web/src/app/api/openrouter/[...path]/route.ts | 524 | Quarantine-3 model-override failure paths (not-found, unavailable) returned without applying delayMs | ✅ Fixed |
| apps/web/src/app/api/openrouter/[...path]/route.test.ts | — | quarantine-1 and quarantine-2 actions had no test coverage | ✅ Fixed |
| apps/web/src/lib/ai-gateway/abuse-service.ts | 303 | Manual type-guard used instead of Zod for parsing cached rules-engine results | ✅ Fixed |
| apps/web/src/lib/ai-gateway/abuse-service.ts | 349 | isRulesEngineBlockingAction lacked a clarifying comment | ✅ Fixed |
| apps/web/src/app/api/openrouter/[...path]/route.ts | 400 | Abuse enforcement flow lacked explainer comments | ✅ Fixed |
| apps/web/src/lib/ai-gateway/abuse-service.ts | — | Cache stored full JSON blob instead of just the action string | ✅ Fixed |

Files Reviewed (3 files)
  • apps/web/src/app/api/openrouter/[...path]/route.ts — no issues
  • apps/web/src/app/api/openrouter/[...path]/route.test.ts — no issues
  • apps/web/src/lib/ai-gateway/abuse-service.ts — no issues

Reviewed by claude-sonnet-4.6 · 326,877 tokens

Review guidance: REVIEW.md from base branch main

jrf0110 and others added 3 commits May 28, 2026 10:27
…re paths

When quarantine-3 model-override provider lookup fails (not-found or
unavailable), the delay was silently bypassed. Now the delay is applied
before returning the error response, preserving the quarantine penalty.

Also adds test coverage for quarantine-1 and quarantine-2 (latency-only
actions that previously had no tests).
@jrf0110 jrf0110 force-pushed the abuse-rules-action branch from c46b25f to d97a3c8 Compare May 28, 2026 16:07
Comment thread apps/web/src/app/api/openrouter/[...path]/route.ts
Comment thread apps/web/src/lib/ai-gateway/abuse-service.ts Outdated
@jrf0110
Copy link
Copy Markdown
Contributor Author

jrf0110 commented May 28, 2026

Addressed the outstanding review summary items: the quarantine-3 unsupported-API-kind model override path now applies delay before returning, and cached rules-engine JSON now validates through Zod. Also replied to and resolved all review threads.

Comment thread apps/web/src/lib/ai-gateway/abuse-service.ts
Comment thread apps/web/src/app/api/openrouter/[...path]/route.ts Outdated
Comment thread apps/web/src/lib/ai-gateway/abuse-service.ts Outdated
Comment thread apps/web/src/lib/ai-gateway/abuse-service.ts Outdated
Comment thread apps/web/src/app/api/openrouter/[...path]/route.ts Outdated
Comment thread apps/web/src/app/api/openrouter/[...path]/route.ts Outdated
Comment thread apps/web/src/app/api/openrouter/[...path]/route.ts Outdated
Comment thread apps/web/src/app/api/openrouter/[...path]/route.ts
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.

2 participants