- Switch default theme from dark to aurora across server config,
all 9 static HTML pages, example config, and docs
- Fix theme docs: list all 8 presets (was 6, missing jaguar/aurora),
add missing type_vdi_bg/type_vdi_fg fields
- Add Vault/address book setup as recommended post-install step in
installation docs — the address book is the primary user-facing
feature and requires Vault
- Renumber subsequent install steps
- Add max_sessions (default 500) and max_sessions_per_user (default 50)
config options. Session creation is rejected with a clear error when
limits are reached. Set to 0 for unlimited (backward compatible).
- Add background reaper that removes completed/error/expired sessions
from the in-memory HashMap after session_cleanup_delay_secs (default
300s). Session history in SQLite is not affected.
- Prevents resource exhaustion from unbounded session creation and
memory leak from accumulated completed sessions.
Closes#99
Avoids false rejections behind reverse proxies where the Host header
may include an explicit port (e.g. :443) that the browser's Origin
omits as a default port.
From OWASP-based security audit (categories 2-12):
- Vault path traversal: validate folder names on read operations
(get_folder_config, list_entries, get_entry) — write operations
already validated but reads did not
- SSH host key: reject connection when stored key fails to parse,
instead of silently accepting (was bypassing verification)
- Config secret redaction: custom Debug impls for OidcConfig and
VaultConfig that redact client_secret, role_id, and client_key
- Branding XSS: HTML-escape site_title and logo_url config values
before injecting into page templates
- WebSocket CSWSH: validate Origin header against Host header on
WebSocket upgrade, reject cross-origin requests
- VDI bind mounts: add nosuid,nodev mount options to home directory
bind mounts to prevent setuid binary attacks
- Recording access: restrict list/serve endpoints to poweruser+ role
(previously any authenticated user including viewers could access
all recordings)
- Redact share_url from session listings for non-owners — previously
any authenticated user could enumerate share tokens and join sessions
they didn't create (share_url now only returned to session creator
and admins)
- Always rate-limit OIDC login/callback (1/sec burst 5 per IP)
regardless of rate_limit config, preventing brute-force on auth
- Fix disconnect instruction detection: use instruction boundary
matching instead of substring contains — clipboard content or typed
text containing "10.disconnect;" could falsely trigger VDI container
destruction
- Restrict sudoers chown rule to rustguac:rustguac only, preventing
arbitrary ownership changes on the LUKS mount point
Bollard 0.20 moved container option types from bollard::container to
bollard::query_parameters, replaced Config<T> with ContainerCreateBody,
and changed several fields to Option types. Update all imports and call
sites in the VDI Docker driver accordingly.
check_server_key no longer blindly accepts all keys. Jump hosts now
support a host_key field stored in Vault alongside credentials.
- New POST /api/ssh/probe-host-key endpoint probes an SSH server and
returns its public key, fingerprint, and algorithm
- Address book UI: "Verify Host Key" button per jump host probes the
server, shows fingerprint for confirmation, stores key on save
- TunnelHandler verifies the server key against the stored key on
connect — rejects with detailed error on mismatch
- Unpinned keys accepted with TOFU warning log for backward compat
- host_key preserved through credential merging on entry update
Closes#95
Frame dropping at queue depth 5 triggered during normal operation and
broke the H.264 reference chain, corrupting output until the next
keyframe. Remove frame dropping entirely — sync gating alone provides
sufficient flow control by delaying the sync response until decodes
complete, giving guacd accurate backpressure.
The H.264 decode path bypassed the Guacamole sync mechanism — the sync
response fired immediately without waiting for WebCodecs to finish
decoding. guacd thought the client was keeping up and sent at full rate,
causing the decode queue to grow without bound (30+ seconds of lag
observed over time).
Fix: gate the sync response on H.264 decode completion so guacd gets
real backpressure. Also drop delta frames when the decode queue exceeds
5 frames as a safety valve for transient overload (tab backgrounding).
- Add pending-decode tracking and per-frame position capture to
H264Decoder.js (fixes shared mutable state race)
- Add waitForPending() with 1s safety timeout for sync gating
- Add frame dropping when decodeQueueSize > 5 (never drops keyframes)
- Add stats() method for console debugging (__guac_client._h264Decoder.stats())
- Gate sync response in Client.js on H.264 decode completion
Closes#93
Switch reqwest from rustls-tls-webpki-roots to rustls-tls-native-roots
so the OS trust store is used by default — private CAs installed
system-wide now work without extra config.
Add ca_cert and tls_skip_verify options to [oidc] for environments
where the system store isn't available or for debugging TLS issues.
Improve OIDC discovery error formatting to surface the actual cause
(issuer mismatch, TLS failure, etc.) instead of opaque "Request failed".
Closes#94
- GitHub badges (CI, release, license, Docker pulls)
- VDI featured in architecture, features, and quick start
- Feature tables for session types, security, connectivity
- Removed RPM/RHEL references (build from source for others)
- Complete docs index with all current pages
- Cleaner quick start with Docker+VDI instructions
Logout link moved inside the float-right user-menu-wrapper so both
Logout and Settings appear on the far right of the nav bar. Fixed
addressbook.html Settings font size to match other pages (1.3em).
Logout is now a standalone nav link next to Settings (Logout Settings
order, right-aligned). Applied consistently across all 7 HTML pages.
Removed Logout from the settings dropdown menu.
- start_or_reuse checks if existing container's image differs from
the requested image. If so, stops the old container and creates
a new one with the new image.
- Clear stale VDI thumbnail when starting a new session, so old
screenshots don't linger from previous images/failed sessions.
- Run example with Docker socket mount and group-add for VDI
- Commented-out [vdi] section in default config template
- vdi-homes directory and volume for persistent home dirs
- No changes to default behavior — VDI stays disabled unless configured
- New Session form collapsed by default (click to expand)
- Added VDI (Docker) to session type dropdown with container image field
- Jump hosts hidden for VDI sessions (local containers)
Address book entries can now set container_idle_timeout_mins to override
the global idle_timeout_mins. Stored as a Docker label on the container
so the reaper reads it without needing session state. Reaper also cleans
up VDI thumbnails when removing idle containers.
Client captures display thumbnail every 10s (JPEG, 320px), uploads
to server. Address book shows "Active Sessions" section with thumbnail
grid — click to reconnect via address book connect flow.
- PUT/GET /api/sessions/{id}/thumbnail endpoints
- GET /api/vdi/containers — list running VDI containers for current user
- VDI container labels: rustguac.entry, rustguac.image for reconnect
- Thumbnail copied to container-keyed file on disconnect (persists)
- Dormant VDI containers shown with last thumbnail
- Cache-busting on thumbnail images for live updates
- Moved logout button out of settings dropdown
- Fixed: VDI containers endpoint in authenticated route group
- Fixed: thumbnail click uses address book connect (not stale session URL)
Show a centered overlay when the Guacamole client disconnects or
errors, instead of leaving a frozen canvas. Offers Reconnect (reload)
and Close (navigate to home) buttons. Applies to all session types.
Sniff for guacd's 10.disconnect; instruction in the proxy stream to
distinguish server-initiated disconnects (user logout, crash) from
browser-initiated disconnects (tab close, network drop).
- Logout from desktop → container stopped and removed immediately
- Tab close / network drop → container persists for reconnection
- Normal RDP/SSH/VNC sessions unaffected (flag only acted on for VDI)
Upstream GUACAMOLE-2221 introduced -Werror=maybe-uninitialized failure.
Pin all build paths (CI, Dockerfile, install.sh) to last known-good commit.
Update guacd version deliberately, not on every upstream push.