the avatar image of Benjamin Bouvier

Fixing Sveltia CMS auth on Forgejo + Anubis


This article is part of a series: le blog. Other articles in the series include:

  1. A new blog theme!
  2. Publish a Zola blog with Gitlab CI, real fast
  3. I've switched blog engines and now every post has 100 million valid URLs
  4. Tiny new blog features
  5. Piggybacking on Mastodon, email newsletters edition
  6. Fixing Sveltia CMS auth on Forgejo + Anubis (👈 you are here)

I’ve managed to set up the Sveltia CMS for my blog, which makes it possible to have a nice UI to write new posts (including this one!), and I ran into a few issues in the process, so might as well document them!

Sveltia CMS is a pure JavaScript CMS frontend for a blog statically generated with something like Zola or Pelican. What’s particularly nice is that you don’t need any server-side component to set up; it’s a static page you can serve from the same domain as your blog, and do so safely as its public configuration doesn’t embed any secret that would put you in danger.

Sveltia can interact with multiple repository backends, like Github of course, but also self-hosted options like Gitlab or Forgejo. I’m hosting the latter, so I wanted to use it as the backend. It’s nicely documented on Sveltia’s online help, and I’ve chosen to go down the OAuth path.

The Forgejo instance is reverse-proxied by an Anubis instance, a system that allows to avoid super heavyweight scraping by the GAFAM, which comes with a high cost for the bandwidth and the CPU usage on my server. Anubis will use heuristics based on the host, path and headers to decide whether to block a request or not. This is all super configurable, and quite effective: in the past, it achieved blocking all the requests from (AI) scraping bots on our instance of Forgejo (while in the worst case, I could see peaks for up to 10 GB of traffick per day coming from these AI bots).

That being said, in my little Sveltia setup, Anubis did prevent authentication from finishing:

Unfortunately, opening the browser’s developer console to look at JavaScript errors or the network requests didn’t help that much. After ahem way too much time exploring different possible causes for the error, it appeared that it was Anubis sending a challenge response during the authentication flow.

The solution consisted in adding a special rule for Anubis to allow queries on those paths for the specific Forgejo host; I’ve added it to the ./apps/allow-api-routes.yaml file, but you can certainly put it elsewhere in your configuration:

- name: allow-forgejo-api-routes
  action: ALLOW
  expression:
    all:
      - host == "forgejo.example.com"
      - path.startsWith("/api") || path.startsWith("/login")

Then import this rule from the main policy file:

bots:
  - import: /data/apps/allow-api-routes.yaml

[...other rules...]

A note: /data means searching in the directory at /data, while (data) means using preregistered rules embedded in the binary. It only took me half an hour to figure out why my configuration was not loaded correctly, so here you go 😁️



Comments

If this article inspires you, feel free to send me an email in response.