WarpEngine: let the host say who a browser is

The access policy asks who the caller is, and until now only a bearer token
could answer. That is what a desktop client carries — but a person clicking a
download link on the site carries a session instead, and the engine has no idea
what a session is. So a host that gated its catalog found its own signed-in
visitors refused at /api/download, which is a regression the shadowed route used
to hide.

c.subject_resolver is a callable taking the Rack request and returning the
host's subject: `->(request) { request.env["warden"]&.user }` for a Devise app.
Unset — every deployment today — a non-bearer request stays anonymous, exactly
as before. A resolver that raises is logged and treated as anonymous, because a
broken one turning every read into a 500 is worse than an anonymous request.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-19 10:36:30 +02:00
co-authored by Claude Opus 5
parent 6c8b026590
commit 76427bab91
5 changed files with 103 additions and 3 deletions
@@ -60,6 +60,11 @@ Rails.application.config.to_prepare do
# It calls WarpEngine::DeviceGrantService#approve. A path is made absolute
# against the request, so you need not know your own hostname (default "/devices").
# c.identity_verification_url = "/devices"
# A browser has a session rather than a bearer token, and the engine cannot
# read one. Say how, and your signed-in visitors are recognised on the
# read-only endpoints too:
# c.subject_resolver = ->(request) { request.env["warden"]&.user }
# c.device_code_ttl = 600 # seconds a pending code lives
# c.device_code_interval = 5 # seconds a client is told to wait between polls