Challenge Types
KEPCA supports six challenge types. Each can be enabled or disabled per site from the dashboard or via the REST API. The adaptive risk engine selects the appropriate challenge based on the visitor's risk score.
Overview
| Challenge | Risk Tier | User Interaction | Bot Resistance | Accessibility |
|---|---|---|---|---|
| Invisible | 1 (low) | None | Medium | Perfect |
| PoW | 1-2 | None (spinner) | High | Perfect |
| Checkbox | 2 | Single click | Medium | Good |
| Slider | 2-3 | Drag interaction | High | Moderate |
| Grid | 3 (high) | Image selection | Very High | Moderate |
| Interactive | 3 (high) | Custom puzzle | Very High | Moderate |
| Text | 2-3 | Text input | High | Good |
Invisible Pass
When the risk score is below the invisible_max threshold, the user passes without any visible challenge. The widget briefly shows a spinner while signals are evaluated, then displays a green checkmark.
No configuration needed -- this is the default behavior for low-risk traffic.
Proof of Work (PoW)
A SHA-256 hash puzzle solved in a Web Worker (or via Rust WASM for faster performance). The difficulty scales with the risk score using adaptive difficulty.
{
"active_challenges": ["pow"],
"risk_thresholds": {
"invisible_max": 0.3,
"pow_max": 0.8
}
}Adaptive PoW difficulty
The difficulty parameter controls how many leading zero bits the hash must have. KEPCA adjusts this dynamically:
| Risk Score | Difficulty (bits) | Approximate solve time |
|---|---|---|
| 0.3 - 0.4 | 12 | ~50ms |
| 0.4 - 0.5 | 15 | ~200ms |
| 0.5 - 0.6 | 18 | ~1s |
| 0.6 - 0.7 | 20 | ~4s |
| 0.7 - 0.8 | 22 | ~15s |
Higher difficulty forces bots to spend more CPU, making large-scale attacks economically impractical.
WASM solver
The widget ships with a Rust-compiled WASM solver that is 3-5x faster than the JavaScript fallback. It is loaded automatically when the browser supports WebAssembly. You can force the JS-only solver with:
<maptcha-widget data-sitekey="..." data-solver="js"></maptcha-widget>Checkbox
The classic "I am not a robot" checkbox. When clicked, the full signal collection and risk scoring pipeline runs behind the scenes. If the risk score stays low, the checkbox turns green immediately. Otherwise, an additional challenge is issued.
{
"active_challenges": ["checkbox"],
"risk_thresholds": {
"checkbox_max": 0.6
}
}Good for login pages and forms where you want visible user confirmation.
Slider
A drag-to-target slider challenge. The user drags a handle to a marked position. The widget collects mouse trajectory signals (speed, acceleration, deviation) to distinguish human drag patterns from scripted movements.
{
"active_challenges": ["slider"],
"risk_thresholds": {
"slider_min": 0.4
}
}Configuration
| Option | Type | Default | Description |
|---|---|---|---|
slider_tolerance | number | 5 | Pixel tolerance for target position |
slider_track_width | number | 280 | Track width in pixels |
Grid
An image grid challenge where the user selects cells matching a prompt (e.g., "Select all images containing traffic lights"). Uses server-side generated grids with distortion to resist OCR-based solvers.
{
"active_challenges": ["grid"],
"risk_thresholds": {
"grid_min": 0.6
}
}Configuration
| Option | Type | Default | Description |
|---|---|---|---|
grid_size | string | "3x3" | Grid dimensions: "3x3" or "4x4" |
grid_min_select | number | 3 | Minimum cells user must select |
Interactive
Custom interactive puzzles that are highly resistant to automated solving. These include map-based challenges (drag a pin to a location), pattern-drawing challenges, and object-rotation puzzles.
{
"active_challenges": ["interactive"],
"risk_thresholds": {
"interactive_min": 0.6
}
}Interactive challenges collect the richest behavioral signals and are recommended for high-security scenarios (payment forms, account recovery).
Available puzzle types
| Puzzle | Description |
|---|---|
map_pin | Place a pin on a map at the described location |
pattern_draw | Draw the displayed pattern on a canvas |
object_rotate | Rotate a 3D object to match a target angle |
Text
Text-based challenges for accessibility or low-bandwidth scenarios. Includes simple math problems, word completion, and basic reasoning questions.
{
"active_challenges": ["text"],
"risk_thresholds": {
"text_min": 0.4
}
}Example challenges
- "What is 7 + 3?"
- "Complete the word: Eleph___"
- "Which of these is a color: bicycle, red, piano?"
Text challenges serve as the primary accessibility fallback. They are automatically offered when the widget detects a screen reader.
Combining challenges
You can enable multiple challenge types per site. The adaptive engine picks the best challenge for each request based on risk score and client capabilities:
{
"active_challenges": ["pow", "checkbox", "slider", "grid", "interactive", "text"],
"risk_thresholds": {
"invisible_max": 0.3,
"checkbox_max": 0.5,
"pow_max": 0.6,
"slider_min": 0.4,
"grid_min": 0.6,
"interactive_min": 0.7,
"text_min": 0.4
}
}Behavioral signals
KEPCA collects passive behavioral signals to improve risk scoring without requiring user interaction.
Tier 1 signals (collected on page load)
| Signal | Description |
|---|---|
time_on_page_ms | Time since page load |
submit_time_ms | Time between page load and form submit |
honeypot_filled | Whether a hidden field was filled |
user_agent | Browser UA string and anomaly detection |
tls_fingerprint | JA3/JA4 TLS fingerprint |
request_count | Requests from same source in window |
ip_hash | SHA-256 of client IP |
Tier 2 signals (collected during interaction)
| Signal | Description |
|---|---|
mouse_movements | Mouse trajectory, speed, acceleration patterns |
mouse_clicks | Click coordinates, timing, and frequency |
keyboard_dynamics | Typing speed, key hold duration, flight time |
scroll_behavior | Scroll depth, speed, direction changes |
touch_patterns | Touch pressure, swipe velocity (mobile) |
focus_changes | Tab/window focus events and timing |
Tier 2 signals are privacy-safe: raw data never leaves the browser. The analyzer computes feature vectors locally and sends only aggregate scores.
ML scoring foundation
The risk scoring engine uses a lightweight gradient-boosted model trained on labeled traffic data. The model evaluates all available signals and produces a composite risk score (0.0 to 1.0). Site owners can retrain the model on their own traffic patterns via the dashboard.
Model inputs:
- Tier 1 passive signals (7 features)
- Tier 2 behavioral signals (6 feature groups)
- Historical session data (repeat visitor patterns)
- Challenge solve metrics (time, accuracy, retries)
Next steps
- Security -- rate limiting, key rotation, and token verification
- Enterprise -- team management, custom domains, and billing
- REST API -- endpoint reference for challenge configuration
