AllYourBot / hostedgpt

An open version of ChatGPT you can host anywhere or run locally.
MIT License
228 stars 92 forks source link

Support auth via HTTP headers #340

Closed krschacht closed 1 week ago

krschacht commented 1 month ago

Requests like #336, #333 will come up with requirements to support other means to authenticate besides username+password. Read: SSO to support "business" use cases (e.g. using generic oAuth 2, EntraID, Google SSO)

In my case to self-host applications like hostedgpt, I tend to use a "ZeroTrust" approach, where the application is not exposed to the public internet. ZeroTrust approaches, like with Tailscale ensure authentication of a user already on the infrastructure level. So no need to re-authenticate the user.

To support SSO, there are two ways to implement it:

1) Add support to omniauth and support with this a random set of SSO providers. This is a maintenance hell for this proejct 2) Allow to skip username+auth and allow to conduct authentication using a HTTP header. This outsources the authenticaton logic to 3rd party services. This is what I would recommend

Deep dive in auth via HTTP header

A 3rd party service (e.g. a reverse proxy or a ZeroTrust appliance) would set a header, which if it exists means the user has been authenticated.

This is supported by Reverse Proxies like Traefik (see for example BasicAuth and especially ForwardAuth where they support a 3rd party auth server), Caddy with forward_auth, Nginx with auth_request_set (source: blog post)

ZeroTrust services like Tailscale can be used with $ tailscale serve. Tailscale sets in such a case so called "Identity headers" (ref. https://tailscale.com/kb/1312/serve?q=header#identity-headers)

The key is: the name of the "identity headers" is not standardized. It would need to be exposed as a configuration setting (e.g., environment variable).

Example: Paperless (a self-hosted DMS) allows to enable authentication via "HTTP_REMOTE_USER" via the setting PAPERLESS_ENABLE_HTTP_REMOTE_USER_API (boolean). The name of the header can be set via PAPERLESS_HTTP_REMOTE_USER_HEADER_NAME. I think this is related to a default feature of Django (ref. https://docs.djangoproject.com/en/5.0/howto/auth-remote-user/).

Possible approach to support this in Rails / hostedgpt

  1. A password must not need to be mandatory at the User model. Ref. https://github.com/allyourbot/hostedgpt/blob/0.6/app/models/user.rb#L7
  2. The Authenticate concern would neither set nor read session[:current_user_id]. Instead, it would look at the defined HTTP header in each request. Ref. https://github.com/allyourbot/hostedgpt/blob/0.6/app/controllers/concerns/authenticate.rb#L11-L16

Originally posted by @tmaier in https://github.com/allyourbot/hostedgpt/discussions/338

tmaier commented 1 month ago

Check :)

tmaier commented 1 week ago

I think this issue can be closed