ntfy icon indicating copy to clipboard operation
ntfy copied to clipboard

Feature request: Allow specifying users and ACLs declaratively

Open pinpox opened this issue 2 years ago • 7 comments

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 and access... 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.

pinpox avatar Nov 03 '22 15:11 pinpox

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.

binwiederhier avatar Nov 07 '22 14:11 binwiederhier

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

pinpox avatar Nov 07 '22 19:11 pinpox

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

agustinmista avatar Nov 09 '22 20:11 agustinmista

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.

pinpox avatar Nov 16 '22 08:11 pinpox

I was gonna "quickly" implement this, but I stumbled over two things:

  1. Would it be ok if auth-file and auth-users were alternatives instead of complements. Initially I was going to offer and auth-users yaml section in addition to the auth-file (= SQLite database), but that will be tricky to implement. Instead, I'd only allow either auth-users (declarative) or auth-file (db file).

  2. 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?

binwiederhier avatar Nov 20 '22 01:11 binwiederhier

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.

daedric7 avatar Nov 20 '22 02:11 daedric7

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.

pinpox avatar Dec 07 '22 16:12 pinpox

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 not sh 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.

macgregor avatar Jul 01 '23 20:07 macgregor

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.

binwiederhier avatar Jul 02 '23 18:07 binwiederhier

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!

macgregor avatar Jul 03 '23 15:07 macgregor

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.

pinpox avatar Jul 04 '23 09:07 pinpox

is there an update to this?

weirlive avatar Oct 04 '23 13:10 weirlive

Nothing yet

wunter8 avatar Oct 04 '23 14:10 wunter8