[GH-ISSUE #464] Feature request: Allow specifying users and ACLs declaratively #354

Closed
opened 2026-05-07 00:23:22 +02:00 by BreizhHardware · 17 comments

Originally created by @pinpox on GitHub (Nov 3, 2022).
Original GitHub issue: https://github.com/binwiederhier/ntfy/issues/464

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.
Originally created by @pinpox on GitHub (Nov 3, 2022). Original GitHub issue: https://github.com/binwiederhier/ntfy/issues/464 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](https://github.com/pinpox/nixos/blob/67e6ba4560cb712bd7f62632ded3b1b2b10a85d8/modules/ntfy-sh/default.nix#L19-L55). 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.
BreizhHardware 2026-05-07 00:23:22 +02:00
Author
Owner

@binwiederhier commented on GitHub (Nov 7, 2022):

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.

<!-- gh-comment-id:1305712248 --> @binwiederhier commented on GitHub (Nov 7, 2022): I think that's a fair feature request. I think adding a section in the server.yml would be easy enough. ``` yaml 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.
Author
Owner

@pinpox commented on GitHub (Nov 7, 2022):

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

<!-- gh-comment-id:1306054079 --> @pinpox commented on GitHub (Nov 7, 2022): > 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 ```yaml 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`
Author
Owner

@agustinmista commented on GitHub (Nov 9, 2022):

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
<!-- gh-comment-id:1309358365 --> @agustinmista commented on GitHub (Nov 9, 2022): 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 ```
Author
Owner

@pinpox commented on GitHub (Nov 16, 2022):

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.

<!-- gh-comment-id:1316609034 --> @pinpox commented on GitHub (Nov 16, 2022): Since ntfy already has a module for [configuring it in NixOS](https://github.com/NixOS/nixpkgs/blob/nixos-unstable/nixos/modules/services/misc/ntfy-sh.nix), I can offer to extend that with ACL settings upstream when this issue is implemented.
Author
Owner

@binwiederhier commented on GitHub (Nov 20, 2022):

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?
<!-- gh-comment-id:1321012724 --> @binwiederhier commented on GitHub (Nov 20, 2022): 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): ``` yaml 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?
Author
Owner

@daedric7 commented on GitHub (Nov 20, 2022):

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.

<!-- gh-comment-id:1321013812 --> @daedric7 commented on GitHub (Nov 20, 2022): 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.
Author
Owner

@pinpox commented on GitHub (Dec 7, 2022):

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.

<!-- gh-comment-id:1341277509 --> @pinpox commented on GitHub (Dec 7, 2022): 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.
Author
Owner

@macgregor commented on GitHub (Jul 1, 2023):

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.

<!-- gh-comment-id:1616078309 --> @macgregor commented on GitHub (Jul 1, 2023): 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.
Author
Owner

@binwiederhier commented on GitHub (Jul 2, 2023):

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.

<!-- gh-comment-id:1616767552 --> @binwiederhier commented on GitHub (Jul 2, 2023): > 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.
Author
Owner

@macgregor commented on GitHub (Jul 3, 2023):

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!

<!-- gh-comment-id:1618674774 --> @macgregor commented on GitHub (Jul 3, 2023): 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!
Author
Owner

@pinpox commented on GitHub (Jul 4, 2023):

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.

<!-- gh-comment-id:1619840670 --> @pinpox commented on GitHub (Jul 4, 2023): > 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.
Author
Owner

@weirlive commented on GitHub (Oct 4, 2023):

is there an update to this?

<!-- gh-comment-id:1746897918 --> @weirlive commented on GitHub (Oct 4, 2023): is there an update to this?
Author
Owner

@wunter8 commented on GitHub (Oct 4, 2023):

Nothing yet

<!-- gh-comment-id:1746959628 --> @wunter8 commented on GitHub (Oct 4, 2023): Nothing yet
Author
Owner

@fudini commented on GitHub (Jul 7, 2025):

I think the closest to declarative configuration would be a bash file that is just a list of commands, but there is no option (afaik) to specify token using ntfy access command and that makes it difficult.

<!-- gh-comment-id:3044115384 --> @fudini commented on GitHub (Jul 7, 2025): I think the closest to declarative configuration would be a bash file that is just a list of commands, but there is no option (afaik) to specify token using `ntfy access` command and that makes it difficult.
Author
Owner

@binwiederhier commented on GitHub (Jul 7, 2025):

^^ The lack of declarative users has personally bugged me too, maybe I'll do that after IPv6 support. No promises

<!-- gh-comment-id:3044150270 --> @binwiederhier commented on GitHub (Jul 7, 2025): ^^ The lack of declarative users has personally bugged me too, maybe I'll do that after IPv6 support. No promises
Author
Owner

@binwiederhier commented on GitHub (Jul 27, 2025):

Only took 3 years, lol -- https://github.com/binwiederhier/ntfy/pull/1384

It's done and documented; though I may add auth-tokens too since that's what people will ask for next. I won't add auth-tiers though, because the format will be ridiculous. I kinda wish that ENV variables weren't a thing. They are so dumb for configuration files...

<!-- gh-comment-id:3124491116 --> @binwiederhier commented on GitHub (Jul 27, 2025): Only took 3 years, lol -- https://github.com/binwiederhier/ntfy/pull/1384 It's done and documented; though I may add `auth-tokens` too since that's what people will ask for next. I won't add `auth-tiers` though, because the format will be ridiculous. I kinda wish that ENV variables weren't a thing. They are so dumb for configuration files...
Author
Owner

@binwiederhier commented on GitHub (Aug 9, 2025):

This has been released as v2.14.0

<!-- gh-comment-id:3170614825 --> @binwiederhier commented on GitHub (Aug 9, 2025): This has been released as v2.14.0
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/ntfy#354
No description provided.