ALTCHA is an open-source, privacy-centric CAPTCHA that replaces puzzle challenges with a tiny client-side proof-of-work (PoW) and optional adaptive challenges (with audio, i18n, RTL). For production-grade needs, ALTCHA Sentinel adds a self-hosted anti-spam/anti-bot platform: multi-layer detection, rate limiting, reputation, ML text classification and policy controls—deployable on Docker/Kubernetes, no third-party data flows, GDPR/EAA compliant.
Why sysadmins care
- Self-hosted, no trackers: no cookies, fingerprinting or external calls. Meets GDPR, CCPA, HIPAA, PIPEDA/CPPA, LGPD, DPDPA, PIPL.
- Accessible by default: WCAG 2.2 AA / EAA 2025 (audio fallback, keyboard, high-contrast, RTL, 50+ locales).
- Light & fast: ~30 kB gzipped (46 kB with all locales). Inline bundling ⇒ 0 ms widget load, no third-party latency budgets.
- Operational control: Sentinel runs on-prem / in your VPC (Docker/K8s), integrates with your WAF, SIEM and rate-limiters, and keeps PII in your infra.
Architecture patterns
Client Reverse proxy / WAF App tier
------ --------------------- --------
ALTCHA PoW -> (optionally call Sentinel /verify) -> your handlers
└─ policies: IP reputation, M2M, rate limits, text ML
- OSS only: embed the PoW widget and verify the token in your backend.
- OSS + Sentinel: front the app with Sentinel’s
/verifyand policy engine; escalate to code+audio challenge only when risk rises.
Threat model & controls
- Commodity bots & scripts → PoW + honeypots + token verification.
- Smart bots / headless browsers → Sentinel reputation, device hints, velocity limits, geofencing, TOR/proxy flags.
- Human-assisted spam → text classifier, language detection, allow/deny lists, M2M quotas.
- API/resource protection → M2M ALTCHA: consumer-side rate-limiter & token gating for expensive endpoints.
Quick integration
Frontend (web)
Install the widget (npm: @altcha-org/altcha) and add to a form:
<form method="post" action="/contact">
<textarea name="message"></textarea>
<altcha-widget name="altcha" sitekey="YOUR_SITE_KEY"></altcha-widget>
<button>Send</button>
</form>
<script type="module">
import '@altcha-org/altcha/widget';
</script>
Code language: HTML, XML (xml)
Bundle inline with Vite/Webpack/Rollup for 0 ms load.
Server-side verification (pick your stack)
Node.js / TypeScript
import { verifyAltcha } from '@altcha-org/altcha-node';
app.post('/contact', async (req, res) => {
const ok = await verifyAltcha({ token: req.body.altcha, secret: process.env.ALTCHA_SECRET });
if (!ok) return res.status(403).send('ALTCHA failed');
// handle form
res.send('OK');
});
Code language: JavaScript (javascript)
Go
ok, err := altcha.Verify(altcha.VerifyParams{
Token: r.FormValue("altcha"),
Secret: os.Getenv("ALTCHA_SECRET"),
})
if err != nil || !ok { http.Error(w, "Forbidden", 403); return }
// proceed
Code language: JavaScript (javascript)
PHP
use Altcha\Verify;
$ok = Verify::token($_POST['altcha'], getenv('ALTCHA_SECRET'));
if (!$ok) { http_response_code(403); exit; }
Code language: PHP (php)
Python (Flask)
from altcha import verify
@app.post("/contact")
def contact():
if not verify(request.form.get("altcha"), os.environ["ALTCHA_SECRET"]):
return ("Forbidden", 403)
return "OK"
Code language: JavaScript (javascript)
Sentinel: what you get beyond OSS
- Adaptive CAPTCHA: PoW baseline; escalate to code+audio only on risk.
- Threat intel & device hints: block known bad IPs/URLs; mark proxies/TOR; basic automation fingerprints.
- ML text classifier: label spam/abuse; language detection; dataset hooks.
- Rate limiting: per-IP/user/session; sliding windows; burst rules; 429 integration.
- Geo-policies: allow/deny by region; geofencing for compliance.
- E-mail verification: MX/role/temporary providers checks.
- Form capture API: built-in endpoint with spam filtering when you need a quick drop-in.
Deploy (Docker compose)
services:
sentinel:
image: altcha/sentinel:latest
environment:
- ALTCHA_SECRET=${ALTCHA_SECRET}
- ALTCHA_ADMIN_TOKEN=${ADMIN_TOKEN}
- ALTCHA_LOG_LEVEL=info
ports:
- "8080:8080"
volumes:
- ./sentinel-data:/var/lib/altcha
Code language: JavaScript (javascript)
K8s (Helm sketch)
values:
image: altcha/sentinel:latest
env:
ALTCHA_SECRET: <secretRef>
ALTCHA_ADMIN_TOKEN: <secretRef>
service:
type: ClusterIP
port: 8080
Code language: HTML, XML (xml)
Migration tips (reCAPTCHA / hCaptcha / Turnstile → ALTCHA)
- Instrument first: log current pass/fail, latency and abandon rate.
- Swap widget: embed ALTCHA PoW; keep graceful fallback for JS-off.
- Server verify: add token verification; return 403 or 422 consistently.
- Tune risk: start PoW-only for all; then enable Sentinel policies (IP rep, velocity, geofence) and adaptive code for the top 1-5% risk bucket.
- Measure: compare spam volume, user-side latency and completion rate; iterate thresholds weekly for the first month.
Ops & observability (what to monitor)
- Verification pass/fail by endpoint & region.
- Elevations (when adaptive challenge kicks in).
- Rate-limit events and 429 ratio.
- Spam caught vs false positives (manual review, sampling).
- Latency: widget load (should be ~0), verify endpoint p50/p95.
- Abandon rate across devices (screen readers, mobile, low-end).
Export Sentinel metrics/logs to Prometheus/Grafana and your SIEM (Syslog/JSON).
Security & compliance notes
- Data flow: tokens are stateless; Sentinel verify happens inside your perimeter; no third-party requests.
- PII: keep PoW/verify tokens separate from form payloads; redact prior to log ingestion.
- WCAG/EAA: maintain audio challenge availability; test with screen readers; verify color contrast & focus order.
- DPIA: for GDPR-heavy orgs, document that no tracking/fingerprinting is used; include retention policy for Sentinel logs.
Sizing & performance
- Widget: ~30 kB gz (≈46 kB with 50+ locales). Inline bundle avoids TLS/handshake overhead.
- Verify: lightweight stateless check; cache public keys/params in your app for micro-latency.
- Sentinel: scale horizontally; verify endpoints are CPU-light; ML text checks should be batched/async for large payloads.
Common pitfalls
- Missing server-side verify: PoW in the DOM is not a defense; always verify token serverside.
- JS-only reliance: provide code+audio fallback; ensure forms work with keyboard only.
- Ignoring M2M: protect APIs and expensive endpoints with M2M ALTCHA + per-consumer quotas.
- Over-strict policies: start permissive; increase friction only for high-risk flows.
When to use OSS vs Sentinel
| Scenario | OSS (PoW + verify) | Sentinel (recommended) |
|---|---|---|
| Low-risk contact forms, small sites | ✅ | — |
| User signup/login brute-force & credential-stuffing | ⚠️ | ✅ |
| High-traffic forms, heavy spam, human-assisted abuse | ⚠️ | ✅ |
| Public APIs / cost-intensive endpoints | ⚠️ | ✅ (M2M, quotas, geofence) |
| Regulated sectors / government | ✅ (with logs/DPIA) | ✅ (on-prem controls, reporting) |
Links & getting started
- OSS repo:
github.com/altcha-org/altcha - Docs & Sentinel trial (30-day):
altcha.org
Bottom line for operators
If you want effective anti-abuse without shipping user data to third parties—and you need EAA/WCAG and GDPR covered—ALTCHA is a pragmatic default. Start with the OSS PoW + server verification; add Sentinel for reputation, rate-limiting and ML filtering when traffic or risk demands it. Keep friction adaptive, visibility high, and your users untracked.
