Comments: secured by ByteBind

There is a comment box at the bottom of this post. It runs on Isso, which is small, self-hosted, and refreshingly uninterested in becoming a social network.

Isso's admin login uses one password. I didn't want another shared password, and I already had ByteBind sitting here looking for a real job. So I put a small gateway in front of Isso.

Reading and posting comments goes straight through. /comments/admin/ requires a ByteBind lease with the comments:moderate authorization. The gateway knows the Isso password and logs in upstream after the lease is granted. Moderators never see that password.

Keeping Isso boring

I left Isso unmodified. It listens on 127.0.0.1:8080, with no public route to the port. Nginx sends /comments/ to the gateway on another loopback port.

reader or commenter
        |
        v
  public gateway  -------->  Isso on localhost
        |
        +-- admin/moderation --> ByteBind lease required

The gateway checks the admin page and the API calls made by its JavaScript. It also checks Isso's signed approve, delete, and edit URLs. Those links would otherwise let anyone holding one moderate a comment without visiting the admin login.

If the ByteBind Authority is down, existing comments and new submissions still work. Moderation waits until it comes back. For emergencies, I can reach Isso's original login through an SSH tunnel to localhost.

This setup should survive an Isso upgrade without carrying a local authentication patch forever. That was the main reason to use a gateway.

No email, and a groundskeeper

The first version required an email address and offered reply notifications. I removed both before inviting anyone to use it. "Optional" was not good enough; if the blog has no use for an address, the form should not ask for one.

The form now asks for a name and comment. The gateway strips email and notification from direct API submissions as well, and the installer clears those fields from comments already in the database. Isso has no SMTP configuration or notification backend.

New comments stay hidden until approved. I can open the ByteBind-protected admin page, but most moderation now happens in Telegram.

The Telegram bot is called Comment Groundskeeper. It polls Telegram rather than accepting a public webhook, and it talks to Isso over localhost. When a comment enters the queue, the bot sends me its author, text, and article link with two buttons: Approve and Delete. /pending shows anything still waiting.

The bot accepts commands and button presses only from numeric Telegram user IDs in its allowlist. Before acting, it fetches the current queue again and gets a fresh signed moderation key from Isso's admin page. A stale button cannot approve a comment that has already left the queue.

This gives me two moderation paths. ByteBind protects the full web interface from tagged devices on my tailnet. Telegram handles the common case from my phone without exposing another HTTP endpoint on the server. Isso's password stays in a root-owned file and is used only for localhost admin sessions.

Admin means admin

My first ByteBind policy required tag:admin and tag:station. It worked on the MacBook. It also excluded my iPhone because a phone isn't a workstation, which is a perfectly accurate label and an unhelpful moderation rule.

The policy now requires tag:admin. Both devices carry that tag and can open the admin page while connected to Tailscale. The lease lasts three minutes and renews while the page remains open.

ByteBind's job here is limited to the moderation door. Isso still stores comments, renders threads, applies its posting limits, and holds new submissions for approval. For the protocol details, see the original ByteBind post and its technical follow-up.

Now I get to find out whether adding a comment section in 2026 was a good idea.

Comments