Links can now open a page inside an app, not just switch to it, so a
Homarr tile or widget can open the exact movie, request or dashboard. This
release also makes several security settings that were documented but
never enforced actually work, adds optional verification of Cloudflare
Access tokens, and corrects much of the wiki, whose guides now use simpler
English.
Setup and examples for deep links are on the
Deep links in links
wiki page.
Upgrade notes:
- Per-app
auth_bypassrules andaccesslists now take effect. If
your config has either, review them before upgrading: bypass rules will
open their paths without a login, and access lists will hide apps from
users they leave out. - Apps without an
enabledkey are now enabled. Only hand-written
YAML is affected; Settings always writes the key. - Cloudflare Access users: add
auth.cloudflare_access(see the
Cloudflare Access guide).
Without it, also add a Cloudflare rule that removes theRemote-Groups
request header, because a signed-in user could otherwise send
Remote-Groups: admin. - If your compose file is based on the example and drops all
capabilities, addcap_add: [CHOWN, SETUID, SETGID]; without them the
container cannot start.
Added
- Deep links in Muximux links. A link can open a page inside the target
app:#emby?path=%2Fweb%2Findex.html%23!%2Fitem%3Fid%3D123, or one path
per app in split view (#emby+radarr?emby=...&radarr=...). This works
from Homarr tiles and Custom JSX widgets, bookmarks and the address bar,
where themuximux:navigatemessage is not available. The target app
opts in with the new "Allow deep links" setting (allow_deep_links,
labelmuximux.app.allow_deep_links), and the path must stay inside the
app, the same rule as the message API. Without it the link only switches
apps. (#545) - Cloudflare Access token verification. Set
auth.cloudflare_access.team_domainand.audience, and forward auth
checks the signedCf-Access-Jwt-Assertionon every request
(signature, issuer, audience, expiry) and takes the user's email, name
and groups from it. Headers, which Cloudflare passes through from the
browser, then no longer decide who the user is or whether they are an
admin.
Security
- Per-app
accesslists (access.roles,access.users) are
enforced. They were read from the config but never checked. They now
apply wherevermin_roleandallowed_groupsdo (the menu and apps
API, the reverse proxy, HTTP actions, health status and Docker
controls), on top of those two. Usernames must match exactly; admins
always pass. A gateway site linked withapp_namekeeps its own
require_auth,min_roleandallowed_groups. - An OIDC sign-in no longer takes over a local account with the same
name. The session's ID is the provider's username claim, so a
provider user named like a local user (such as a kept break-glass
admin) signed in with that account's role. - HTTP actions no longer expose their URL. A failed action's error, in
the audit log and the response, quoted the full target URL, including
any secret in its query string. The app list also sent the full URL to
every user who could see the action. Relay and health check errors now
never quote a URL, non-admins get only an action's scheme and host, and
non-admins no longer receive an app'shealth_url. - A disabled HTTP action can no longer be fired by POSTing to
/api/app-action/{name}. It was only hidden from the menu. - The HTTP action and Docker lifecycle endpoints answer 404, not 403,
for an app the caller may not see, so they no longer reveal which
hidden apps exist. - Gateway migration from a Caddyfile refuses a site that uses TLS
client authentication (client_auth), whichgateway_sitescannot
express, instead of migrating it without the certificate check. - Docs: a
:roDocker socket mount does not limit Docker API calls, so
it is no protection against a compromised Muximux. The guides now
recommend a socket proxy that filters by endpoint. The Cloudflare
Access guide now covers spoofed groups headers and unprotected routes. klauspost/compress1.20.2 (GO-2026-6865).
Fixed
- Per-app
auth_bypassrules take effect. They were read from the
config but never handed to the auth middleware, so an allowlisted path on
a proxied app (an API called with the Muximux API key, an RSS feed, a
webhook) still redirected to the login page. Rule paths are relative to
the app (/api/*covers/proxy/sonarr/api/*); the full path also
works. A rule that could reach outside its app (an empty path, another
app's prefix,.., or a slug two apps share) is ignored with a warning,
and changes apply on save. When a rule passes a request on the Muximux
API key, the key is removed before the request reaches the backend. - The example
docker-compose.ymlstarts. It dropped all Linux
capabilities, so the entrypoint could not switch to thePUID/PGID
user and the container exited withsu-exec: setgroups: Operation not permitted. It now adds backCHOWN,SETUIDandSETGID. - Health checks follow three redirects, as documented, instead of two.
- A proxied app's plain
fetch('/api/appearance')reaches Muximux; the
proxy's interceptor used to send it to the app's backend. - Docker discovery import refuses an app whose name maps to the same
/proxy/<slug>/path as an existing app, as Settings already did. - Many wiki pages corrected where they did not match the code, from the
OIDC and forward-auth guides to CSRF, gateway and health details.
Changed
- Apps without an
enabledkey are enabled. They loaded as disabled,
although the wiki always described apps as enabled by default and its
minimal examples left the key out. Typos inside app entries are still
rejected. Two apps without the key whose names map to the same
/proxy/<slug>/path now stop startup with an error. - The wiki's step-by-step guides and explainers use simpler English: one
action per step, short sentences, terms explained on first use. - Dependencies updated to their latest releases, including Caddy 2.11.9,
Paraglide 3 and jsdom 31.