Introduction

What Bollwark is, how the proof-of-work challenge works, and why it sets no cookies.

Bollwark is a bot-protection service that replaces the "click the traffic lights" CAPTCHA with a memory-hard proof-of-work puzzle. The visitor's browser spends a fraction of a second on an Argon2id computation; a script farm spends that same fraction of a second on every request it makes.

Nothing is asked of the person. No images to squint at, no audio fallback to fail, no cookie.

How a submission flows

Two scoring passes bracket every solve.

  1. Puzzle time — GET /v1/puzzle scores the request on what is knowable before any work happens: address reputation, request rate, geography, TLS fingerprint. That picks an escalation tier, and the visitor gets a puzzle at tier-adjusted difficulty — or, at the top tier, a 429 and no puzzle at all.
  2. Verify time — your backend posts the widget's opaque token to POST /v1/verify. The service re-scores on submit-only signals (the honeypot, behavioural counters, dwell time) and answers pass, shadow-fail or block.

Your form handler only ever reads success. The band behind that decision is available as risk when you want to step up rather than refuse — see Verifying on your backend.

No cookies, by design

The service never sets or reads a cookie, and the widget writes nothing to localStorage. That's why embedding Bollwark adds no consent banner to your site, and why there's no session affinity to configure at your proxy.

The trade is that everything the scorer knows, it knows from the request in front of it. There's no cross-visit identity to lean on.

Hosted or self-hosted

The service is MIT-licensed and designed to run as a single-tenant appliance — one operator, one admin token. Self-hosting is a first-class path, not a limited edition.

The hosted service at api.bollwark.eu runs the same unmodified binary. What you get on top is the account layer: orgs, per-site ownership, longer analytics retention and billing.