Module: CloudflareAccessGate
- Defined in:
- lib/cloudflare_access_gate.rb,
lib/cloudflare_access_gate/gate.rb,
lib/cloudflare_access_gate/version.rb,
lib/cloudflare_access_gate/jwks_cache.rb,
lib/cloudflare_access_gate/audit_logger.rb,
lib/cloudflare_access_gate/structured_logger.rb
Overview
Rack middleware that gates a dashboard (typically Sidekiq::Web) behind Cloudflare Access, plus an audit logger for the requests that get through. See the README for the ENV contract and security notes.
Defined Under Namespace
Classes: AuditLogger, Gate, JwksCache, StructuredLogger
Constant Summary collapse
- VERSION =
'0.2.1'
Class Attribute Summary collapse
-
.logger ⇒ Object
Logger used by both middlewares.
Class Method Summary collapse
-
.logger_for(name) ⇒ Object
Returns the logger to use for
name, wrapped so structured payloads work regardless of the underlying logging library. -
.protect(app, audience:, session_key:, **gate_options) ⇒ Object
Wire the full Cloudflare Access protection stack onto a Rack app in the canonical order.
Class Attribute Details
.logger ⇒ Object
Logger used by both middlewares. Assign anything that responds to
debug/info/warn/error — SemanticLogger, a stdlib Logger,
Rails.logger, and so on:
CloudflareAccessGate.logger = Rails.logger
When left unset (nil), SemanticLogger is used if the host app has it
loaded (giving per-class named loggers and tagged output), and a stdlib
Logger.new($stdout) otherwise.
26 27 28 |
# File 'lib/cloudflare_access_gate.rb', line 26 def logger @logger end |
Class Method Details
.logger_for(name) ⇒ Object
Returns the logger to use for name, wrapped so structured payloads work
regardless of the underlying logging library.
30 31 32 |
# File 'lib/cloudflare_access_gate.rb', line 30 def logger_for(name) StructuredLogger.wrap(@logger || default_logger(name)) end |
.protect(app, audience:, session_key:, **gate_options) ⇒ Object
Wire the full Cloudflare Access protection stack onto a Rack app in the canonical order. Typically called on Sidekiq::Web from an initializer:
CloudflareAccessGate.protect(
Sidekiq::Web,
audience: ENV['CLOUDFLARE_ACCESS_SIDEKIQ_AUD'],
session_key: '_myapp_sidekiq_session'
)
This installs, in order:
1. Gate - rejects requests without a valid Cf-Access JWT
2. AuditLogger - logs who accessed the dashboard
3. ActionDispatch::Cookies
4. ActionDispatch::Session::CookieStore(key: session_key)
ActionDispatch (from Rails/actionpack) must be loaded before this is
called, so .protect is for Rails hosts only. Gate and AuditLogger
themselves are plain Rack and carry no Rails dependency — outside Rails,
install them directly with app.use.
Extra keyword arguments are forwarded to Gate (e.g. team_domain:,
jwks_stale_grace:).
Idempotent: the middleware stack is class-level, so re-calling would otherwise re-append it. Returns the app.
72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/cloudflare_access_gate.rb', line 72 def self.protect(app, audience:, session_key:, **) @install_mutex.synchronize do return app if @installed[app] app.use Gate, **, audience: audience app.use AuditLogger app.use ActionDispatch::Cookies app.use ActionDispatch::Session::CookieStore, key: session_key @installed[app] = true end app end |