HLCaptcha is a project designed to integrate a CAPTCHA-like labeling system into your site for your need this clearly inspired by reCAPTCHA. This project come from the need of data with annotation inside the ministary. Users complete annotation tasks via Label Studio, displayed in a pop-up. This system is designed to be user-friendly to install see getting started, for developers see the Technical Design System. The sytem aggregates annotations to compute ground truth values based on ODD consensus base on crowdfunding.
In this video, you can see the CAPTCHA tool in action. The video shows two scenarios:
- First case – Correct answer:
The user solves the Known CAPTCHA correctly → We present an Unknown Task for annotation. - Second case – Incorrect answer:
The user fails the Known CAPTCHA → We loop back and present a new Known CAPTCHA before proceeding to annotation.
For more information, see the activity diagram here.
demo.mp4
- Seamless pop-up UI using React & shadcn/ui
- Label Studio integration for rich annotation interfaces
- Consensus-based ground truth via ODD and overlap algorithms
- Redis-powered task distribution for low-latency assignment
- Modular microservices: frontend, MITM, jobs, consensus engine, Label Studio
- Kubernetes-ready with Helm charts and distroless Docker images
- Extensible & open source stack: Node TS, Express, Python, pnpm, Docker
To use the captcha you need to setup the service, then install the npm package @captcha/captcha in your project.
To Deploy this system there are 2 approaches:
- Docker Compose, for local development
- Kubernetes, for production
All the custom images are using distroless images to reduce size and increase security.
This approach is recommended for local development and testing, or even for small production deployments. The env are stored in a .env file, you can use the .env.example file as a template, all env variable are required unless specified otherwise.
you will need the following tools installed on your machine:
- Node.js ≥ v23.11.x & pnpm
- Python ≥ 3.13.x & pipenv & Pipfile
- Docker & Docker Compose
basic simple launch:
docker compose upIf you want to dev on specific service, you will need to comment the services in the compose.yml file. and run it with separately (don't forget to source the source .env file before running the service).
git clone https://github.com/GuillaumeDorschner/captcha.git
cd captcha
cp .env.example .env # modify the env file with your config
docker compose up --buildUse Kubernetes for scalable, secure production deployments. All services are packaged in a Helm chart (deployments/helm/captcha) and rely on a dedicated namespace, ConfigMaps, and Secrets for configuration. Environment variables live in Kubernetes Secrets; use .env.example as your local template, then inject values via kubectl create secret.
- kubectl (v1.24+)
- Helm (v3.8+)
- A running cluster (e.g. managed GKE/EKS/AKS, or local with Minikube / kind)
- Docker for building and pushing images
- (Optional) cert-manager for TLS certificates
- (Optional) Ingress controller (NGINX, Traefik, etc.)
The process is trivial you will deploy a helm chart with the following command:
helm install captcha ./deployments/helm/captcha \
--namespace captcha-system
# verify the installation
kubectl get pods -n captcha-system:::info For a production deployment, you should use argoCD to follow the GitOps approach. Check the argoCD documentation for more information. :::
The captcha composnent is a React component that can be used in your project. But don't forget to set env so the captcha can communicate with the services.
You will need to install the npm package @captcha/captcha in your project.
npm install @captcha/captchaSamll example of usage:
import { Captcha } from '@captcha/captcha';
export default function MyPage() {
return <Captcha title="Verify you’re human" description="Complete this quick task to proceed" />;
}For more information see the frontend README & the code here.
For the captha and service to work you need to set the domain in the env file. The domain should be the same as the one used in the frontend. You can use a local domain like captcha.local or a public domain like yourdomain.com. For local development you can modify the /etc/hosts file to point the domain like this:
<ip cluster/nginx> yourdomain.com
<ip cluster/nginx> engine.example.com
<ip cluster/nginx> labelstudio.example.com
127.0.0.1 localhost
255.255.255.255 broadcasthost
::1 localhost
Note
if you have any problems i refer you to the doc It's also recommended to use separate buckets for each project to avoid data conflicts.
-
create 1 or more projects in Label Studio so the jobs will pick the project
- if the data will be store via minio
- create a host in minio in the
/etc/hostsfile:127.0.0.1 minio
-
create a bucket in minio in public
-
create an access key
-
connect the bucket to Label Studio
-
sync ls to minio
-
Run Jobs to sync mongo & redis
-
Open the frontend to test the captcha
Open http://yourdomain.com/page-captcha with your browser to see the result.
If you want to develop on the project, the services you dev need to be commented in the docker-compose.yml file.
docker compose up --buildinstall the dependencies:
pnpm install
# or
pip install -r requirements.txtThen you can run the service you want to dev on. For example, to run the frontend:
source .env # load the env file
pnpm run dev --filter frontend- Technical Design System
- Troubleshooting Guide
- Frontend README
- MITM README
- Jobs README
- Consensus Engine README
- Jupyter README
- Label Studio README
- Deployments README
- Shared README
- Jupyter Notebook
The Makefile provides two practical options for streamlined development across all services:
- test: Run tests for all services to ensure functionality and stability.
- build: Build all services for quick development and deployment.
These commands are designed to simplify and accelerate your development workflow.
HLCaptcha: Human Labor Captcha Annotate to prove you exist. Descartes approved.
See the troubleshooting section for common issues and solutions.
We welcome your contributions!
- Fork the repo
- Create a feature branch (
git checkout -b feat/your-feature) - Commit with clear messages (
git commit -m "feat: add X") - Push and open a Pull Request
Please follow our Code of Conduct and link relevant ADRs in your PR.
As usual ! Then wait for the review of your PR, and we will merge it if everything is good.
This project is licensed under the MIT License. See the LICENSE file for details.
Guillaume Dorschner guillaume.dorschner@gmail.com

