BackendSide MailPanel
Changelog
Full release history and version notes for BackendSide MailPanel – a self-hosted, API-first mail server control panel for Linux.
Build numbers are continuous across all packages; the version stays at 0.1.0 until the first tagged release. Format follows Keep a Changelog.
Build 056
Latest
2026-05-28
API convergence with the BackendSide DNS panel — the two products' HTTP surfaces now share a common shape so a single integration or central orchestration panel can drive both with one client.
Added
- Managed API tokens.
GET / POST / DELETE /api/v1/admin/tokens mint named, individually revocable tokens with a last-used timestamp. The plaintext is shown exactly once on creation; only a SHA-256 hash is kept on disk. The legacy static API_KEY from config.env still works as a fallback for bootstrap and recovery.
- Per-IP rate limiting. Token-bucket limits on
/auth/login (default 5 / min) and /api/v1/* (default 60 / min). Hitting a limit returns 429 with a Retry-After: 60 header. Tunable via GET / PUT /api/v1/security/settings.
- Two-list IP allowlist.
admin_login_whitelist gates panel sign-in; api_key_whitelist gates X-API-Key automation (browser JWT sessions bypass). Empty list means no restriction. Both managed via /api/v1/security/settings.
- File-based audit log at
/etc/backendside-mailpanel/audit.log, served via GET /api/v1/admin/audit-log. Append-only, JSON-per-line; records every mutating admin action with who-did-what-when.
- Outbound webhooks. Register receivers via
/api/v1/admin/webhooks with an optional shared secret; the panel fires a signed POST (X-BackendSide-Signature: sha256=… HMAC) on domain, mailbox, and alias create/delete events.
Changed
- Response envelope unified. List endpoints now return
{"data": […], "meta": {"page", "limit", "total"}} with ?page=N&limit=N query params; single-resource GETs return the bare object; mutations return {"message": "…"}. The internal admin UI keeps working unchanged through a thin shim that aliases the canonical shape to the legacy entity-named keys.
- Error envelope flattened. Errors now use a single flat shape:
{"error": "…", "detail": "…", "code": "…"} with SCREAMING_SNAKE codes (VALIDATION_FAILED, MAILBOX_NOT_FOUND, RATE_LIMITED, …). The previous nested {"error":{code,message,hint}} shape and lowercase codes are gone.
- Config file path renamed from
/etc/backendside-mailpanel/.env to /etc/backendside-mailpanel/config.env — matches the cluster-wide /etc/backendside-<product>/config.env convention shared with the DNS panel. The systemd unit, postinst (DEB and RPM), and certbot renewal hook all read the new path. Upgrades migrate the file in place.
- Security tab in the dashboard now reads the admin allowlist from
/api/v1/security/settings instead of the removed legacy IP-list endpoint — one settings store for the new two-list model.
Removed
- Legacy admin-IP middleware and its separate
admin_allowed_ips.txt storage — replaced by the two-list model under /api/v1/security/settings.
- The DB-backed
audit_logs table. The file-based audit log is now the single source of truth.
- Nested error envelope and its lowercase /
snake_case codes.
- Entity-named list wrappers (
{"domains": […]}, {"mailboxes": […]}, …) at the HTTP boundary.
Upgrade note
- External scripts that read
response.domains, response.mailboxes, etc. from list endpoints need a one-line tweak to read response.data instead. Single-resource GETs are now bare objects without a wrapper.
- Branch on the new
code field for programmatic error handling — the codes are stable across builds and shared with the DNS panel where they overlap.
Build 054
2026-05-26
Added
- Site-wide page footer on all five UI pages (dashboard, login, setup wizard, domain detail, mailbox detail). Fixed to the bottom of the viewport, semi-transparent dark bar reading "© 2026 BackendSide. All rights reserved." with a link to backendside.com in brand orange. Scrollable content areas gained an extra 24 px of bottom padding so the footer never overlaps the last row/button.
Changed
- About modal copyright refreshed from "© 2025" to "© 2026 BackendSide. All rights reserved." for consistency with the new page footer.
Build 053
2026-05-26
Fixed
- Panel UI no longer makes external requests for fonts. The Inter web font is now self-hosted at
/ui/fonts/InterVariable.woff2 (variable font, weights 100–900 in a single 344 KB file). Previous builds linked to Google Fonts via fonts.googleapis.com, which was blocked by the Build 045 CSP and silently fell back to system fonts.
Security
- Removes the last cross-origin asset reference from the admin UI — all static assets ship inside the binary.
Build 052
2026-05-26
Changed
- Brand logo across the UI. Every page that previously showed text now uses the official rectangle logo (with rounded corners, white background for contrast against the dark sidebar). The square logo serves as the browser favicon and the badge in the About modal. Affected pages: dashboard, login, setup wizard landing, domain detail, mailbox detail.
- Two PNG assets embedded into the binary at
/ui/img/backendside-emailserver-rectangle-logo.png and /ui/img/backendside-email-server-logo.png. Total package size grew by ~1 MB.
Build 051
2026-05-26
Fixed
- postgrey now stays enabled across reboot on RHEL family. Reconciler runs
systemctl enable postgrey before reload-or-restart when greylisting is enabled. Debian/Ubuntu was already correct.
Known limitation
- Greylisting is not available on AlmaLinux 10 / Rocky 10 / RHEL 10. EPEL 10 does not currently ship the
postgrey package. Setup wizard logs a non-fatal warning and the reconciler's capability gate correctly skips Postfix wiring; toggling greylist on in the UI has no effect on these distros. DNSBL is unaffected. Workaround documented in USERGUIDE §20.
Build 050
2026-05-26
Added — Phase 8: Greylisting + DNSBL
- DNSBL rejection wired into Postfix
smtpd_recipient_restrictions. Configurable zones (default zen.spamhaus.org) emit one reject_rbl_client <zone> each, placed after the destination guard so outbound mail and authenticated submissions are unaffected.
- Greylisting via
postgrey on 127.0.0.1:10023. Capability-gated on the postgrey binary. Configurable initial delay (default 300 s) and auto-whitelist max age (default 35 d). Auto-whitelist after 5 successes.
- Anti-spam whitelist — new
spam_whitelist table with entry types ip / cidr / domain / email. Reconciler rewrites /etc/postgrey/whitelist_clients.local and /etc/postgrey/whitelist_recipients on every reconcile.
- Anti-Spam dashboard tab with three cards: DNSBL config, greylist config, and the whitelist table (add / delete inline).
- New endpoints:
GET/PUT /api/v1/config/antispam, GET/POST /api/v1/antispam/whitelist, DELETE /api/v1/antispam/whitelist/:id.
- Setup wizard installs
postgrey on Debian/Ubuntu and on RHEL-family (via EPEL).
Build 049
2026-05-11
Fixed
- ClamAV content filter wiring is now live. The reconciler now checks for the
clamsmtpd daemon binary instead of the clamsmtp package name, so the content_filter actually gets wired into Postfix when the package is installed.
Build 048
2026-05-11
Added
- RHEL / AlmaLinux / Rocky / CentOS / Fedora support in the setup wizard. Installer detects OS family from
/etc/os-release and uses dnf on RHEL-family systems. Runs postgresql-setup --initdb on RHEL, rewrites pg_hba.conf so postgres keeps peer auth while the panel role uses md5 over loopback.
Fixed
- Prior
.rpm packages installed cleanly on AlmaLinux but the setup wizard immediately failed with exec: apt-get: not found.
Build 047
2026-05-11
Packaging & Fixed
LICENSE and scripts/logrotate.conf now ship inside both .deb and .rpm.
- Mailbox creation now strips the
@domain suffix from the username before storing (was previously stored verbatim, breaking lookups).
- Aliases get a
domain_id foreign key with ON DELETE CASCADE — deleting a domain no longer leaves orphaned alias rows.
Build 046
2026-05-10
Added
- Confirmation dialogs and loading indicators across destructive actions in the dashboard (delete domain / mailbox / alias, flush queue, etc.).
- Audit log UI subtab — admins can now see who did what, when.
- Backup / restore endpoints for the panel's own configuration and DB.
- Deep
/health probe — checks DB, Postfix, Dovecot and disk space, not just process liveness.
- Structured JSON logging via
LOG_FORMAT=json (slog).
- spampd milter wiring (remote SpamAssassin scoring) and ClamAV / clamsmtp content_filter wiring (later corrected in Build 049).
Build 045
2026-05-10
Security
- JWT secret fail-closed. Panel refuses to start if
JWT_SECRET is missing rather than silently generating a weak default.
- Hostname validation on certificate and DKIM paths (rejects
.., slashes, shell metacharacters).
- Security response headers (HSTS, X-Content-Type-Options, X-Frame-Options, Referrer-Policy) added to all admin routes.
- Admin IP allowlist warning + UI banner when the allowlist is empty.
- DSN scrubbing in error responses — DB connection strings no longer leak in 500s.
Changed
- Atomic config writes — Postfix and Dovecot config files are written to a temp file, validated with
postfix check / doveconf -n, then renamed. A broken render no longer leaves a half-written file in place.
- Policyd context cancellation — clean shutdown when the panel restarts.
Added
- Test suite covering ~60% of
internal/ packages.
- Audit log middleware records all mutating admin actions.
Build 044
2026-05-09
Changed
- Brand display rename: MailPanel → BackendSide MailPanel (UI labels, About modal, log lines, packaged metadata). Service name, binary name, and filesystem paths were renamed in Build 034.
Build 043
2026-04-30
Added
- About modal — circular
? button in the header opens a dialog showing app version, build number, OS pretty name, Postfix version, Dovecot version, hostname, and copyright link to backendside.com.
Build 042
2026-04-30
Changed
- Webmail tab redesigned as a structured form (was raw YAML textarea). Listen port, cookie-secure toggle, session secret + Regenerate button, allow-custom-server, allow-insecure-plaintext, and an inline-editable mail server table with Add / Delete rows.
- New
POST /api/v1/webmail/regen-session-key endpoint.
Build 040
2026-04-30
Added
- Security tab in the dashboard: change admin password (rewrites
.env, hot-reloads); Admin IP restriction list (allowlist of IPs / CIDRs, blocks any other IP with 403 globally); per-port firewall via the BSMP_FW iptables chain — Allow / Block / Restrict (per-IP) for each managed port. Re-applied automatically on panel restart if firewall.json exists.
Build 039
2026-04-30
Added
- Webmail companion panel. If BackendSide WebMail is installed, a 📧 Webmail nav item appears with service controls (start / stop / restart), a config editor, and a log viewer.
- Admin UI rethemed to the BackendSide design system.
Build 038
2026-04-30
Fixed
- Sent counter stays correct for local-to-local mail. Detection switched from
postfix/smtp[ (only fires for external relay) to postfix/submission/smtpd[ + sasl_method= — fires once per authenticated send, local or external.
Build 037
2026-04-30
Fixed
- Dashboard mail stats no longer return zero on Ubuntu 24.04.
journalctl -u postfix doesn't work without rsyslog; switched to journalctl "SYSLOG_FACILITY=2".
- Timestamp parse now uses
2006-01-02T15:04:05-07:00 (colon in timezone offset).
Build 036
2026-04-30
Added
- Mail stats cards on the dashboard — Sent (1h), Sent (24h), Received (1h), Received (24h), auto-refresh every 10 seconds.
Build 034
2026-04-30
Changed
- Product rename:
mailpanel → backendside-mailpanel. Affects binary name (/usr/bin/backendside-mailpanel), systemd unit, .deb and .rpm package names, all /etc/mailpanel/ paths, and all UI strings.
Build 033
2026-04-30
Added
- Auto-create
Sent / Drafts / Trash / Junk folders. Added special_use + auto = subscribe Dovecot namespace blocks so IMAP clients see these folders on first login.
Build 030
2026-04-30
Added
- Dedicated Logs tab in the dashboard (between Mail Queue and Sessions). Postfix / Dovecot selector, 50 / 150 / 500 / 1000 line picker, keyword filter, 10-second auto-refresh, color-coded lines (errors red, warnings orange, delivered/connect green).
Build 029
2026-04-30
Added — Phase 5: DKIM / SPF / DMARC milter wiring
- OpenDKIM in
sv mode (sign outbound + verify inbound). KeyTable + SigningTable + TrustedHosts auto-generated.
- OpenDMARC in observe mode (RejectFailures=false, no DB).
postfix-policyd-spf-python wired as a recipient restriction.
- All three are capability-gated — reconcile is safe on systems without the optional packages.
Build 028
2026-04-30
Added — Phase 4: Policy daemon
- Policy daemon on
127.0.0.1:10031. Enforces per-mailbox: SMTP enabled / disabled flag, require TLS, message size limit, recipients per message, daily send count (resets midnight UTC).
- Only enforces on authenticated (outbound) submissions; unauthenticated traffic returns
DUNNO.
- New endpoints:
GET /api/v1/policyd/status, POST /api/v1/policyd/reset/:id.
Build 027
2026-04-30
Added
- Queue tab — per-message table backed by
postqueue -j. Delete a single message, Flush All refreshes the table.
Build 026
2026-04-30
Added
- DKIM tab live. Lists all
/etc/opendkim/keys/* .txt files with a Copy DNS Record button; auto-refreshes after generate. New endpoint GET /api/v1/dkim/list.
Build 024
2026-04-30
Added
- Per-mailbox detail page (
/mailbox.html) with Overview / Settings / Limits tabs.
PATCH /api/v1/mailboxes/:id/password — bcrypt password reset (Dovecot {BLF-CRYPT} prefix).
Build 023
2026-04-29
Added — Phase 3: TLS
- Self-signed day-0 certificate so port 8080 / 587 / 993 work immediately.
- Let's Encrypt integration via certbot wrapper.
certificates DB table and full Certificates UI (upload / issue / renew).
- Automatic Postfix / Dovecot wiring when a cert exists on disk.
Build 022
2026-04-29
Added — Phase 1 + 2
- Three-tier configuration schema (server defaults / domain overrides / mailbox overrides).
- SMTP / IMAP auth via Dovecot SQL.
Builds 016–021
2026-04-25 → 2026-04-29
Added
- Domain detail page with tabbed interface (Build 020).
- Sidebar in domain page; mailboxes / aliases removed from top nav (Build 021).
Changed & Fixed
- Admin credentials moved from DB to
/etc/backendside-mailpanel/.env (Build 019).
- Setup-complete redirect (
/ → /login) (Build 018).
- Login / dashboard redirect loop (Build 017).
- Schema init race: explicit
public schema, DB setup retry, TryConnect backoff (Build 016).
Build 001
2026-04-24
Added
- Initial release.
- Option 3 authentication: admin login page (
/login), JWT tokens for browser sessions, X-API-Key header for programmatic integrations.
- Domains / mailboxes / aliases CRUD via REST API.
- Setup wizard for first-time installation (installs Postfix, Dovecot, PostgreSQL; creates DB and schema; vmail user and
/var/mail/vhosts).
- Modern dark-theme dashboard.