---
type: explanation
title: Gate a whole site at your reverse proxy
summary: What the Proxy page-gate is, who it is for, and how a visitor solves one game to earn a short-lived pass that clears their requests, so you can protect apps you cannot embed the widget into.
---

The normal way to use Caputchin is to embed the [widget](/docs/site-keys/embedding-the-widget) on a page and verify the token from your backend. That needs a place to put the widget and a backend to check the token. The Proxy page-gate needs neither. It puts a full-page verification in front of a whole site or route at your **reverse proxy**: a visitor solves one game, earns a short-lived pass, and roams the site until the pass expires. The protected app is never touched.

Because nothing is added to the app itself, this is the way to protect hosts you cannot embed a script into, a compiled single-page login portal, an appliance, or an internal tool that sits behind an auth proxy.

<Callout type="info">
The Proxy page-gate is on the Alpha plan and up, enabled per site key. Caputchin hosts the challenge and issues the pass; you point your existing reverse proxy (nginx, Traefik, Caddy, or whatever fronts your app) at it.
</Callout>

## Who it is for

Reach for the gate when the inline widget does not fit:

- **The app has no place for the widget.** A sealed login portal (like Authelia), a vendor appliance, or any UI you cannot edit.
- **You want to gate a whole surface, not one form.** "Prove you are human before you reach this site" rather than a check on a single submit.
- **You have no backend to verify a token.** The proxy does the enforcing; there is no `/siteverify` call to write.

For a normal page or form you control, embed the [widget](/docs/site-keys/embedding-the-widget) instead, it is lighter and does not redirect the visitor. If you have a form but no backend, [hosted verification](/docs/hosted-verification/overview) is the better fit.

## How it works

One solve buys many requests. The visitor plays the game once; after that a first-party cookie clears their requests until it expires.

```mermaid
sequenceDiagram
    participant V as Visitor
    participant P as Your reverse proxy
    participant C as Caputchin
    V->>P: request a gated URL
    P->>C: authz check (forwards the cpt_gate cookie)
    C-->>P: 401, no valid pass yet
    P-->>V: 302 to the hosted challenge
    V->>C: play the game
    C-->>V: pass, auto-POST to your callback
    V->>P: POST the pass to /__cpt/callback
    P-->>V: set cpt_gate cookie, redirect back
    V->>P: request again (cookie present)
    P->>C: authz check
    C-->>P: 204 allow
    P-->>V: your app responds
```

The proxy makes a small **authorizer** call to Caputchin on every request. When the request carries no valid pass, Caputchin answers `401` and the proxy redirects the visitor to the hosted challenge. When the pass is present and valid, Caputchin answers `204` and the proxy passes the request through to your app.

## The clearance cookie

The pass lives in a first-party cookie named `cpt_gate`, set on your own domain by a small callback you host. It is a signed, short-lived token, not tied to a device, so its safety comes entirely from the cookie attributes (`HttpOnly`, `Secure`, `SameSite=Lax`) and a short TTL you choose. Because it sets a cookie on your visitors, disclose it in your cookie policy. The [set-up guide](/docs/proxy-page-gate/set-up) walks through the callback and the required attributes.

## What is intentionally left out

- **No self-hosted gate.** Caputchin hosts the challenge and verifies the pass; you do not run a verifier. Your proxy only forwards a cookie and follows redirects.
- **A per-request check, not local token validation.** The proxy asks Caputchin on each request. The **fail mode** you pick (open or closed) decides what happens if Caputchin is briefly unreachable.
- **Per-site-key, cookie-scoped clearance.** A pass clears one origin, not a whole account or several domains, because it is an ordinary first-party cookie.
- **Not a session or a login.** The gate proves a human reached the site; your app still handles authentication and its own rate limits. The two stack.

## See also

- [Set up the Proxy page-gate](/docs/proxy-page-gate/set-up) — enable it and wire your proxy end to end.
- [Reverse-proxy recipes](/docs/proxy-page-gate/reverse-proxy-recipes) — nginx, Traefik, Caddy, and the Authelia worked example.
- [Proxy page-gate statistics](/docs/proxy-page-gate/statistics) — read the passthrough-to-challenge ratio.
- [Hosted verification](/docs/hosted-verification/overview) — the no-backend option when you do have a form to point at us.
