Add basic auth support to the proxy - #1865
Conversation
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>
There was a problem hiding this comment.
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_authsupport to proxy deploy options/command args. - Validate that
basic_authcontains bothusernameandpassword. - Document
basic_authconfiguration 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.
| 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 |
There was a problem hiding this comment.
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.
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>
| 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 |
|
Would love to this shipped in kamal. Would make having stage deployment behind a basic auth a breeze |
Add basic auth support to the proxy
Fixes #1604
What
Adds HTTP Basic Auth as a proxy option, configurable per app/role:
Kamal renders this into a
--basic-auth="username:password"flag on thekamal-proxy deploycommand. The proxy enforces it, returning401 Unauthorizedwith a
WWW-Authenticatechallenge 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-proxyis. So this is a two-part change:--basic-authdeployflag. The password is hashed before it's stored, and credentials are compared in
constant time.
It lives under
proxy:for consistency with every other routing option (host,ssl,path_prefix, …), and it inherits/overrides per role through the existingproxy-merge machinery.
Notes
Both
usernameandpasswordare required; a partial config raises aConfigurationError.Credentials are sent on every request, so enable
sslwhen using basic auth (noted in the docs).The password ends up on the
kamal-proxy deploycommand line and in the proxy'sstored options, so prefer injecting it from a secret rather than committing it:
MINIMUM_VERSIONis intentionally not bumped yet — it should move to whateverkamal-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.rbcovers flag emission, absence when unset,validation of partial configs, and per-role override. Full config suite + rubocop pass.