Skip to content

Add basic auth support to the proxy - #1865

Open
r4mbo7 wants to merge 2 commits into
basecamp:mainfrom
r4mbo7:basic-auth
Open

Add basic auth support to the proxy#1865
r4mbo7 wants to merge 2 commits into
basecamp:mainfrom
r4mbo7:basic-auth

Conversation

@r4mbo7

@r4mbo7 r4mbo7 commented Jun 4, 2026

Copy link
Copy Markdown

Add basic auth support to the proxy

Fixes #1604

What

Adds HTTP Basic Auth as a proxy option, configurable per app/role:

servers:
  web:
    proxy:
      basic_auth:
        username: "abc"
        password: "123456"

Kamal renders this into a --basic-auth="username:password" flag on the
kamal-proxy deploy command. The proxy enforces it, returning 401 Unauthorized
with a WWW-Authenticate challenge for requests without valid credentials.

How it works

Basic auth has to be enforced by something in the request path, and Kamal is never
in that path — kamal-proxy is. So this is a two-part change:

  • Proxy side (companion PR: Add HTTP Basic Auth support to deploy kamal-proxy#216): new --basic-auth deploy
    flag. The password is hashed before it's stored, and credentials are compared in
    constant time.
  • Kamal side (this PR): config parsing, validation, schema/docs, and flag generation.

It lives under proxy: for consistency with every other routing option (host,
ssl, path_prefix, …), and it inherits/overrides per role through the existing
proxy-merge machinery.

Notes

  • Both username and password are required; a partial config raises a ConfigurationError.

  • Credentials are sent on every request, so enable ssl when using basic auth (noted in the docs).

  • The password ends up on the kamal-proxy deploy command line and in the proxy's
    stored options, so prefer injecting it from a secret rather than committing it:

    password: <%= ENV["WEB_PASSWORD"] %>
  • ⚠️ MINIMUM_VERSION is intentionally not bumped yet — it should move to whatever
    kamal-proxy release first ships Add HTTP Basic Auth support to deploy kamal-proxy#216. Happy to update it once that's tagged.

  • The basic auth middleware only applies to traffic routed through the HTTP/HTTPS server. kamal-proxy's internal health check connects directly to the backend container (bypassing the middleware stack entirely), so deploys are unaffected.

Tests

test/configuration/proxy_test.rb covers flag emission, absence when unset,
validation of partial configs, and per-role override. Full config suite + rubocop pass.

Allow protecting an app behind HTTP Basic Auth from the deploy config:

    servers:
      web:
        proxy:
          basic_auth:
            username: "abc"
            password: "123456"

This passes the credentials to kamal-proxy via a new --basic-auth flag,
which enforces the auth and returns a 401 challenge for unauthenticated
requests. Both username and password are required, and the option is
inherited/overridable per role like the rest of the proxy config.

Requires kamal-proxy with basic auth support (basecamp/kamal-proxy#216).
The MINIMUM_VERSION bump is left until that ships in a release.

Fixes basecamp#1604

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 4, 2026 22:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds HTTP Basic Auth support to the proxy configuration so deployments can enforce authentication at the kamal-proxy layer.

Changes:

  • Add basic_auth support to proxy deploy options/command args.
  • Validate that basic_auth contains both username and password.
  • Document basic_auth configuration and add test coverage for the new behavior.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
test/configuration/proxy_test.rb Adds tests covering basic-auth deploy options/args, validation failures, and role overrides
lib/kamal/configuration/validator/proxy.rb Validates presence of both username/password when basic_auth is configured
lib/kamal/configuration/proxy.rb Adds basic_auth helpers and includes basic-auth in deploy options
lib/kamal/configuration/docs/proxy.yml Documents new basic_auth YAML configuration and guidance on secrets/SSL

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +24 to +28
if config["basic_auth"].is_a?(Hash)
if config["basic_auth"]["username"].blank? || config["basic_auth"]["password"].blank?
error "basic_auth requires both username and password to be set"
end
end

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.

Good instinct, but this is already covered: the proxy config is schema-validated against docs/proxy.yml, where basic_auth is defined as a hash. A string/boolean/array value raises proxy/basic_auth: should be a hash before basic_auth? is ever reached, so it fails closed rather than silently ignoring the misconfiguration. I've added a test ("basic auth must be a hash") to make that explicit and prevent regressions.

Comment thread lib/kamal/configuration/proxy.rb
Comment thread test/configuration/proxy_test.rb Outdated
Wrap the --basic-auth argument as a sensitive value so the password is
redacted in SSHKit command logs and other human-visible output, while
still being passed verbatim to kamal-proxy.

Also make the deploy-args test resilient to argument quoting and assert
the credentials are redacted, plus cover that a non-Hash basic_auth is
rejected (already enforced by the proxy schema).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@r4mbo7 r4mbo7 mentioned this pull request Jun 6, 2026
@r4mbo7
r4mbo7 requested a review from Copilot June 17, 2026 10:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Comment on lines +24 to +28
if config["basic_auth"].is_a?(Hash)
if config["basic_auth"]["username"].blank? || config["basic_auth"]["password"].blank?
error "basic_auth requires both username and password to be set"
end
end
@pievalentin

Copy link
Copy Markdown

Would love to this shipped in kamal. Would make having stage deployment behind a basic auth a breeze

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.

Suggestion: Basic auth

3 participants