Files
sure/app/constraints/super_admin_constraint.rb
Guillem Arias Fauste e699f5272b feat(sidekiq): mount Web UI in production behind super-admin sessions (#2683)
/sidekiq was mounted `unless Rails.env.production?`, and the Docker
image bakes RAILS_ENV=production — so no self-hosted or managed
deployment has ever had queue tooling, while the production basic-auth
block (with default "sure"/"sure" credentials) was dead code. Worse,
any custom non-production env (e.g. staging) got the dashboard with no
authentication at all.

Now:

- Development keeps the open mount for convenience.
- Everywhere else the route only exists for a signed-in super admin,
  via a routing constraint that resolves the signed session cookie the
  same way Authentication#find_session_by_cookie does. The session's
  user is always the true user (impersonation is resolved at the
  Current level and impersonating a super admin is forbidden), and
  sessions are only created after MFA verification, so neither can
  bypass it. Fails closed — errors mean 404.
- The "sure"/"sure" default credentials are deleted. Basic auth now
  activates only when BOTH SIDEKIQ_WEB_USERNAME and
  SIDEKIQ_WEB_PASSWORD are explicitly set, as an optional second
  layer on top of the constraint.
- Documented in .env.example and docs/hosting/docker.md, including
  warnings that the dashboard is break-glass tooling: never manually
  retry SimplefinConnectionUpdateJob (single-use token), and deleting
  jobs does not update the corresponding Sure records.

The super-admin bar's Jobs link is feature-detected via
sidekiq_web_available? and lights up automatically now that the route
exists in production.
2026-07-17 07:00:27 +02:00

24 lines
1008 B
Ruby

# Routing constraint for mounting engines that bypass ApplicationController
# entirely (e.g. Sidekiq::Web). Resolves the signed session cookie the same
# way Authentication#find_session_by_cookie does and requires the session's
# user to be a super admin.
#
# The session's user is always the TRUE user: impersonation is resolved at the
# Current level, so an impersonated member can never satisfy this, and a
# super admin impersonating someone still is one. Sessions are only created
# after MFA verification, so this does not bypass MFA either.
#
# Fails closed: any error (garbage cookie, unreachable DB) means the route
# does not exist for the request (404).
class SuperAdminConstraint
def matches?(request)
cookie_value = request.cookie_jar.signed[:session_token]
return false if cookie_value.blank?
Session.find_by(id: cookie_value)&.user&.super_admin? || false
rescue => e
Rails.logger.warn("SuperAdminConstraint rejected request: #{e.class}: #{e.message}")
false
end
end