TILLGATE · TILLSHIELD

Prove there’s a human.
Nothing else.

TillGate issues a signed pass token after the visitor’s browser does a small proof-of-work — a real CPU cost that makes automation expensive, bound to your hostname and gone in seconds. No third-party tracking, no cross-site cookies, no behavioral profiling. Your server verifies the token at /siteverify.

LIVE · issuing passes
proof-of-work · hostname-bound · short-ttl · replay-safe
HOW IT WORKS

A cost on automation. Not a tracker.

Three steps, and we’d rather you know exactly what each one does. TillGate is a proof-of-work challenge with hostname and replay binding — not a behavioral or machine-learning bot detector. It doesn’t fingerprint your visitors or guess how “human” they move.

01 · IN THE BROWSER

A small proof-of-work

The widget asks the browser to find a nonce whose SHA-256 hash has a set number of leading zero bits. For a real visitor that costs a fraction of a second; run at the scale a bot needs, it costs real CPU and real money. The difficulty is yours to tune.

02 · A SIGNED PASS

A token, bound and brief

On success the widget drops a signed pass token into a hidden field named tillgate-response and calls your data-callback. The token is bound to your hostname and carries a short TTL, so a pass minted on your page can’t be lifted and replayed somewhere else.

03 · ON YOUR SERVER

Verify at /siteverify

Your backend POSTs the token plus your secret key to /siteverify and gets back success, the hostname the pass was issued for, and a challenge timestamp. The response is a plain, familiar { success, hostname, challenge_ts, error-codes } shape, so it maps cleanly onto whatever verification code you already have.

THREE MODES

Same core. Different presentation.

Every mode runs the same proof-of-work and issues the same signed pass. What changes is how much the visitor sees. Set it on the site key, or per widget.

managed

The default. The widget usually runs silently and only escalates to a visible, click-to-confirm step when the configured difficulty warrants it. One line to embed, sensible behavior out of the box.

invisible

No visible control at all. The proof-of-work runs in the background and the pass token is produced silently, ready in the tillgate-response field by the time the form submits.

interactive

Always renders an explicit control the visitor clicks to start the check. Use it where you want the human step to be deliberate and obvious — high-value forms, account creation, checkout.

TWO KEYS, ONE PROJECT

One you show. One you keep.

Each project gets a pair of keys, minted in the dashboard under Shield → TillGate. The site key is public and lives in your page markup. The secret key is a server credential and only ever leaves your backend to call /siteverify.

Keep them straight and the split does the work: even with your site key in hand, nobody can forge a verification without the secret.

SITE KEY · PUBLIC
tg_site_…

Embedded in the widget. Safe to ship to the browser — it only identifies which project a pass belongs to.

SECRET KEY · SERVER-SIDE
tg_secret_…

Used only in your /siteverify call. Never put it in client code, a bundle, or a repo.

PRIVACY-FIRST, HONESTLY

No profile of your visitor
leaves the page.

The whole trick is arithmetic: raise the cost of doing a thing a million times, and bind each pass to the one page that issued it. That’s it. There’s no third-party tracking script, no cross-site cookie, and no machine-learning model scoring how “human” a mouse moves.

We’d rather you know the mechanism than trust a black box. It won’t catch a determined, well-funded attacker who’s happy to pay the CPU bill — but it turns cheap, mass automation into something that costs, and it does it without watching anyone.

WHAT IT IS — AND ISN’T
No third-party tracking

The widget talks to your project on tilldev.dev, not to an ad or analytics network.

No cross-site cookies

Nothing follows the visitor from one site to the next. A pass is good for the page it was minted on.

Not an ML bot-detector

It doesn’t fingerprint or profile behavior. It raises a computational cost and binds the result.

A mechanism you can read

Proof-of-work, a signed token, a verify call. Simple enough to reason about end to end.

NOT A SEPARATE PRODUCT

The human check inside TillShield.

TillGate is part of TillShield, in the workspace you already have. On its own it protects any form or route you drop it onto. Paired with the TillShield inline WAF, it becomes the friendly face of an enforcement decision.

WAF · CHALLENGE MODE

A TillShield inline WAF rule in challenge mode can present TillGate instead of returning a bare 429. A request that trips a rate limit or a suspicious-pattern rule gets a chance to prove there’s a human behind it and carry on — the same signal, a softer edge.

DROP IT IN

One script, or one import.

Add the hosted widget with a script tag, or install the package. Either way, the pass token lands in a tillgate-response field and your server verifies it.

HOSTED SCRIPT
html · login.html
<script src="https://tilldev.dev/tillgate.js" async defer></script>

<form method="POST" action="/login">
  <div class="tillgate" data-sitekey="tg_site_…"></div>
  <button type="submit">Sign in</button>
</form>
NPM
ts · gate.ts
// npm i @tilldev/tillgate
import { render } from '@tilldev/tillgate'

render('#gate', {
  sitekey: 'tg_site_…',
  mode: 'managed',                 // managed | invisible | interactive
  callback: (token) => {
    // token is your pass — send it to the server to verify
  },
})
SERVER VERIFY · TILLGATE
bash · verify.sh
POST https://tilldev.dev/api/tillgate/siteverify
Content-Type: application/json

{ "secret": "tg_secret_…", "response": "<token from tillgate-response>" }

→ { "success": true, "hostname": "example.com", "challenge_ts": "…", "error-codes": [] }
PUT A GATE ON IT

A human check that raises the cost of automation without watching the humans. One script, one verify call, and it’s already part of your TillShield workspace.

PART OF TILLDEV

One of four.

You don't have to use the rest. But they fit together — same workspace, same audit log, same shortcut to switch between them. Add what you need when you need it.