Skip to content

VPN & proxy detection

Arcjet provides IP reputation information in two places:

  • Decisions after calling protect() include IP address analysis fields depending on your pricing plan. You can use this to customize responses. See the SDK reference for details e.g. Next.js.
  • Filter rules have access to IP address analysis. You can use this to block traffic.
  • IP AS type. This is the Autonomous System associated with the IP, which can be used to identify VPNs and proxies. This can be one of isp, hosting, business or education.
  • IP type. Arcjet adds one or more categories to the IP address to help you identify VPNs and proxies. The categories are vpn, proxy, tor, hosting, relay.
FiltersDecisionFreeStarterBusiness
ip.src.asnum.countryip.asnCountry🚫
ip.src.asnum.domainip.asnDomain🚫
ip.src.asnum.nameip.asnName🚫
ip.src.asnum.typeip.asnType🚫
ip.src.asnumip.asn🚫
ip.src.serviceip.service
ip.src.hostingip.isHosting()
ip.src.proxyip.isProxy()
ip.src.relayip.isRelay()
ip.src.torip.isTor()
ip.src.vpnip.isVpn()

The IP analysis fields may be undefined, but you can use various methods to check their availability. See the SDK reference for details.

// ... imports, client configuration, etc
// See https://docs.arcjet.com/get-started
const decision = await aj.protect(req);
if (decision.ip.hasASN() && decision.ip.asnType === "hosting") {
// The network this IP belongs to is a hosting provider, which makes it more
// likely to be a VPN, proxy, or other suspicious network.
}
if (
decision.ip.isHosting() ||
decision.ip.isProxy() ||
decision.ip.isRelay() ||
decision.ip.isTor() ||
decision.ip.isVpn()
) {
// The IP is from a hosting provider, proxy, relay, Tor, or VPN. We can check the name
// of the service and customize the response
if (decision.ip.hasService()) {
if (decision.ip.service === "Apple Private Relay") {
// We trust Apple Private Relay because it requires an active iCloud
// subscription, so we can allow it
} else {
// Do something else
}
} else {
// The service name is not available, but we can still do something here
}
}

Filter rules can be used to block traffic based on IP reputation:

// …
rules: [
filter({
deny: ['ip.src.vpn'],
mode: "LIVE",
})
],
// …
const decision = await aj.protect(req);
if (decision.isDenied()) {
// Return 403 Forbidden
}

Customize response for Apple Private Relay

Section titled “Customize response for Apple Private Relay”

The ip field on a decision can be used to customize the response based on IP reputation:

// …
const decision = await aj.protect(req);
if (decision.isDenied()) {
// Handle your other configured rules here.
}
// Otherwise, customize for Apple Private Relay:
if (decision.ip.service === "Apple Private Relay") {
return new Response("Hello, Apple Private Relay user!");
}