Skip to content

feat: Add configurable HTTP Basic Authentication for the web UI - #148

Open
HassaanSiraj wants to merge 3 commits into
fgrehm:masterfrom
HassaanSiraj:feat/add-basic-auth
Open

feat: Add configurable HTTP Basic Authentication for the web UI#148
HassaanSiraj wants to merge 3 commits into
fgrehm:masterfrom
HassaanSiraj:feat/add-basic-auth

Conversation

@HassaanSiraj

@HassaanSiraj HassaanSiraj commented Feb 23, 2026

Copy link
Copy Markdown

Summary

Adds opt-in HTTP Basic Authentication to protect the Letter Opener Web interface, primarily useful for staging and pre-production environments where the UI is accessible but should not be publicly open.

Users can enable it via the existing LetterOpenerWeb.configure block in a Rails initializer:
LetterOpenerWeb.configure do |config| config.authentication_enabled = true config.username = ENV['LETTER_OPENER_WEB_USERNAME'] config.password = ENV['LETTER_OPENER_WEB_PASSWORD'] end

Details

  • Opt-in by default -- authentication_enabled defaults to false, so existing users are unaffected.
  • No new dependencies -- uses Rails' built-in authenticate_or_request_with_http_basic and ActiveSupport::SecurityUtils.secure_compare for constant-time credential comparison.
  • Misconfiguration warning -- if authentication_enabled is true but username or password is blank, a warning is logged at boot time via Rails.logger.warn so the issue is caught early.
  • Config options: authentication_enabled (boolean), username (string), password (string) -- all added to LetterOpenerWeb::Config, consistent with the existing letters_location pattern.

Test plan

  • Auth enabled + correct credentials returns 200
  • Auth enabled + no credentials returns 401
  • Auth enabled + wrong username returns 401
  • Auth enabled + wrong password returns 401
  • Auth disabled (default) allows access without credentials
  • Auth disabled with username/password set still allows open access
  • basic_auth_enabled? returns correct value for all config combinations
  • Warning is logged when authentication_enabled = true but credentials are blank

@HassaanSiraj
HassaanSiraj force-pushed the feat/add-basic-auth branch 2 times, most recently from d4735eb to f51123c Compare February 23, 2026 22:41

module LetterOpenerWeb
class ApplicationController < ActionController::Base
before_action :enforce_basic_auth, if: -> { LetterOpenerWeb.config.enabled? }

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A general #enabled? makes it seem like it's checking if LetterOpenerWeb itself is enabled or not. But that's not the case. I think we should be more explicit.

Suggested change
before_action :enforce_basic_auth, if: -> { LetterOpenerWeb.config.enabled? }
before_action :enforce_basic_auth, if: -> { LetterOpenerWeb.config.basic_auth_enabled? }

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see your point, this makes the intent much clearer. I’ll go ahead and update it to reflect this.

- Inline before_action condition with a lambda instead of a separate
  private method
- Add .to_s guard on credentials in secure_compare
- Rename validate! to warn_if_basic_auth_misconfigured for clarity
- Add enabled? alias for basic_auth_enabled?
- Merge attr_accessor declarations into a single line
- Fix long lines in controller specs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants