skip to content
▓ ONBER.BBS · --:--:--
← all work

Seven tools we operate ourselves

Log parsing and detection engineering · our own product

▶ VISIT LIVE SITE → bokamba.com▶ BOOK A 20-MIN CALL
ROLE
our own product
TOOLS
7
TESTS
2199
HOSTING
self-hosted, tunnel
~/summary.md● READ

# summary

> Seven browser-based tools for log parsing and detection engineering, live at bokamba.com on hardware we own — our own product, not client work, so the operational claims can be checked instead of asserted.

├─ problem · a repository proves someone can write code, not that they can keep something running after the handoff
├─ what we did · seven browser-based tools: a static free tier, a small Hono API for the paid tier, all on hardware we own
└─ result · live at bokamba.com with no cloud hosting bill; 2199 tests, lint clean and blocking in CI
~/problem.md● READ

# the problem

> A repository proves someone can write code. It does not prove they can keep something running after the handoff: reachable, patched, and with the paid tier still working on a Sunday. bokamba.com is the one system where we carry that ourselves, in public.

~/build.md● READ

# what we built

> bokamba.com is a suite of seven tools. LogForge turns raw log lines into parser configuration for Wazuh, Grok, rsyslog, Datadog and Loki among others; LogScrub pseudonymises sensitive fields in a log sample; OS_Regex Lab interprets Wazuh's OS_Regex dialect against test input; RuleForge clusters a mixed log sample and builds a Wazuh rule set that accounts for the noise; SIEM Sizing, IOC Extractor and LogAnvil cover ingest estimates, indicator extraction and synthetic log generation.

> The free tier is static — Astro builds the pages, vanilla TypeScript islands do the work in the browser, and no server is involved at all. The paid tier adds a small Hono API on Node with SQLite and Lemon Squeezy licence validation. All of it runs on a Mac mini we own, under launchd, behind Caddy, with a Cloudflare Tunnel as the only way in. The suite is at 2199 tests and lint blocks CI.

bokamba.com · home: paste your log, review the fields, copy the parser
./shots/home.pngbokamba.com · home: paste your log, review the fields, copy the parser
~/decisions.md● READ

# technical decisions

  • The free tier makes zero server calls.

    Every free tool runs entirely client-side; the server hands over static files and nothing else. That was verified during a security sweep rather than assumed. It exists because of the first objection any security engineer has to a web tool: they are about to paste production log lines into it. If the bytes never leave the machine, that objection is answered by architecture instead of by a privacy page — and the marginal cost of a free user is a file transfer.

    The price is real. No cross-device state, nothing server-side in the free tier, and no visibility into what people actually paste, which is exactly the data that would tell us what to build next. The server exists only for the paid tier, and its runtime dependency list is two packages: hono and zod.

  • Self-hosted behind a tunnel, and the tunnel is shared.

    One cloudflared process on that Mac mini fronts several unrelated sites, so its ingress config is append-only by rule: add a rule for bokamba.com, never reorder or remove one, because a careless edit takes down things that have nothing to do with this product. The services bind loopback only, and that is a checked fact rather than a policy — the same audit found sibling services on the same box bound to 0.0.0.0 and reachable from anything on the LAN, entirely bypassing the tunnel.

    Those siblings have since been moved to 127.0.0.1, so that contrast is history rather than a live gap on the box. The arrangement only works because the product is static-first: the pages are files, so a bad day for the box costs the paid API, not the site. A platform-as-a-service would have sold us autoscaling for traffic we do not have, in exchange for a bill and a second place to debug.

  • The ReDoS was in generation, not in user input.

    A corpus sweep of roughly 30,000 real log lines through the regex generator found a pattern that took 9676ms; after bounding how far optional runs are flattened and reordering the candidate list, the worst case is 15ms. The rule that came out of it is structural rather than a patch: generation-time verification executes only patterns the engine itself produced, and no user-authored regex ever reaches the JS regex engine unescaped.

    OS_Regex Lab, which by definition takes a pattern from the user, runs it through its own interpreter with an explicit step budget instead of handing it to RegExp. Escaping user input before new RegExp is the cheap half of the problem; the expensive half is your own generated patterns, and those are the ones nobody audits.

  • A parse failure that returns nothing is the worst defect this product can have.

    It renders identically to an empty input box, so the user concludes the tool does nothing and leaves, and no bug report is ever filed. LogScrub's failure path returned null and its state had no error field at all. Every failure across the seven tools now states what failed, where in the input, and what to try next. The mechanism that recovers a line number re-runs the same engine call one line at a time, and it introduced two defects of its own.

    It reused the caller's pseudonym dictionary, so a paste that produced no output still persisted pseudonyms to localStorage. And it made 20,002 synchronous calls for a 20,001-line paste. It now probes against a copy under a 1000-line budget and says out loud when the rest was not checked — a worse message than an exact line number, and a much better one than a frozen tab.

~/stack.md● READ

# stack

├─ Astro 4, static output
├─ Vanilla TypeScript islands, no UI framework
├─ Tailwind CSS v4
├─ Hono on Node, SQLite via node:sqlite, Zod
├─ Vitest, ESLint, pnpm
├─ Caddy, Cloudflare Tunnel, launchd
├─ Lemon Squeezy for payments
└─ Umami for analytics, self-hosted
~/outcome.md● READ

# outcome

> Live at bokamba.com — all seven tool pages plus pricing, docs and blog, served from hardware we own, with no cloud hosting bill. The regex generator's worst case is 15ms; that fix is older work, from the corpus sweep that first measured 9676ms.

> In this round of work the test suite went from 2117 to 2199, and lint went from failing and unenforced to clean and blocking in CI. That round is deployed — bokamba.com serves it as of 11 August 2026, so the parse-failure messages described above are live.