This release includes 7 security fixes for security teams reviewing exposed deployments.
Topics
+12 more
Affected surfaces
Summary
AI summaryUpdates usulnet v26.2.4 — 2026-02-21, SOC2/ISO27001/CIS, and eBPF-based across a mixed release.
Full changelog
usulnet v26.2.4 — 2026-02-21
Added
-
Redis TLS Encryption by Default: All Redis connections now use TLS with ECDSA P-256 self-signed certificates. The Redis container generates certificates at startup (or uses custom certs mounted at
/certs-src/). Connection URL scheme changed fromredis://torediss://. New PKI methodEnsureRedisServerCert()generates and signs Redis server certificates via the internal CA. Full mTLS support available viatls_cert_fileandtls_key_fileconfig options. -
Container Registry Browser: Full UI for browsing private and public container registries. List repositories, explore tags with digest, platform, and size details, and inspect image manifests (config, layers, OS/architecture). Supports Docker Hub, GitHub Container Registry, and any OCI-compliant private registry. New
RegistryServicewith authentication caching,GET /registries/{id}/browse,/{id}/tags/{repo}, and/{id}/manifest/{repo}/{ref}routes. Three new template pages: browse, tags, manifest. -
Drift Detection: Automatically detects configuration drift between the desired and actual state of running containers. Compares expected image tag, environment variables, volume mounts, port bindings, and resource limits against what is actually running. Results presented in a dedicated Drift page with per-container diff view. Backed by
DriftService, migration040_drift_detection, andDriftDetection/DriftDiffmodels. -
Change Events Feed: Chronological audit trail of infrastructure changes — container start/stop/restart, image pulls, stack deploys, configuration edits, and user actions — displayed in a filterable timeline. Backed by
ChangesService, migration039_change_events, andChangeEvent/ChangeEventStatsmodels. Accessible at/changes. -
Resource Cost Optimization: Analyzes container CPU and memory usage patterns and surfaces rightsizing recommendations (over-provisioned and under-provisioned containers). Calculates estimated cost impact based on resource waste. New
CostOptService, migration041_resource_optimization,ResourceRecommendation/ResourceUsageSamplemodels, and/costoptpage. -
Session Recording & Replay: Terminal sessions (SSH, host exec, container exec) can now be recorded and replayed in-browser with full timing accuracy. Recordings are stored server-side. New
RecordingService, migration042_session_recording, session replay routes at/session-replay/{id}and/session-replay/{id}/data. -
Calendar: Integrated operations calendar for scheduling maintenance windows, tracking SLA deadlines, and coordinating team tasks. Supports events, tasks with checklists, and notes. New
CalendarService, migration044_calendar,CalendarEvent/CalendarTaskmodels, and a full calendar grid UI at/calendar. -
Scheduled Jobs Management UI: Visual management page for all recurring background jobs (backup, retention, metrics collection, security scans, drift checks, SLA evaluation). View status, next run time, last result, and manually trigger jobs. Accessible at
/jobs/scheduled. -
Developer Tools Suite: 15 built-in browser-based developer utilities, accessible at
/toolsand individually:- Encoders: Base64 encode/decode, URL encode/decode, HTML entities, hex
- Formatters: JSON pretty-print/minify, YAML↔JSON conversion
- Generators: UUID v4/v7, random strings, secure passwords, Lorem Ipsum
- Hash: MD5, SHA-1, SHA-256, SHA-512, bcrypt calculator
- Network: CIDR/subnet calculator, IP geolocation lookup, DNS resolver
- Regex: Live regex tester with match highlighting and group extraction
- Text Diff: Side-by-side and unified diff viewer for text comparison
- JWT: JWT decoder with header/payload/claims display and expiry validation
- Crypto: RSA/ECDSA key pair generation, certificate info viewer
- Token: API key generator, TOTP secret generator
- All tools run client-side with no server round-trips
-
Enterprise Feature Previews: Eight preview pages for upcoming Enterprise tier features — OPA Policy Engine, Compliance Frameworks (SOC2/ISO27001/CIS), Image Signing & Verification, Runtime Security (eBPF-based), Custom Dashboards, Ephemeral Environments, Manifest Builder, and Git Sync — each with feature descriptions and early-access prompts.
-
About Page: Application version, build info, license edition, active feature flags, and runtime statistics accessible at
/about. -
App Catalog: 14 New One-Click Deploy Apps: The stack catalog grows from 6 to 20 apps, now organized into 7 categories. New additions:
- Storage: Nextcloud (file sync, calendar, contacts, 300+ apps)
- Networking: Traefik v3 (Docker service discovery, Let's Encrypt), WireGuard Easy (VPN server with web UI)
- Communication: Mattermost (Slack-compatible team messaging)
- Security (new category): Passbolt (E2E-encrypted team password manager, LDAP sync), Vaultwarden (Bitwarden-compatible, works with all Bitwarden clients), Authentik (enterprise SSO with OAuth2, SAML, LDAP proxy, SCIM)
- Monitoring (new category): Uptime Kuma (uptime monitoring with status pages, 90+ notification channels), Grafana + Prometheus (metrics stack with embedded
prometheus.ymlvia Docker Compose configs, includes node-exporter) - Development: Woodpecker CI (pipeline-as-code CI/CD with native Gitea OAuth2 integration)
- Database (new category): PostgreSQL 16 + pgAdmin 4 (shared database server with web management UI)
-
Dashboard Service: New
DashboardServiceaggregates container stats, host health, recent events, storage usage, and security scan summaries into a single optimized query for the main dashboard. Replaces multiple individual queries. -
Nginx Reverse Proxy Backend: New
services/proxy/nginx/sub-package adds a complete Nginx proxy backend alongside the existing Caddy adapter. Includes ACME certificate management, upstream builder, and API client. The proxy service abstraction layer is refactored withbackend.goandcaddy_backend.gointerfaces. -
Compliance PDF Report Generator: The compliance service gains
evaluator.go(CIS Docker Benchmark scoring engine) andpdf_report.go(generates downloadable audit-ready PDF reports with findings, risk ratings, and remediation steps). -
Runbook Approvals: Multi-step runbook execution now supports approval gates. Designated approvers must sign off before the next runbook step executes. New
RunbookApprovalmodel, migration043_runbook_approvals, andrunbook_execute.goscheduler worker. -
Automatic Deployment Worker: New
auto_deploy.goscheduler worker continuously watches for GitOps sync triggers and stack update webhooks, automatically redeploying stacks when new image tags are pushed or repository changes are detected. -
SLA Breach Worker: New
sla_breach.goworker evaluates SLA thresholds against live metrics on each scheduler tick, firing notifications and creating calendar events when breach conditions are detected. -
Webhook Dispatch Worker: New
webhook_dispatch.goworker handles reliable asynchronous delivery of outbound webhooks with retry logic and delivery confirmation tracking. -
TOTP Replay Attack Protection: Redis-backed
TOTPReplayStorerejects one-time codes that have already been used within their validity window, preventing replay attacks even when the server clock is slightly ahead of the client. -
Database Migrations 036–044: Nine new schema migrations covering agent events table (
036), git sync repo full-name field (037), vulnerability remediation tracking (038), change events (039), drift detection state (040), resource usage samples and optimization recommendations (041), session recording storage (042), runbook approval gates (043), and calendar events/tasks (044). -
WebSocket Origin Validation: Dedicated
ws_origin.gomodule validates theOriginheader on all WebSocket upgrade requests in both the web and API layers, rejecting cross-origin connections from unauthorized domains. -
Comprehensive Test Suite: ~140 new
_test.gofiles added across the entire codebase. Sharedtestutil/testutil.gohelper package. Coverage now spans agent sub-packages (executor, connection, inventory), Docker SDK wrappers, all seven service layers, PostgreSQL and Redis repositories (including integration tests), API auth handlers, and web WebSocket origin logic. Integration tests for Gitea and NPM clients added withhttptestmocking. -
GitHub Actions CI Pipeline: Lint, test, security scan, build, and Docker image push workflow.
-
GoReleaser Configuration: Multi-platform release builds for Linux (amd64, arm64).
-
Pre-commit Hook:
govulncheck, migration verification, andgo mod tidychecks. -
Prometheus Scrape Configuration: Templates for usulnet and agent metrics.
Changed
-
Application Initialization Refactored: Monolithic
app.go(2,554 lines) decomposed into eight domain-specific initialization files —init_docker.go,init_api.go,init_auth.go,init_scheduler.go,init_server.go,init_services.go,init_web.go, andinit_context.go— plusbootstrap.go,adapters.go, andcommands.go. Each file has a single clear responsibility, improving readability and testability. -
Route Permissions Hardened: SSH, RDP, and SFTP connection routes are now split into separate permission groups. Read-only operations (
host:view) and mutation operations (host:update) are independently gated. SFTP write operations and SSH tunnel create/toggle/delete now requirehost:update; listing and viewing require onlyhost:view. -
Auth Rate Limiting: Login and TOTP POST endpoints are now wrapped with
WebAuthRateLimit()middleware, limiting brute-force attempts per IP. -
Request Body Limit: All authenticated routes now enforce a 10 MB maximum request body size via
MaxRequestBodymiddleware, preventing memory exhaustion from oversized uploads to unexpected endpoints. -
Logout CSRF Protection:
POST /logoutmoved inside the authenticated middleware group, ensuring CSRF validation applies. TheGET /logoutalias is kept for plain anchor links. -
API DTO Layer Removed: The
api/dto/requestandapi/dto/responsepackages were absorbed directly into handler structs, eliminating an unnecessary indirection layer and reducing boilerplate. -
Container Registry UI Dark Theme: Registry browse, tags, and manifest pages rewritten to use the project's dark-first Tailwind classes (
bg-dark-800,divide-dark-600,hover:bg-dark-700/50) instead of the light-mode-firstdark:variant pattern, matching the rest of the application. -
Error Context Wrapping: 234 bare
return errstatements wrapped with contextualfmt.Errorfmessages for better debugging and log traceability. -
Configurable Paths: Hardcoded paths (
/tmp/usulnet/*) moved to a configurablepathssection in config.yaml. -
PostgreSQL TLS by Default: Default PostgreSQL SSL mode changed to
require. Connection enforces TLS verification. -
Redis TLS by Default: Redis connection URL scheme changed from
redis://torediss://. All deployment configurations (docker-compose, install script, test environment) updated with TLS-enabled Redis.
Fixed
-
Containers Not Appearing After Restart (critical):
bootstrapLocalHostpreviously returned early if the local Docker host row already existed in the database, leaving hosts stuck inofflinestatus after any Docker connectivity failure. Fixed with anON CONFLICT DO UPDATE SET status = 'online'upsert that always restores online status on startup. The reconciliation worker and event watchers filter bystatus = 'online', so this was silently preventing all container sync. -
Host Never Recovered from Offline:
performHealthCheckscorrectly calledSetOfflinewhen a ping failed but never calledUpdateStatus(..., "online", ...)when the ping subsequently succeeded. Hosts marked offline by a transient Docker outage stayed offline until the next restart. Fixed by adding the success branch withUpdateStatus. -
Shortcuts Form Multiple Submission: The three icon type inputs (
fa,url,emoji) sharingname="icon"were all submitted simultaneously regardless of which icon type was selected, becausex-showonly setsdisplay:nonewithout disabling form submission. Fixed by adding:disabled="iconType !== 'X'"Alpine.js bindings so only the active input is included in the form submission. -
Ansible Inventory Routes: The
/tools/ansiblehandler (handler_ansible.go) was fully implemented but its routes had been commented out, causing a 404 for both the sidebar navigation link and the tools list card. Routes re-registered:GET /ansible,POST /ansible/upload,POST /ansible/parse,DELETE /ansible/{id}. -
Node Metrics "No Data Available": The metrics collector was using
MetricsTypeNodeto store node-level metrics but the handler was querying with a different type constant. Aligned the type constants so node Storage & Resources displays data correctly. -
NATS "Disconnected" on About Page: The about page handler was probing NATS connectivity before the client had fully connected. Added a connection readiness check so the NATS status reflects the actual connection state.
-
Stack Deploy Log Not Streaming: Stack deployment output was buffered and only shown after completion. Fixed to stream log lines in real-time via the WebSocket connection.
-
Calendar Event Creation: Calendar service was not properly initializing the event store on first use. Fixed initialization sequence.
-
Neovim Editor Integration: The embedded Neovim terminal was not forwarding resize events, causing display corruption. Fixed WebSocket resize handler.
-
Host File Browser Auth: File browser API endpoints were accessible at operator level despite containing write operations. Elevated to admin-only consistent with the security model.
-
Forward Reference Compile Error: Fixed forward reference of
trackedVulnRepoin app.go causing build failure. -
NATS Client Never Connected:
Connect()was never called after NATS client creation, leaving the messaging bus non-functional. -
Audit Service Standalone Mode:
apiHandlers.Auditwas not initialized in standalone mode, causing nil pointer dereference on audit log queries. -
Orphan Contexts in Goroutines: Fixed orphan contexts in Trivy goroutine and scheduler callbacks that could leak resources.
-
Startup Timing Race: Replaced
time.Afterstartup timing with ready channels for deterministic initialization sequencing. -
Proxy Host ID Resolution: Fixed proxy host ID resolution to match by
hashUUIDToIntinstead of list index, which broke when hosts were added/removed. -
Data Race in Audit Mock: Fixed concurrent slice access in audit service test mock.
-
Pricing Page Node Count Display: Fixed visual off-by-one where the pricing calculator showed one more node than actually purchased. The master node (always free) is now displayed separately.
Security
- Removed hardcoded JWT secret and encryption key from versioned configuration files
- JWT token lookup restricted to
Authorizationheader and cookie; query-parameter tokens rejected on all API routes - CORS restricted to same-origin by default (was
*) - Host terminal and file browser access elevated to admin-only (previously operator-level)
- 10 MB upper limit on host file reads via the file browser API
- Webhook tokens hashed with SHA-256 before database storage
- Secure cookies enabled by default when TLS is active
- Per-route Content Security Policy: strict policy globally, relaxed CSP only for Monaco Editor routes
getRealIPnow uses the rightmost non-private IP fromX-Forwarded-For, preventing IP spoofing via prepended addressesFailedLoginAttemptsfield excluded from User JSON serialization- Encryption key validated for hex encoding (not just byte length)
- Default PostgreSQL SSL mode changed to
require - Redis TLS encryption enabled by default with ECDSA P-256 self-signed certificates
- JetStream stream size limits added (
MaxBytes/MaxMsgs) to prevent unbounded disk growth - TOTP replay attack protection via Redis-backed used-code store
- WebSocket upgrade requests now validated against allowed origin list
Full Changelog: https://github.com/fr4nsys/usulnet/compare/v26.2.3...v26.2.4
Breaking Changes
- Redis connection URL scheme changed from redis:// to rediss:// (TLS enforced by default).
- Connection string defaults updated to require TLS for PostgreSQL and Redis.
Security Fixes
- Removed hardcoded JWT secret and encryption key from versioned configuration files.
- JWT token lookup restricted to Authorization header and cookie; query‑parameter tokens rejected on all API routes.
- CORS now defaults to same‑origin (was *).
- Host terminal and file browser access elevated to admin‑only.
- Webhook tokens hashed with SHA‑256 before database storage.
- Secure cookies enabled by default when TLS is active.
- WebSocket upgrade requests validated against allowed origin list.
Weekly OSS security release digest.
The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.
No spam, unsubscribe anytime.
Share this release
About fran-olivares/usulnet
All releases →Related context
Related tools
Beta — feedback welcome: [email protected]