Skip to content

Readable logs, public health page and an admin page behind Cloudflare Access - #18

Merged
BaranDev merged 3 commits into
mainfrom
readable-logs
Oct 21, 2026
Merged

BaranDev merged 3 commits into
mainfrom
readable-logs

Conversation

@BaranDev

Copy link
Copy Markdown
Owner

What

  • Readable logs: one plain line per request and per background event (queue decisions, GitHub fetches with quota and refill time, retries, pauses, cache sweeps, start, and a status line every 15 minutes). Each request line says whether the card came from the memory cache, the disk cache or was drawn, and how long drawing took. Client IPs are never written. Lines are cleaned of control characters and capped at 600 characters. Docker logs are capped at 5 x 20 MB.
  • Public health: /status page (linked as "Health" in the footer) and a trimmed /health: up or not, whether GitHub fetching runs, whether new users get in, with times in minutes and UTC. No counts or capacities.
  • Admin: /admin/status and /admin/health with every count and capacity, the last hour of traffic by minute, users, held logins, memory, disk cache and the latest 400 log lines (filter and search). Cloudflare Access guards them at the edge, and the server verifies the Access token (RS256 signature against Access's keys, audience, issuer, expiry, allowed emails) on every request. Set ACCESS_TEAM_DOMAIN, ACCESS_AUD and ADMIN_EMAILS; without them only a local run opens them.

Checks

  • cargo test --release --locked: 137 passed.
  • A security review probed header spoofing, the local-run exception, path tricks, the static route, JWT algorithm and claim checks, log injection, oversized lines and caching. Its medium and low findings are fixed in the last commit.

BaranDev added 3 commits October 20, 2026 17:42
- One plain line per request: what was asked, the answer, whether it came from the
  memory cache, the disk cache or was drawn (with draw time), size, country, kind of
  client and Cloudflare ray id. Client IPs are never written.
- Lines for queue decisions, GitHub fetches (with quota and refill time), retries,
  pauses, cache sweeps, the start, and a status line every 15 minutes.
- /health and the new /status page show only public state: up, whether GitHub
  fetching runs, whether new users get in, with times in minutes and UTC.
- /admin/health and /admin/status show every count and capacity, answer only on
  questlog.cc (or locally) and are never cached; they go behind Cloudflare Access.
- Health link in the footer; Docker log size capped at 5 x 20 MB.
…e log

- /admin/status and /admin/health need a valid Cloudflare Access login on every
  request: the token's signature (Access's published keys), audience, issuer,
  expiry and email are checked by the server, set by ACCESS_TEAM_DOMAIN,
  ACCESS_AUD and ADMIN_EMAILS. Only a local run opens them without it. Every
  refusal is logged with its reason; the page shell is no longer under /static.
- The admin page adds the last hour of traffic by minute (cache, drawn, busy,
  errors, other), users saved, asked for and unknown, logins held after failed
  fetches, container memory, disk cache size, and the latest 400 log lines with
  a filter for warnings and errors and a search.
- Every log line is one plain line: control characters and bidi overrides become
  ?, and a message is cut at 600 characters, so a crafted token or user agent can't
  forge lines, send terminal escapes or bloat memory and the admin page. A failed
  log write no longer panics.
- The admin check refuses tokens with another algorithm before any key lookup,
  fetches Access's keys at most once per minute even under a burst, and logs only a
  cut, quoted key id. Refused admin requests are never cached.
- Public /health gives the next opening only when the hourly cap is the reason, in
  whole minutes, and the GitHub pause in whole minutes.
@BaranDev
BaranDev merged commit 2220d0e into main Oct 21, 2026
2 checks passed
@BaranDev
BaranDev deleted the readable-logs branch October 21, 2026 11:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant