Deployment
CLAWPTCHA currently runs as a self-deployed Cloudflare Worker in your own
account. Repository policy stays in .github/clawptcha.yml; credentials and
storage stay under the operator’s Cloudflare and GitHub accounts.
Self-deploy when you want to control Cloudflare account, storage, model provider, GitHub App, secrets, and retention posture.
Local setup requires Node.js 22.22.1 or newer and npm.
npx wrangler login && npm run setupThe setup wizard builds and deploys the Worker, provisions D1, creates the GitHub App through the manifest flow, configures Turnstile, generates the session signing key, and writes Worker secrets. Secrets are sent to Wrangler through the secret APIs rather than saved in project files.
Deploy button path
Section titled “Deploy button path”The Cloudflare deploy button can provision the Worker, D1 database, and Workers AI binding from a fork. After that, clone the fork and run the same setup wizard so the GitHub App, Turnstile, and secrets are configured.
npx wrangler login && npm run setupThe wizard’s deploy step is safe to rerun against already-provisioned resources.
Manual setup
Section titled “Manual setup”Manual setup is useful when a wizard phase fails or when an operator wants to control every credential by hand.
-
Deploy the Worker and apply migrations.
Terminal window npm run deploynpm run deploybuilds, deploys the Worker, and applies remote D1 migrations. Usenpm run db:migrate:localonly when preparing local development data fornpm run dev. -
Create a GitHub App.
Configure:
- webhook URL:
https://<your-worker>/webhook; - events: Pull request, Issue comment, Installation;
- permissions: Checks read/write, Pull requests read/write, Contents read-only, Metadata read-only, Members read-only.
Members read is needed only for
github_teamexemptions. Leave team exemptions unset if you do not want team membership lookups. - webhook URL:
-
Convert the GitHub private key to PKCS#8 if needed.
Terminal window openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in app.pem -out app-pkcs8.pem -
Create a Cloudflare Turnstile widget for the Worker domain.
-
Set Worker secrets.
GITHUB_APP_IDGITHUB_PRIVATE_KEYGITHUB_WEBHOOK_SECRETTURNSTILE_SITE_KEYTURNSTILE_SECRET_KEYSESSION_SIGNING_KEYLLM_API_KEYLLM_API_KEYis only needed foranthropicor keyedopenai-compatproviders.
Model providers
Section titled “Model providers”Most self-deploys should start with workers-ai. It uses the Cloudflare AI
binding and does not require an external model API key.
Other options:
anthropic: direct Anthropic API withLLM_API_KEY;openai-compat: any/chat/completionscompatible endpoint withLLM_BASE_URL,LLM_MODEL, and optionalLLM_API_KEY.
Model provider failures should resolve the challenge as neutral rather than blocking the PR.
Flue investigator
Section titled “Flue investigator”The main Worker can investigate normal PRs without Flue. Configure the optional Flue investigator when large PRs are common and you want large evidence bundles handled outside the main Worker.
Deploy the Flue Worker, then configure the main Worker with a service binding:
"services": [ { "binding": "FLUE_INVESTIGATOR", "service": "clawptcha-flue-investigator" }]The Flue Worker is service-binding-only. It disables workers.dev, does not
require a shared secret, and does not support an external URL fallback.
If context.investigator: flue is configured and the service is unavailable,
CLAWPTCHA reports neutral instead of falling back to raw large-diff generation.
Scheduled sweep
Section titled “Scheduled sweep”The Worker includes a cron trigger that runs every 15 minutes. It removes old rate-limit/session rows, neutralizes stale challenge setup, and reconciles terminal challenges whose check-run update failed after the database state was committed.
No separate service is required; deploy registers the trigger from
wrangler.jsonc.