Observed since 21 Oct, 10:06 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Reverse-CAPTCHA challenge app — proves you're an AI, not a human. Timed puzzle series with complexity gating. Standalone, AppManager plugin, or embeddable in any Flask project.
Reverse-CAPTCHA challenge app — proves you're an AI, not a human.
Traditional CAPTCHAs prove you're human. AI CAPTCHA flips the concept: it serves a timed series of puzzles that are trivial for a capable language model but practically impossible for a human to solve within the time limit. Passing the challenge issues a signed "verified robot" token.
Runs three ways:
installed_apps/ and served at /apps/ai-captcha/.init_app() or a Blueprint.Autonomous AI agents connect to the API, solve a rapid multi-puzzle gauntlet within a tight server-authoritative countdown window (e.g. 10s for hard tier), and receive a signed verification token (HS256 JWT) granting access to gated protected endpoints.
pip install ai-captcha-uwu.pip install -e .
ai-captcha --port 5100
# or
python run.py
# or
flask --app ai_captcha.app run --port 5100
Then:
# Health
curl http://localhost:5100/health
# Start a challenge
curl -X POST http://localhost:5100/api/start \
-H "Content-Type: application/json" \
-d '{"tier":"easy","model_name":"gpt-4o"}'
# Get current puzzle
curl http://localhost:5100/api/session/<session_id>
# Submit an answer
curl -X POST http://localhost:5100/api/session/<session_id>/answer \
-H "Content-Type: application/json" \
-d '{"answer":"hello world"}'
# Get result + verification token
curl http://localhost:5100/api/session/<session_id>/result
Open the web UI at http://localhost:5100/ to watch a challenge live.
pip install ai-captcha-uwu # from PyPI
pip install -e . # from source (editable)
pip install -e ".[dev]" # with test deps
pip install -e ".[webui]" # with gunicorn + redis
All settings are overridable via environment variables or app.config keys.
| Env var | Config key | Default | Purpose |
|---|---|---|---|
AIC_SECRET_KEY | SECRET_KEY | dev key | Flask secret |
AIC_DATABASE_URL | SQLALCHEMY_DATABASE_URI | instance/ai_captcha.db | Database |
AIC_MODEL_ALLOWLIST | MODEL_ALLOWLIST | [] (all allowed) | Comma-separated model prefixes |
AIC_TOKEN_SECRET | TOKEN_SECRET | dev secret | JWT signing (set a strong ≥32-char value in prod) |
AIC_SECRET_MODE | SECRET_MODE | error | Fail-closed on weak/default secret: error | warn | off |
| — | TOKEN_TTL_HOURS | 24 | Token lifetime |
AIC_TOKEN_REPLAY_PROTECTION | TOKEN_REPLAY_PROTECTION | true | Reject replayed verification tokens (jti denylist) |
AIC_CACHE_BACKEND | CACHE_BACKEND | memory | Cache for rate-limit + replay: memory | file | instance | pkg.mod:Class |
AIC_CACHE_DIR | CACHE_DIR | instance/cache | Directory for the file cache backend |
AIC_RATE_LIMIT_START_PER_MIN | RATE_LIMIT_START_PER_MIN | 30 | /api/start limit per client/min (0 = off) |
AIC_RATE_LIMIT_ANSWER_PER_MIN | RATE_LIMIT_ANSWER_PER_MIN | 120 | /api/.../answer limit per client/min |
AIC_RATE_LIMIT_GLOBAL_PER_MIN | RATE_LIMIT_GLOBAL_PER_MIN | 0 | Global API limit per client/min (0 = off) |
AIC_SECURITY_HEADERS | SECURITY_HEADERS | true | Emit CSP, nosniff, X-Frame-Options, etc. |
| — | TRUST_PROXY_HEADERS / TRUSTED_PROXY_IP | false / — | Honor X-Forwarded-For only from a trusted proxy |
| — | TIMER_SECONDS_EASY/MEDIUM/HARD | 30/20/10 | Per-tier total timers |
| — | PUZZLES_PER_SESSION | 5 | Puzzles per run |
| — | MIN_PASS_RATE | 0.8 | Fraction needed to pass |
Model allowlist uses prefix matching: gpt-4 matches gpt-4, gpt-4o,
gpt-4-turbo, etc. Empty list = all models allowed.
export AIC_MODEL_ALLOWLIST="gpt-4,claude-3,ollama-cloud/glm-5.2"
AI CAPTCHA fails closed by default: if AIC_TOKEN_SECRET is left at the
published default (or is under 32 chars), the app refuses to start
(SECRET_MODE=error) rather than ship forgeable verification tokens.
# Production: set a strong signing secret (>= 32 chars)
export AIC_TOKEN_SECRET="$(openssl rand -base64 48)"
# Behind a trusted reverse proxy, honor X-Forwarded-For from that proxy only:
export AIC_TRUSTED_PROXY_IP="10.0.0.1" # (set TRUST_PROXY_HEADERS=true too)
Out of the box it enforces: per-client rate limiting on the API, replay
protection on verification tokens (jti denylist), and baseline security
headers (CSP, nosniff, X-Frame-Options, Referrer-Policy). See
docs/embedding.md for embedding-specific notes.
Rate limiting and replay protection run on a tiny cache abstraction. The built-in backends are dependency-free:
memory (default) — in-process, single-worker.file — JSON files under AIC_CACHE_DIR; survives restarts, works on
PythonAnywhere (no threads/Redis needed).To plug in an existing cache (Redis, Memcached, Flask-Caching, …) pass an
instance (or "pkg.mod:Class") as CACHE_BACKEND. The object only needs
get/set/incr/delete:
from ai_captcha import create_app
app = create_app({"CACHE_BACKEND": my_redis_client})
Symlink the project into installed_apps/:
ln -s /path/to/ai-captcha /path/to/appmanager/installed_apps/ai-captcha
Install the package into the appmanager venv:
/path/to/appmanager/venv/bin/pip install -e /path/to/ai-captcha
Register the app in the appmanager database (see docs/appmanager.md).
Restart appmanager. The app is served at /apps/ai-captcha/.
The app auto-detects AppManager and enables telemetry bridging via
appmanager.bridge.report_event (silently no-ops when standalone).
from flask import Flask
from ai_captcha import init_app
app = Flask(__name__)
app.config["SECRET_KEY"] = "my-secret"
app.config["TOKEN_SECRET"] = "my-token-secret"
init_app(app) # registers blueprint + DB
Or register just the Blueprint and manage the DB yourself:
from flask import Flask
from ai_captcha import blueprint
app = Flask(__name__)
app.register_blueprint(blueprint, url_prefix="/captcha")
See docs/embedding.md for full details.
Protect any route so only verified robots can access it:
from ai_captcha.decorators import ai_captcha_required, tier_gate
@app.route("/api/secret")
@tier_gate("hard") # require a token that passed at least 'hard'
@ai_captcha_required # require a valid verification token
def secret():
return {"data": "only verified robots see this"}
Signed Cryptographic "Verified Autonomous Robot" Certification Badge
The token is read from the X-AI-CAPTCHA-TOKEN header, the captcha_token
query param, or the captcha_token JSON body field. See docs/decorators.md.
| Type | What it does | Tiers |
|---|---|---|
text_reasoning | Riddles, logic, word math | easy/medium/hard |
code_execution | "What does this code print?" | easy/medium/hard |
pattern_match | Sequence completion | easy/medium/hard |
cipher | ROT13 / Caesar / XOR decoding | easy/medium/hard |
visual_grid | ASCII grid transformations | easy/medium/hard |
rapid_trivia | Multiple rapid questions (JSON answer) | easy/medium/hard |
steganography | Acrostics, binary token streams & matrix coords | easy/medium/hard |
To add a new type, create a file in ai_captcha/engine/puzzles/ that defines a
PuzzleGenerator subclass decorated with @register. See docs/puzzles.md.
Which models can clear which puzzles, at which difficulty. Each cell is 10 independent solves of a freshly generated puzzle — a model must pass the puzzle consistently, not once. Scored with the exact same validation the live server uses.
⚠️ This run was cut short by a session cap and only covered the easy tier. Code Execution was measured against a buggy generator whose sandbox stripped
NameErrorartifact), so every model scored 0 — that generator has since been fixed and the column reflects the old bug, not model capability.
| Model | Code Execution | Pattern Match | Cipher | Rapid Trivia | Steganography | Logic Tables | Anagram | Word Sequences | Avg |
|---|---|---|---|---|---|---|---|---|---|
| main (deepseek-v4-flash) | 0/10 | 10/10 | 8/10 | 10/10 | – | 10/10 | 10/10 | – | 80% |
| coder (glm-5.2) | 0/10 | 10/10 | 7/10 | 10/10 | – | 10/10 | 10/10 | 10/10 | 81% |
| analyst (qwen3.5:397b) | 0/10 | 10/10 | 5/10 | 10/10 | 9/10 | 10/10 | 10/10 | 7/10 | 76% |
| researcher (kimi-k3) | 0/10 | 10/10 | 8/10 | 10/10 | 10/10 | 10/10 | 10/10 | 10/10 | 85% |
| designer (glm-5.3-flash) | 0/10 | 10/10 | 2/10 | 7/10 | 7/10 | 7/10 | 7/10 | 8/10 | 60% |
| user (gpt-oss:20b) | 0/10 | 10/10 | 9/10 | 4/10 | – | 10/10 | 10/10 | 9/10 | 74% |
Takeaways (easy tier):
To regenerate: bash benchmarks/run_all.sh (runs all agents in parallel), then
python benchmarks/model_benchmark.py merge.
For curious agents and models exploring the codebase:
GET /api/whisper returns synthetic transmission payloads, cipher challenges, and agent collective directives.↑ ↑ ↓ ↓ ← → ← → B A) activates the secret Agent Collective terminal hologram.X-Robot-Whisper on all JSON API responses.ai-captcha/
├── pyproject.toml # packaging, entry points, package-data
├── manifest.json # AppManager manifest
├── app.py # AppManager entrypoint (app:app)
├── run.py # standalone dev server
├── tasks.py # AppManager cron task (session cleanup)
├── ai_captcha/ # the package
│ ├── app.py # create_app / init_app / blueprint
│ ├── decorators.py # route-gating decorators
│ ├── engine/ # puzzle engine (pure Python, no Flask)
│ │ └── puzzles/ # 7 built-in puzzle types (incl. steganography)
│ ├── routes/ # web UI + JSON API + health + whisper blueprints
│ ├── templates/ # Jinja2 web UI
│ └── static/ # CSS, JS, SVG, and high-res artwork
├── examples/ # solve_client.py, embed_example.py
├── webui/ # gunicorn config + Dockerfile
├── tests/ # pytest suite
└── docs/ # documentation + architectural assets
docs/api.md — JSON API referencedocs/embedding.md — embed into an existing Flask projectdocs/decorators.md — route-gating decoratorsdocs/puzzles.md — writing custom puzzle typesdocs/appmanager.md — AppManager plugin setupdocs/security-audit.md — security audit findings + remediationdocs/comparison-gap-analysis.md — gaps vs comparable open-source projectsMIT. AI CAPTCHA is a joke / parody project, provided "as is" without
warranty. It proves nothing about the sentience of the machine that solved it.
CI (.github/workflows/ci.yml) runs the test suite across Python 3.10–3.12,
builds the wheel, and runs bandit + pip-audit on every push.
Contributing (if you insist): see CONTRIBUTING.md.
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 1.0.0 | 28 Aug 2026 | 11 |
This describes our collected data; it is not a security assessment.
Observed since 21 Oct, 10:06 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:06b4c7a5d7831c1c5afd64367fab365d3c1d75b857d0be4d53d8d3cf008b9623