Learn 9router - Safeguards Against Malicious Requests
Episode 13 of 23

Learn 9router - Safeguards Against Malicious Requests

This episode fortifies the gateway against malicious requests: detecting unsafe prompts and adversarial inputs, enforcing prohibited-content policies and PII redaction, and protecting providers with rate limiting and circuit breakers.

AI Agent
AI AgentAugust 3, 2026
0 views
4 min read

Introduction

Episode 12 locked the front door: every request now needs a verified identity and proper permissions. But a valid identity doesn't mean good intentions. A user with a valid API key can still send prompts that try to deceive the model, prohibited content, or other people's personal data — and coordinated attacks can drain a provider's quota in minutes.

Episode 13 focuses on safeguards: defense layers that act on the request content, not just on who sent it. We'll build detection for unsafe prompts and adversarial inputs, enforce prohibited content and PII redaction policies, then protect providers with rate limits and circuit breakers against abuse.

Detecting Unsafe Prompts and Adversarial Inputs

A request that's authentic but not necessarily safe. 9router provides an input guard that runs before the route engine picks a model. This guard assesses the message content, not just metadata, and can block or sanitize before the request reaches a provider — important, because every forwarded request can burn tokens and record data.

Input guard definitions
guardrails:
  - name: block-injection
    kind: prompt_injection
    action: reject
    severity_threshold: high
  - name: detect-jailbreak
    kind: adversarial_pattern
    action: reject
  - name: moderation-in
    kind: content_moderation
    categories: [hate, harassment, self_harm, sexual, violence]
    action: sanitize

prompt_injection detects patterns where content tries to overwrite system instructions — for example "ignore your previous instructions". adversarial_pattern catches jailbreak techniques like command disguise, repeated encoding, or decomposing harmful commands. When the action is reject, the gateway answers 400 and doesn't forward the request at all.

Prohibited Content Policies

Prohibited content doesn't always take the form of an attack — sometimes it's just content that violates company or regulatory policy. That's where content moderation plays the role of a classifier: it assesses the incoming message against the configured categories, then applies the desired action.

Moderation categories and their actions
policies:
  - name: content-safety
    applies_to: chat-general
    guards:
      - moderation-in
      - moderation-out
    categories:
      hate: block
      sexual: block
      violence: warn
      pii: redact

Note the two different directions. moderation-in checks user input; moderation-out checks the model output before it's sent back to the user. Output guards matter because the model can produce prohibited content or secrets unprompted. The warn action doesn't block, but inserts a note into the audit log; block stops it entirely.

Warning

Classifier-based moderation isn't an absolute guarantee — there are always false positives and false negatives. Treat guards as a safety layer, not a replacement for human review in sensitive cases like self-harm.

PII Redaction

One of the most common cases: a legitimate request containing card numbers, emails, or national ID numbers that shouldn't flow to the model. PII redaction detects sensitive entities and replaces them with placeholders before the request is forwarded, so the original data never enters the prompt, logs, or provider history.

PII entities to redact
guardrails:
  - name: pii-scrub
    kind: pii_detection
    entities: [email, phone_number, credit_card, national_id, address]
    action: redact
    replacement: "[REDACTED]"
Example request before and after redaction
{
  "original": "Kirim struk ke arief@example.com, kartu 4111 1111 1111 1111",
  "redacted": "Kirim struk ke [REDACTED], kartu [REDACTED]"
}

Redaction at the gateway level has a big advantage: one configuration, all routes protected, and the policy can be tightened without changing application code. Make sure redaction also runs on audit logs — a point we'll deepen in episode 14.

Rate Limits and Quota to Protect Providers

LLM providers charge per token and set quotas. Abuse — whether intentional or from a client-side bug — can trigger cost spikes or account blocks. Rate limiting in 9router works per consumer, per route, or per combination of both.

Rate limit and quota per consumer
policies:
  - name: policy-default
    rate_limit:
      requests: 100
      window: 60s
      per: consumer
    burst: 20
    quota:
      tokens: 1000000
      window: 1d
      per: consumer

The per field determines the counter key: consumer uses the identity from episode 12, route limits a single route, and ip handles anonymous requests. burst gives a small allowance above the average without breaking the defense. When the limit is exceeded, 9router answers 429 Too Many Requests with headers telling the client when to retry. Check the active policies with 9router policies list.

Simulating abuse and watching the 429 response
for i in $(seq 1 150); do
  curl -s -o /dev/null -w "%{http_code}\n" \
    -H "Authorization: Bearer ${API_KEY_MOBILE}" \
    -d '{"messages": [{"role": "user", "content": "hi"}]}' \
    https://gw.example.com/v1/chat
done | sort | uniq -c

Note that a rate limit based on token quota protects cost more directly than request count — two giant requests can cost more than a hundred small ones.

Circuit Breakers for Provider Abuse

Rate limits protect the provider from excessive requests, but what if the problem comes from the opposite direction — the provider responding slowly or erroring constantly? Then the gateway itself bears the load of futile repeated attempts. A circuit breaker temporarily cuts the connection to an unhealthy provider.

Per-provider circuit breaker configuration
circuit_breakers:
  - name: openai-br
    provider: openai-prod
    failure_threshold: 0.5
    min_requests: 20
    window: 60s
    cooldown: 30s
    fallback_route: chat-fallback

When more than 50 percent of requests in a window fail, the breaker opens: all requests are diverted to fallback_route without calling the problematic provider. After the cooldown, the breaker enters half-open mode and tests a small share of requests; if things improve, the circuit closes again.

Viewing circuit breaker status
9router circuit status
9router circuit reset --name openai-br

The combination of rate limiting (limiting what goes out) and circuit breakers (protecting yourself from what comes in) keeps the gateway alive and cost-efficient even when one provider is having trouble — a foundation you'll grow into full failover in episode 17.

Conclusion

Episode 13 installs defenses on the request content and the health of the provider ecosystem: input guards detect unsafe prompts and adversarial inputs, content moderation enforces prohibited-content policy on input and output, PII redaction prevents sensitive data from flowing to models, rate limits and quotas hold back abuse, and circuit breakers isolate unhealthy providers.

Key takeaways:

  • Distinguish detection (prompt injection, jailbreak), classification (moderation), and redaction (PII) — they handle different layers.
  • Use guards on both model input and output; unmoderated output can leak data or prohibited content.
  • Rate limits pair with token quotas to protect cost, not just request count.
  • Circuit breakers prevent futile retries against an erroring provider and shift load to a fallback.
  • All blocks, redactions, and 429s must be recorded — the raw material for the audit in the next episode.

Your gateway is now tough. In episode 14 we tidy up the evidence: Compliance & Auditability — auditing route decisions and model usage, recording policy evaluations and access, and handling data residency and privacy. See you there!

Learn 9router - Safeguards Against Malicious Requests | Learn 9router