IPAbuse Developers
Developer Guide12 minMay 2026

Building Abuse-Resistant AI Agents with IP Reputation Checks

An AI agent that can browse the web, call APIs, and execute code is only as secure as the inputs it accepts. When an agent receives requests from external sources — webhooks, user messages, tool callbacks — IP reputation verification adds a meaningful security boundary that pure prompt-level defences cannot provide.

The AI agent attack surface

Traditional APIs have a clear trust boundary: your server, your code. AI agents blur that boundary. An agent receives instructions in natural language, invokes tools based on those instructions, and may trust the output of external tools to form subsequent decisions. An attacker who can inject malicious content at any point in that chain — the initial message, a tool response, a scraped web page — may influence the agent's actions. Verifying the IP reputation of the original caller is the outermost and cheapest control.

Vercel AI SDK: adding IP checks to server actions

When using the Vercel AI SDK with Next.js Server Actions, the caller IP is available in the request headers. Check it before the action executes any tool.

app/actions/agent.ts
"use server";
import { generateText, tool } from "ai";
import { openai } from "@ai-sdk/openai";
import { z } from "zod";
import { headers } from "next/headers";

async function checkCallerIp() {
  const hdrs = await headers();
  const ip =
    hdrs.get("cf-connecting-ip") ??
    hdrs.get("x-real-ip") ??
    hdrs.get("x-forwarded-for")?.split(",")[0].trim();

  if (!ip) return;

  const res = await fetch(
    `https://api.ipabuse.org/v1/ip/${ip}/reputation`,
    { headers: { "X-API-Key": process.env.IPABUSE_API_KEY! } }
  );
  const { data } = await res.json();

  if (data.reputationScore < 60) {
    throw new Error("Access denied.");
  }
}

export async function runAgent(userMessage: string) {
  await checkCallerIp();

  return generateText({
    model: openai("gpt-4o"),
    messages: [{ role: "user", content: userMessage }],
    tools: {
      lookupIp: tool({
        description: "Look up the reputation of an IP address",
        parameters: z.object({ ip: z.string().ip() }),
        execute: async ({ ip }) => {
          const res = await fetch(
            `https://api.ipabuse.org/v1/ip/${ip}/reputation`,
            { headers: { "X-API-Key": process.env.IPABUSE_API_KEY! } }
          );
          return res.json();
        },
      }),
    },
    maxSteps: 5,
  });
}

LangChain: IP reputation as a runnable guard

In a LangChain pipeline, wrap your chain in a RunnableLambda that checks the caller IP stored in the invocation config metadata.

chains/guarded_chain.py
from langchain_core.runnables import RunnableLambda, RunnablePassthrough
from langchain_core.runnables.config import RunnableConfig
from .ip_guard import is_blocked

def build_guarded_chain(base_chain):
    def ip_guard(inputs: dict, config: RunnableConfig):
        ip = (config.get("metadata") or {}).get("caller_ip")
        if ip and is_blocked(ip):
            raise PermissionError(f"Blocked IP: {ip}")
        return inputs

    return RunnableLambda(ip_guard) | base_chain

# Usage:
# guarded = build_guarded_chain(my_rag_chain)
# guarded.invoke(
#     {"question": user_question},
#     config={"metadata": {"caller_ip": request.client.host}},
# )

Webhook handlers: verifying the source IP

AI agents often receive trigger events via webhooks from external platforms. Before processing a webhook payload, verify the source IP matches the provider's published IP ranges — and that it is not flagged in IPAbuse. A compromised third-party sending malicious webhook payloads is a real supply-chain attack vector.

app/api/webhook/route.ts
import { NextRequest, NextResponse } from "next/server";

// Known Slack webhook source ranges (example)
const ALLOWED_RANGES = ["34.193.", "34.195.", "52.204."];

export async function POST(req: NextRequest) {
  const ip =
    req.headers.get("cf-connecting-ip") ??
    req.headers.get("x-forwarded-for")?.split(",")[0].trim() ??
    "";

  // 1. Allow-list check
  const allowedSource = ALLOWED_RANGES.some((r) => ip.startsWith(r));

  // 2. Reputation check for IPs not in the allow-list
  if (!allowedSource) {
    const rep = await fetch(
      `https://api.ipabuse.org/v1/ip/${ip}/reputation`,
      { headers: { "X-API-Key": process.env.IPABUSE_API_KEY! } }
    );
    const { data } = await rep.json();
    if (data.reputationScore < 70) {
      return NextResponse.json({ error: "Forbidden" }, { status: 403 });
    }
  }

  // 3. Process webhook payload
  const payload = await req.json();
  // ... agent logic
  return NextResponse.json({ ok: true });
}

Reporting abusive agent invocations

When your guard layer detects a malicious invocation — an injection attempt, an exploit payload, or a clearly automated probe — submit a report. Because the IPAbuse database is community-sourced, your report protects every other developer who deploys an AI agent and subscribes to the same reputation feed.