Skip to content

Breeze Core v3.0.2

Choose a tag to compare

@github-actions github-actions released this 13 Aug 16:43
· 76 commits to main since this release

Breeze Core 3.0.2 — a reliability release, from the postmortem of a real lockout: several users lost access for days and nothing in the log said why.

Fixed

  • Authentication failures are now logged. There was previously no auth logging at all — only uvicorn's bare 401 Unauthorized access lines. Every failure now records a reason code, the client IP and an 8-character key-id hint (never a secret), and enrolments/revocations are logged too, so "it logged me out yesterday" is answerable:
    journalctl -u breeze-core | grep "auth failed"
    
  • 401s now say why, so clients can tell transient from fatal. A phone whose clock had drifted past the ±60 s signature window produced a 401 indistinguishable from a revoked credential — so the app concluded its credential was dead and deleted its Ed25519 private key, which with LAN-only enrolment strands anyone away from home. Failures now carry a stable error code and a retryable flag: clock_skew, replay, incomplete_signature are retryable; unknown_key, expired, bad_signature, no_credential, bad_api_key are definitive. A clock_skew rejection also returns server_time, so a client can measure its offset and re-sign instead of re-pairing. unknown_key and expired are now distinguished.
  • The shipped fail2ban configs banned legitimate users. The filter counted 400|401|403|404|405|422|429 at 5 hits per 10 minutes, escalating to a five-week ban — but 404 is a client feature-detecting endpoints, 422 is input validation, and 429 is our own rate limiter. The tripwire banned for a week on a single 403. And since clients behind NAT share one address, a ban took everyone on that connection offline at once. Now: 401/403 only, 20 per 10 min, 1 h capped at a day, tripwire needs 3 hits, and ignoreip documents that your WAN address belongs there. See HARDENING §3 — including a new §3.1 on reading the auth log.

Added

  • AC_AUTH_SKEW_SECONDS (default 60) to widen the accepted clock drift for devices with sloppy clocks.

Upgrading is safe from 3.0.1 (the packaging scriptlet fix in that version means dnf/apt upgrade no longer stops the service). 28/28 tests pass.

RISC-V (added after the initial release)

riscv64 now ships as a musl build — breeze-core_3.0.2_riscv64.apk and the matching tarball, also in the Alpine repo on bolero.

It is the first architecture that compiles rather than unpacks: PyPI has no riscv64 wheels, so every dependency is built from source under QEMU emulation — pydantic-core's Rust and PyInstaller's own bootloader included. That build takes hours, needs Alpine edge (rustc >= 1.88, which no stable Alpine ships yet), and is why riscv64 will land last on future releases and may lag the current version.

There is no OpenWrt riscv64 .ipk: that bundle is built on a newer Alpine than OpenWrt 23.05's musl 1.2.4 floor permits. There is no glibc riscv64 build either — see the note on bolero for why.

IT TOOK TWO FUCKING HOURS TO MAKE THAT RISCV BUILD