Stop bad bots at the edge
Every request that reaches an ngris endpoint gets a bot score from 1 to 99. Turn on Under attack mode to make visitors pass a browser check, block clients by their JA3/JA4 TLS fingerprint, and let verified search and AI crawlers through. It is a rule on the endpoint, so it protects an agent tunnel to your laptop and an app hosted on ngris the same way.
- One switch: Under attack mode
- Tunnels and hosted apps
- No third-party CAPTCHA
rules:
- phase: on_http_request
rule_type: challenge
name: "Under attack"
config:
mode: smart
pass_score: 70
block_score: 10
interaction: checkbox
skip_paths: [/api/, /webhooks/]
allow_verified_bots: true
Every request gets a bot score
The edge scores each HTTP request from 1 (almost certainly automated) to 99 (looks like a person's browser), with a reason code for every point it takes off. A normal browser scores about 95.
User agent
Headless and automation tools (HeadlessChrome, Puppeteer, Playwright, Selenium, curl, python-requests, Scrapy and more) score 5 or lower. Self-declared crawlers are classed as crawlers.
Browser headers
Real browsers send Accept, Accept-Language, Accept-Encoding and Fetch Metadata, and speak HTTP/2 over TLS. A script that only copied a browser's user agent loses points for each one it misses.
Network
A browser on a cloud range (AWS, Google Cloud, Oracle, DigitalOcean, Linode) or a Tor exit loses points. Anything from a Spamhaus DROP network is capped at 2.
Fake crawlers
A user agent that names Googlebot, Bingbot or GPTBot from outside its operator's published IP ranges is an impersonator, and is capped at 2.
Use it in any rule's expression: req.bot_score < 30 && !req.verified_bot, req.bot_class == "automation", "datacenter" in req.bot_reasons. Send it to your app as the X-Ngris-Bot-Score header, and see it on every request in the traffic inspector.
Under attack mode: a browser check before your origin
A challenge rule makes each visitor's browser solve a small SHA-256 proof-of-work, then the edge sets an HMAC-signed clearance cookie bound to your site, the browser and, by default, the network. Nothing goes to a third party. Turn it on with the Under attack mode switch on the endpoint's Overview tab.
- Automatic: no clicks; the browser solves the proof-of-work and lands on the page.
interaction: automatic - Checkbox: the visitor also ticks “I’m a person”, a step generic bots skip.
interaction: checkbox - Puzzle: slide a piece into a gap; every attempt costs a fresh proof-of-work.
interaction: puzzle
Always, or only the suspicious
mode: always checks every visitor without a clearance. mode: smart lets a score at or above pass_score through, sends a 403 below block_score, and checks the rest. Defaults 70 and 10, both yours to change.
Runs before everything else
Challenge rules run before every other request rule and before the edge cache, so no cached page reaches a visitor who hasn't passed.
Re-checks busy visitors
Each clearance has its own ID. A visitor who sends more than clearance_max_rpm requests a minute (default 600) loses it and gets a stronger check.
Keeps your API working
Calls that can't show a page get a 403 with X-Ngris-Challenge: required. List API and webhook prefixes in skip_paths and your monitors in allow_ips.
What it doesn't do: it stops tools that don't run JavaScript and makes every client pay for the check, but a headless browser can pass it. Pair it with a rate limit for floods from real browsers.
Fingerprints, verified crawlers and shared reputation
The score is one signal. The edge also knows how a client speaks TLS, which crawlers are real, and which IPs misbehaved elsewhere on the network.
JA3 and JA4 fingerprints
The edge fingerprints each TLS ClientHello as JA3 and JA4. The bot-management rule blocks or only logs by allow and deny lists of either, and conn.ja3 is available in expressions.
Verified crawlers
Crawlers from Google, Bing, Apple, DuckDuckGo, OpenAI and Perplexity are checked against the IP ranges each operator publishes, and pass a challenge so your site stays in search and AI answers. Rules see req.verified_bot.
Shared reputation
Repeated challenge failures, WAF blocks and abuse-limit blocks lower an IP's score on every ngris endpoint in the region for an hour. Only a score crosses accounts, never your data.
Seven checks, in an order you can rely on
Bot protection sits in line with the firewall, rate limits, your rules and edge login. Any step can stop a request before your origin sees it.
Firewall policies
Allow, block or challenge across your account by source IP, country, ASN, browser, user agent, endpoint, path, method, header, cookie, protocol or port, joined with AND/OR, in the order you set. Firewall docs
WAF
The waf rule runs the Coraza engine with a built-in baseline for SQL injection, XSS, path traversal, command injection, Log4Shell, template injection and scanner user agents, plus your own SecLang rules. Start in detect mode, then block.
Rate limits
A rate-limit rule counts per IP, header, cookie or JWT claim. Rate-limit rules take the firewall's conditions and block or throttle.
Rules from plain English
Iris, the dashboard assistant, drafts firewall and rate-limit rules from a sentence. Nothing is saved until you confirm. About Iris
See what was stopped
The Security Analytics page in the dashboard turns your traffic into who attacked, from where, and what stopped them.
Mitigation over time
Total requests, mitigated requests and the mitigation rate, with firewall and rate-limit blocks charted apart.
Attacker fingerprints
Top source IPs, ASNs, countries, user agents and paths. From a row, Block with a firewall rule opens a policy already filled in.
The rule that fired
Top firing rules and recently mitigated requests with the rule that stopped each one. The traffic inspector shows every request's bot score.
Works on tunnels and apps
Bot protection is a rule on an endpoint, not an app setting. Agent tunnels and apps hosted on ngris are both endpoints, so they get the same protection at the edge.
Agent tunnels
Run ngris http 3000 on your laptop, a server or in Kubernetes. The score, the check and every rule run at the edge, so blocked traffic never reaches your machine.
Hosted apps
Static sites, full-stack and Docker apps, WordPress and functions on ngris get the same Under attack switch and the same rules. App hosting
TCP and UDP
Firewall policies, IP rules and rate limits apply when a connection opens. A Challenge action blocks there, since there is no browser to check.
Frequently asked questions
What is the ngris bot score?
Every HTTP request that reaches an ngris endpoint gets a score from 1 (almost certainly automated) to 99 (looks like a person's browser). It is built from the user agent, the headers every browser sends, the client's network (cloud ranges, Tor exits, Spamhaus DROP), fake-crawler checks and the IP's shared reputation. Your rules read it as req.bot_score, and you can pass it to your app in the X-Ngris-Bot-Score header.
How does Under attack mode work?
It is a challenge rule on the endpoint. The visitor's browser solves a small SHA-256 proof-of-work, and the edge sets a signed clearance cookie for that site and browser; nothing is sent to a third party. Requests that can't show the check page, such as API calls and curl, get a 403 unless their path is in skip_paths or their IP is in allow_ips.
Will it block Google or AI crawlers?
Not by default. Crawlers from Google, Bing, Apple, DuckDuckGo, OpenAI and Perplexity go through when their IP is in the ranges their operator publishes, so your site stays in search and AI answers. A bot that only copies their user agent is checked like anyone else, and you can set allow_verified_bots to false to check the real ones too.
Does the challenge stop headless browsers?
Not on its own. It stops scripts and tools that don't run JavaScript and makes every client pay for the check, but a headless browser can pass it. Pair it with a rate limit, JA3/JA4 fingerprint rules and firewall policies for floods from real browsers.
Does bot protection work on agent tunnels and hosted apps?
Yes. It is a traffic-policy rule on an endpoint, and agent tunnels and apps hosted on ngris are both endpoints, so the same rules run at the edge before a request reaches your machine or your app. On TCP and UDP endpoints there is no page to show a check on, so a firewall Challenge action blocks the connection instead.
Will it break my API clients or webhooks?
No, if you tell it where they are. A call that cannot show a page gets a 403 with X-Ngris-Challenge: required instead of an HTML challenge. List your API and webhook path prefixes in skip_paths and your monitoring IPs in allow_ips, and they are never challenged.
Keep bots off your endpoints.
Start free, no card needed. Turn on Under attack mode for a tunnel or an app in one switch.