Web protection

Security headers, forgery checks, rate limits and bot challenges on every app.

Built on Caddy and Altcha

Plans: Every plan, including the free app

What you get

  • Standard security headers on every response
  • Form posts from other websites refused
  • Rate limits per visitor and per app
  • A bot challenge for public forms, with no third party
  • Your own headers, such as a Content-Security-Policy
  • A clear error when a limit is reached

How it works

Every request passes through Caddy, the open-source web server, before it reaches the app. Caddy adds security headers such as HSTS, which keeps browsers on HTTPS, and refuses a form posted to the app from another website. A visitor who sends too many requests is told to wait and try again.

A public form, such as a quote request, can require a bot challenge. Whisk uses Altcha, an open-source proof-of-work check: the visitor's browser works through a small calculation in the background, with no picture puzzles and no third-party service. Each solution is accepted once.

The protection is in place before the app's first line of code. An app can add or override headers in its whisk.yaml, for example a Content-Security-Policy. Pages anyone may open are listed as public pages, and everything else needs a signed-in person.

Example

An electrical contractor puts a callout request form on its website. Spam bots that filled in the old form now fail the challenge. Real customers complete a quick check and send the form as before.

For your coding agent

routes:
  public: ["/", "/callout", "/health"]
  challenge: ["/callout"]
  headers:
    Content-Security-Policy: "frame-ancestors 'self'"

A POST to /callout without a solved challenge gets CHALLENGE_REQUIRED, which carries a new challenge for the Altcha widget. Every option is in the whisk.yaml reference.

All features