Documentation Index
Fetch the complete documentation index at: https://mintlify.com/TecharoHq/Anubis/llms.txt
Use this file to discover all available pages before exploring further.
Anubis uses proof-of-work challenges to distinguish legitimate browsers from bots. This page covers challenge difficulty settings and available challenge methods.
Challenge Settings
Challenges can be configured globally (via command-line flags) or per-rule (in the policy file).
Global Configuration
# Set default difficulty for all challenges
anubis --difficulty 2
# Or via environment variable
export DIFFICULTY=2
Default difficulty: 2
Per-Rule Configuration
bots:
- name: suspicious-browsers
user_agent_regex: "(?i:bot|crawler)"
action: CHALLENGE
challenge:
difficulty: 4
algorithm: fast
Challenge Parameters
Difficulty
Difficulty controls the number of leading zero bits required in the proof-of-work hash.
| Field | Type | Range | Default |
|---|
difficulty | int | 0-64 | 2 |
Valid range: 0 to 64
- Too low (
< 0): ErrChallengeDifficultyTooLow
- Too high (
> 64): ErrChallengeDifficultyTooHigh
Recommended Difficulty Levels
| Difficulty | Solve Time | Use Case |
|---|
| 0 | Instant | Development/testing only |
| 1 | < 100ms | Meta refresh challenges |
| 2 | ~200ms | Default for most traffic |
| 3 | ~500ms | Moderate suspicion |
| 4 | ~1s | High suspicion |
| 8 | ~10s | Extreme cases (use with care) |
| 16+ | Minutes | Effectively blocks all traffic |
Solve times are approximate and depend on client device performance.
Algorithm
Anubis supports multiple challenge algorithms:
| Algorithm | Description | Client Support |
|---|
fast | SHA-256 proof-of-work | Modern browsers |
metarefresh | HTML meta refresh (no JavaScript) | All browsers |
preact | React-based challenge UI | Modern browsers |
slow | Deprecated SHA-256 (use fast instead) | Legacy |
Default: fast
Challenge Methods
Fast (Recommended)
SHA-256 proof-of-work challenge using WebCrypto API:
challenge:
algorithm: fast
difficulty: 2
Advantages:
- Fast client-side computation
- No external dependencies
- Works in all modern browsers
Requirements:
- JavaScript enabled
- WebCrypto API support (all modern browsers)
HTML-only challenge using <meta http-equiv="refresh">:
challenge:
algorithm: metarefresh
difficulty: 1
Advantages:
- No JavaScript required
- Works in text browsers (lynx, w3m)
- Accessible to screen readers
Limitations:
- Lower difficulty only (recommend
difficulty: 1)
- Slower user experience
- Cannot use client-side computation
Use cases:
- Accessibility requirements
- JavaScript-disabled environments
- Low-suspicion traffic
Preact
React-based UI with visual feedback:
challenge:
algorithm: preact
difficulty: 2
Advantages:
- Better user experience
- Progress indicators
- Error handling UI
Requirements:
- Modern JavaScript support
- Same as
fast algorithm
Slow (Deprecated)
Legacy algorithm. Use fast instead:
challenge:
algorithm: slow # Don't use this
difficulty: 2
Anubis will log a warning if slow is detected. Update to fast when possible.
Challenge Configuration Examples
Lightweight Protection
bots:
- name: generic-browser
user_agent_regex: "Mozilla"
action: CHALLENGE
challenge:
algorithm: metarefresh
difficulty: 1
Standard Protection
bots:
- name: browsers
user_agent_regex: "Mozilla"
action: CHALLENGE
challenge:
algorithm: fast
difficulty: 2
Heavy Protection
bots:
- name: suspicious-traffic
user_agent_regex: "(?i:bot|crawler)"
action: CHALLENGE
challenge:
algorithm: fast
difficulty: 4
Graduated Protection with Weights
thresholds:
- name: minimal-suspicion
expression: weight < 0
action: ALLOW
- name: low-suspicion
expression:
all:
- weight >= 0
- weight < 10
action: CHALLENGE
challenge:
algorithm: metarefresh
difficulty: 1
- name: moderate-suspicion
expression:
all:
- weight >= 10
- weight < 20
action: CHALLENGE
challenge:
algorithm: fast
difficulty: 2
- name: high-suspicion
expression: weight >= 20
action: CHALLENGE
challenge:
algorithm: fast
difficulty: 4
Custom Status Codes
By default, challenges return HTTP 200 to deceive scrapers. You can customize this:
status_codes:
CHALLENGE: 200 # Default
DENY: 200 # Default
# Or use standard codes
status_codes:
CHALLENGE: 403 # Forbidden
DENY: 429 # Too Many Requests
Valid range: 100-599
Challenge Cookies
Successful challenge solutions are stored in cookies:
Cookie Configuration
# Cookie domain (for subdomain sharing)
anubis --cookie-domain example.com
# Dynamic domain (auto-detect from request)
anubis --cookie-dynamic-domain
# Cookie expiration (default: 24 hours)
anubis --cookie-expiration-time 48h
# Cookie security flags
anubis --cookie-secure=true # HTTPS only (default)
anubis --cookie-same-site None # None, Lax, Strict, Default
anubis --cookie-partitioned # CHIPS support
Cookie Names
Cookies are prefixed (default: anubis):
# Custom prefix
anubis --cookie-prefix myapp
# Results in cookies:
# - myapp-auth
# - myapp-cookie-verification
JWT Signing
Challenge solutions are signed with Ed25519 or HMAC-SHA512. See Security for key configuration.
Validation
Common configuration errors:
Missing Algorithm
challenge:
difficulty: 2
# Error: ErrChallengeMustHaveAlgorithm
Fix: Always specify algorithm:
challenge:
algorithm: fast
difficulty: 2
Invalid Difficulty
challenge:
algorithm: fast
difficulty: 100 # Error: ErrChallengeDifficultyTooHigh
Fix: Use difficulty between 0-64:
challenge:
algorithm: fast
difficulty: 4
CHALLENGE without Challenge Config
- name: browsers
action: CHALLENGE
# Error if no global default set
Fix: Either set global default or specify per-rule:
- name: browsers
action: CHALLENGE
challenge:
algorithm: fast
difficulty: 2
Client-Side
- Difficulty 2: ~200ms on modern devices
- Difficulty 4: ~1s on modern devices, ~5s on older devices
- Difficulty 8+: May timeout on mobile devices
Server-Side
Challenges are stateless and require no server computation. Server load comes from:
- Challenge page delivery (minimal)
- JWT verification (fast)
- Storage backend operations (depends on backend)
Testing Challenges
Test challenge configuration without blocking traffic:
# Force all requests to show challenge
anubis --debug-benchmark-js
This bypasses all rules and presents challenges to every request.
Next Steps