Authentication: match username from configurable header
I'd like to elevate https://github.com/binwiederhier/ntfy/issues/19#issuecomment-1023118885 as an explicit feature request, that I believe enables administrators/users that self-host to handle both https://github.com/binwiederhier/ntfy/issues/530 and https://github.com/binwiederhier/ntfy/issues/296 (and may make a custom solution for https://github.com/binwiederhier/ntfy/issues/297 easier for users to implement).
I'd propose a configuration option (user-header) specifying a trusted header that a proxy in front of ntfy could set, and whose value is matched to a username. If the value matches an existing username, then ntfy assumes the request/connection to originate from that user, delegating the responsibility for credential validation to the proxy.
Example:
If the configuration for the server (server.yml) has the following:
user-header: x-forwarded-user
Then a request reaching ntfy with
POST /mytopic HTTP/1.1
Host: ntfy.sh
x-forwarded-user: ngerstle
Backup successful
would be trusted to be made by the user ngerstle.
Authorization, and user management (excepting possible changes around passwords, if desired), would not change.
This would allow any number of different authentication options for access (depending on client support), ranging from the presently implemented basic, to LDAP, OIDC, OAuth2, JWT, mTLS, etc. Options for proxies are numerous, and include (among others):
If a dependency on a proxy is an acceptable requirement for authentication, then existing password storage and validation code could be removed entirely.
Client support for different authentication forms would vary, but differences already exist between client support for different features (streams, for example). The selection of authentication mechanism(s) can be left to administrators, and they would need to evaluate which clients support what forms of authentication. Ideally, all clients support all forms of authentication, but applications can add support independently, and as there is interest once reverse proxies are supported. I would suggest adding mTLS/OIDC/OAuth2 to the Android/iOS apps; most programming languages have support for acquiring credentials based on common authentication flows, and if there are custom tools built I'd suggest using standard libraries.
Open question: I defer on whether it should be possible to enable multiple forms of authentication at a time.
- There is the option to allow both forms of user determination to function concurrently (prioritizing the configured header if present ahead of/behind basic auth?), or making the two options mutually exclusive. Mutually exclusive authentication is easier to reason about, but makes migration between forms harder, and can result in users being locked out (if no admin user exists/can be authenticated to, though this may be a risk in any case).
I do want to compliment the project- barring some typos while switching reverse proxies, I was able to start hosting ntfy remarkably quickly, and have found it easy to use- thanks for the contribution to the opensource ecosystem!
I do not have the time to fully answer, but I do like this idea, and the WIP implementation doesn't look half bad.
It is worth noting that Android/iOS/web client also need to support whatever you are implementing, which may makes things a lot trickier.
Also: Implementing anything on top of main right now is not a good idea. I have been working on the user-account branch for over a month now, so it may be a good idea to re-base (re-implement) on top of that.
On reflection, as long as the topic and operation are easily extracted from the request in a generic fashion, perhaps handling authorization external to ntfy is simpler.
It seems as though ("Publish as JSON" aside), the topic is always in the url; and the action (publish/subscribe) can be determined by http method (and url, in the case of webhooks)- if this is the case, then rules in a reverse proxy can handle a fair bit of the work, with significant flexibility (mTLS + OPA, client support aside).
It seems like there's quite a bit of work in the user-account branch, and while I see work towards token based auth, the change is significant enough that I think I'll defer future work on https://github.com/binwiederhier/ntfy/pull/602 until you've completed the user-account work.
I do think the user-account branch is very close to completeness. Structurally nothing big will change. But if you'd like to wait a few days until I merge I understand.
I do not think that handling authorization should be done outside of ntfy. authn is easy to outsource to another app, but authz is really really bound to an application usually, because it depends on resources (topics).
FYI the user-account branch is merged.
FYI the user-account branch is merged.
Is there any documentation? I don't find anything from: https://github.com/binwiederhier/ntfy/pull/602
@helmut72 hi, were you able to find any?