ntfy
ntfy copied to clipboard
Feature request: Allow specifying users and ACLs declaratively
Users and ACLs have currently to be set up imperatively using the ntfy user
and ntfy access
commands after ntfy is installed and running. It would be nice to be able to configure them declaratively, i.e. in a configuration file or environment variables that are read on startup.
Benefits:
- Fixed/predifined rights: You can always be sure the ACLs are set up correclty
- Backup of configuration. Currently the only possibility is backing up either the database itself or a SQL export
- Edit users and right externally
- Generate users/rights with scripts
- (Probably most importatnt for me) Ease of deployment: I deploy using on NixOS and define all configuration declaratively. The same applies if you deploy with tools like Ansible though. It would be great to just "drop" the user configuration during the deployment without having to log in and run all the
user add
andaccess...
commands by hand.
Possible implementations I can think of:
- Read users/acls from a config (e.g. yaml) file at start
- Read them from environment variables. This would also make the application more stateless and better suited for deployments with containers that are often thrown away and re-instantiated.
I think that's a fair feature request. I think adding a section in the server.yml would be easy enough.
base-url: ...
...
users:
phil:
role: ADMIN
password: $2y$... (bcrypt hash)
The only "issue" with this is that so far all options can be specified as CLI options, env variables OR in the server.yml. Nested structures like that may not be supported via the CLI library. I'd have to check.
may not be supported via the CLI library.
Maybe, but it wouldn't remove any existing functionality from the CLI.
Just another implementation detail, because I see you added a bcrypt hash: If possible, it would be great if values (especially the password) could be read from environment variables here, something like
users:
phil:
role: ADMIN
password: $ADMIN_PASS
That would make it easy to provide these secrets to the systemd unit's environment and not have them in the config, which might be versioned in a public git repository. Alternatively, the password could be read from a separate file with something like password_file: /var/lib/ntfy/secret-password.txt
This would be very handy! I'm hosting ntfy using the Docker image and the only way I found to set up user authentication was by attaching a shell to the running container:
docker exec -it ntfy /bin/sh
Since ntfy already has a module for configuring it in NixOS, I can offer to extend that with ACL settings upstream when this issue is implemented.
I was gonna "quickly" implement this, but I stumbled over two things:
-
Would it be ok if
auth-file
andauth-users
were alternatives instead of complements. Initially I was going to offer andauth-users
yaml section in addition to theauth-file
(= SQLite database), but that will be tricky to implement. Instead, I'd only allow eitherauth-users
(declarative) orauth-file
(db file). -
I am struggling to design the declarative design in such a way that it fits in environment variables and a yaml format. In yaml, it would look like this (or something similar):
auth-users:
- phil:
role: admin
password: "this is a plaintext password" # See alternative below
- ben:
# role: user # This is implied if omitted
password-hash: "$2y$10$abc.."
access:
- mytopic: rw
- announcements: write-only
- emma:
role: user
password-env: NTFY_PASSWORD_EMMA
access:
- mytopic: read-only
# My apologies for any "bad yaml". I don't know how to yaml.
``´
Now, how in the holy spaghetti monster's name do you encode this in environment variables?
I don't believe you can encode so many info with env variables, not in a elegant way.
I've seen users being defined, but its always a yaml file. The granularity you require would be prohibitive with env variables.
We have username, that can have a role, must have a password, then a random-lenght list of topics each with its permissions.
Maybe just create a env variable like AUTH_USERS_PATH
that points to that yaml file would be an option? If set, any modification of the configuration via the cli after the application has started should be prohibited.
here from the future to give a bump. User/ACL configuration is very awkward in a containerized installation where you dont have easy access to the "server" to run commands like "ntfy user add ..." So far I:
- looked for and failed to find a default admin user
- signed up a new user in browser, but couldnt change its roles or anything.
- Tried to connect to the running container but failed, I think because i exec'ed
bash
and notsh
but i wiped out the deployment so cant confirm - spent a few minutes trying to figure out how to add users/roles as an init container but only half heartedly
I'm only doing this for fun, so at this point I think I'm just going to check back on the project in a couple months.
User/ACL configuration is very awkward in a containerized installation
I agree with this. But there are other things that would need to be declarative, and it's not easy to combine declarative with command-driven user management. The world gets so much more complex when you have declarative users and can, e.g., also allow registration.
Plus, the CLI library does not allow nested yml structures at all, so that's a problem too.
Understood, just wanted to give a bump for the ever-more-containerized selfhosting landscape. For now I'm making due with ntfy.sh since I am not publishing anything remotely sensitive. I appreciate the service you're providing the open source community!
it's not easy to combine declarative with command-driven user management.
How about adding a parameter to just allow declarative users and disable cli-driven management? E.g. --users-from-file=./myusers.yml
could disable dynamic user management and set the acls and users to a fixed state.
is there an update to this?
Nothing yet