<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Leaf_0223</title>
    <description>The latest articles on Forem by Leaf_0223 (@51511).</description>
    <link>https://forem.com/51511</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3811766%2Fbc3c4166-1381-4cdf-bc34-c0172d876dfe.jpeg</url>
      <title>Forem: Leaf_0223</title>
      <link>https://forem.com/51511</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/51511"/>
    <language>en</language>
    <item>
      <title>I built Anubis-inspired PoW bot protection for static sites — no server needed</title>
      <dc:creator>Leaf_0223</dc:creator>
      <pubDate>Sat, 07 Mar 2026 15:55:10 +0000</pubDate>
      <link>https://forem.com/51511/i-built-anubis-inspired-pow-bot-protection-for-static-sites-no-server-needed-3hi0</link>
      <guid>https://forem.com/51511/i-built-anubis-inspired-pow-bot-protection-for-static-sites-no-server-needed-3hi0</guid>
      <description>&lt;p&gt;Anubis is great. If you haven't heard of it, it's a Proof-of-Work bot protection tool that forces every client — including headless browsers — to solve a CPU challenge before accessing your site. It's been blowing up lately, with major projects like GNOME and FFmpeg adopting it to fight AI scrapers.&lt;/p&gt;

&lt;p&gt;There's just one problem: &lt;strong&gt;Anubis requires a reverse proxy&lt;/strong&gt;. That means if your site is on Cloudflare Pages, Netlify, Vercel, or GitHub Pages, you simply can't use it.&lt;/p&gt;

&lt;p&gt;I ran into this exact problem with my own blog. I wanted PoW protection, but I'm on Cloudflare Pages — no server, no reverse proxy, nothing. So I built &lt;strong&gt;&lt;a href="https://github.com/51511/Albireo" rel="noopener noreferrer"&gt;Albireo&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;Instead of a reverse proxy, Albireo runs entirely on &lt;strong&gt;edge functions&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloudflare Pages&lt;/strong&gt; → Pages Functions (&lt;code&gt;_middleware.ts&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Netlify&lt;/strong&gt; → Netlify Edge Functions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vercel&lt;/strong&gt; → Next.js Middleware (&lt;code&gt;middleware.ts&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When a request comes in, the edge function intercepts it and checks for a valid PoW token in the cookie. If there's no valid token, it serves a challenge page. The client solves the challenge using &lt;strong&gt;Web Workers&lt;/strong&gt; (multi-threaded, so it's faster for real users), then gets a signed HMAC token and is redirected to the original page.&lt;/p&gt;

&lt;p&gt;The whole thing is serverless — no database, no backend, no infrastructure to maintain.&lt;/p&gt;




&lt;h2&gt;
  
  
  What it protects against
&lt;/h2&gt;

&lt;p&gt;To be honest about the limitations (as the README says): Albireo is designed to &lt;strong&gt;deter the vast majority of automated crawlers&lt;/strong&gt;, especially bots scraping static content. It is &lt;strong&gt;not intended to defeat highly resourced or targeted scraping operations&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;What it does stop well:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JS-less bots (they can't solve the challenge at all)&lt;/li&gt;
&lt;li&gt;Headless browsers running at scale (PoW makes mass scraping expensive)&lt;/li&gt;
&lt;li&gt;Basic scrapers that don't handle cookies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SEO bots (Google, Bing, etc.) are whitelisted by default, so your search rankings won't be affected.&lt;/p&gt;




&lt;h2&gt;
  
  
  Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Albireo&lt;/th&gt;
&lt;th&gt;Anubis&lt;/th&gt;
&lt;th&gt;Cloudflare Free&lt;/th&gt;
&lt;th&gt;Cloudflare Pro+&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cost&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Free&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;td&gt;$20–200+/mo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Requires server&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Works on Netlify&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Works on Vercel&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Proof-of-Work&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Slows headless browsers&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open source&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Cloudflare's free Bot Fight Mode relies on User-Agent and IP heuristics — easy to bypass. Albireo forces real computation regardless of how sophisticated the bot is.&lt;/p&gt;




&lt;h2&gt;
  
  
  Setup (Cloudflare Pages — 3 steps)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Copy the &lt;code&gt;functions&lt;/code&gt; folder to your project root&lt;/li&gt;
&lt;li&gt;Change &lt;code&gt;SECRET_KEY&lt;/code&gt; in &lt;code&gt;_middleware.ts&lt;/code&gt; to a random string&lt;/li&gt;
&lt;li&gt;Push and deploy&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it. If you don't have mascot images, it automatically falls back to emoji indicators (😐 / 😊 / ❌), so it works out of the box with zero assets.&lt;/p&gt;

&lt;p&gt;Netlify and Vercel setups are equally simple — check the README for details.&lt;/p&gt;




&lt;h2&gt;
  
  
  Live demo
&lt;/h2&gt;

&lt;p&gt;My blog is running Albireo right now: &lt;a href="https://www.leaftechblog.cloudns.biz/" rel="noopener noreferrer"&gt;leaftechblog.cloudns.biz&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First visit will show you the challenge page. Subsequent visits within the TTL window skip the challenge automatically.&lt;/p&gt;




&lt;p&gt;GitHub: &lt;a href="https://github.com/51511/Albireo" rel="noopener noreferrer"&gt;github.com/51511/Albireo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feedback welcome — especially if you run into issues on Netlify or Vercel, those are harder for me to test than Cloudflare Pages.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
