Open AnalogJ opened 1 year ago
This is probably several different features as there are many different things that could be implemented and self-hosters likely already have their own preferred solution. It is probably crazy to try to implement everything, but here is some brainstorming of things I have used/considered that could be implemented as part of this:
For broadest coverage with least implementation effort, Authorized-User
header-type authentication is a reasonably-common favorite. A large part of the burden is sufficiently documenting the ways in which it's dangerous; i.e. "don't open the service directly to the internet, ensure your proxy strips the header from incoming requests, etc."
Based on my pretty light understanding of the code, this would be a pretty straightforward alteration to backend/pkg/web/middleware/require_auth.go
: check the config to see if an auth.remote_user_header
is set, and if so branch from the default logic to find the value of the configured header, deny if not set, and otherwise set the authenticated username. (Side note, it would be great to create the user on the fly here -- in my use-case, I'd have oauth2-proxy in front attached to my existing SSO infrastructure, and don't necessarily have a list of usernames to create at install-time.)
Moving a related request over here – having the ability to disable signups for now would be a great first step. I'd like to expose my Fasten instance to family members without risking some random person attempting to load their health data into the NUC in my office. 😂
This is probably several different features as there are many different things that could be implemented and self-hosters likely already have their own preferred solution. It is probably crazy to try to implement everything, but here is some brainstorming of things I have used/considered that could be implemented as part of this:
SSO/Oauth with "well known" providers such as Google or Facebook.
SSO/Oauth with custom/arbitrary providers.
OIDC, similar to but potentially not the same as SSO. Specifically being able to discover providers given a provider URL and/or using webfinger discovery.
SAML
Externally provided auth via e.g. oauth2-proxy that inserts a header identifying the authenticated user into the request (There are other mechanisms similar to this I can't recall at the moment)
Ability to do UN/PW lookup/validation against an external DB/IDP/service. (LDAP, SQL, CAS, SASL, IMAP, SMTP, etc. are all possibilities)
Hm… so just to clarify: OpenID Connect (OIDC) is directly based on OAuth 2.0 and probably the best option for SSO nowadays. So 1., 2. and 3. can be summarised in a single feature since OIDC is a standard after all. Having predefined configurations for well known providers usually just saves three config parameters manually or so.
Older application have certain providers separately but mostly this shouldn't be necessary.
See for instance how Mattermost describes this:
With OpenID Connect, users can also use their login to Keycloak, Atlassian Crowd, Apple, Microsoft, Salesforce, Auth0, Ory.sh, Facebook, Okta, OneLogin, and Azure AD, as well as others, as a Single Sign-on (SSO) service for team creation, account creation, and user login.
Modern applications just allow to set all parameters and they don't care about who's well known and who isn't (i.e. Stalwart, Nextcloud, Vikunja, Tolgee or Penpot).
So having all configuration parameters available (maybe even just via ENV variables like Penpot does it) will enable 1., 2. and 3. out of the box.
TL:DR: I don't see any point in implementing anything else than generic OIDC as a start. Everything else can be connected via other application that are already matured and secure. There are also quite a few OIDC packages for Go available (i.e. go-oidc or this one).
https://discord.com/channels/1023634406935642223/1023634407480885400/1099367475184926740