LnL7 / nix-darwin

nix modules for darwin
MIT License
2.82k stars 431 forks source link

Overhaul user management #1017

Open dlubawy opened 2 months ago

dlubawy commented 2 months ago

This PR is related to issues #554 and #96. I've opened this more as discussion around possibilities rather than as a request to actually merge the code. There are a few problems I see with nix-darwin around user management. Using numbers for reference later, these problems are:

  1. No options to configure users as admin, system, or token users
    • New Macs and Nix installs use FileVault. dscl user management does not work for this as new users created will not be able to use FDE and so will be unable to login on reboot
    • dscl is an older (maybe arguably deprecated) tool for creating new users. New users created this way will lack specific metadata that prevents certain user management actions in System Settings such as profile picture selection and other odd behavior
    • dscl requires careful tracking of reserved UIDs/GIDs which can change between OS upgrades or other operations
  2. Missing options to set passwords
  3. Configured users/groups need an additional config option knownUsers/knownGroups in order to actually be managed by nix-darwin
    • This adds code duplication and a layer of confusing abstraction that diverges from NixOS; "If a user is configured isn't it already known?".
    • "Used to indicate what users are safe to create/delete based on the configuration. "; There is no mention if this option can do other things to those configured+unknown users/groups
    • Makes for a strange workflow that mixes mutable and immutable user management schemes (very different from NixOS)

The edits I made tackled these problems in the following manner (each numbered point corresponding to the problem with the same number):

  1. Add these as configuration options; move from dscl to sysadminctl commands
    • isNormalUser: normal user according to macOS (i.e. UID > 500)
    • isAdminUser: adds the user to the admin group
    • isSystemUser: configure system user according to macOS (i.e. 200 <= UID <= 400)
    • isTokenUser: configure the user for FDE by having an admin with a secure token add a token to this user
  2. Add these as configuration options; use sysadminctl to perform user changes
    • password: behaves like NixOS option; password is only changes when users are immutable
    • initialPassword: equivalent to password when users are immutable; otherwise sets the initial password when a user is first created
  3. Remove knownUsers/knownGroups in favor of NixOS users.mutableUsers flag
    • Adds a NixDeclarative attribute with dscl to track which users/groups are managed
    • If users are mutable then nothing should change, otherwise users with the NixDeclarative attribute are modified according to configs

This isn't a perfect approach to things as isTokenUser needs an admin user with a secure token to be able to enter their password as well as the user requiring the change to do the same, but in combination with the mutableUsers and password options this could be mitigated on new system builds by pulling the password from the config.

It's my intention with these changes to have a system whereby I can more easily manage an admin user (which runs nix-darwin and manages homebrew through it) and a normal user (for daily use) that can run sudo -Hu admin darwin-rebuild (because running as root is broken right now). This is typically how systems should be configured in macOS where running admin as a daily user goes against best practices according to Apple. I've been using this code in my personal system configuration and it has achieved that for me. Hopefully, this can be of use to others as well.

emilazy commented 2 months ago

Thanks for this. Your changes absolutely seem directionally correct and I think we’re basically in complete agreement on what the ideal end‐state for nix-darwin looks like.

However, there are considerations to make in terms of the migration path for the inevitable breaking changes it would involve, and the best way to move things over smoothly without disrupting users’ setups multiple times along the way. I’ve been meaning to start tackling this for a long while now and it’s on me for not having written down my thoughts and plans in details, so I’m sorry about that! I really appreciate you taking the initiative on this work and it would be great to work with you on gradually moving towards a setup where nix-darwin exclusively manages the system, darwin-rebuild is always run as root, multiple‐user setups work in a reasonable way, we don’t duplicate work that better belongs in Home Manager, and so on.

I have a lot on my stack right now and my availability isn’t perfect, but if I don’t get around to replying again with my blueprint for what I think we should do here in a couple days please feel free to ping me.

dlubawy commented 1 month ago

@emilazy if you can manage it, I would love to hear the blueprint and maybe help out to achieve a better experience in this space. No worries if you are still too busy.

emilazy commented 1 month ago

Sorry for the delayed reply; I will try to get back to this ASAP.

emilazy commented 1 month ago

I’ve replied in https://github.com/LnL7/nix-darwin/pull/1016 instead as it is more directly related to what I talk about there. This PR actually seems like it probably has no conflicts with any of that work and might just be totally fine as‐is; thank you for doing the work! I’ll have to give it a proper review some other time, though, since I just spent like five years writing up the big plan :)

dlubawy commented 1 month ago

I responded in #1016 and closed it as a PR. That was a great comment, and I'm looking forward to those changes!

Back on this PR. This is definitely a separate topic, but it is in the same spirit of improving multi-user support on nix-darwin. I would greatly appreciate a good review on the changes and ideas I propose here. Ultimately my intention is to bring some parity to user management between nix-darwin and NixOS. I think I was pretty heavy handed in some aspects here so a review by someone more seasoned in nix-darwin is highly valuable, especially to determine better approaches for backwards compatibility. I would also greatly appreciate some feedback on the ideas I put out around the notion of admins, token users, and removal of knownUsers.

emilazy commented 3 weeks ago

Sorry for the delay; I’ve been busy lately but I’ll try to get around to reviewing this soon because we are going to need to do stuff with user management within the next couple weeks to handle the _nixbld* UID clashes in the upcoming macOS Sequoia upgrade.

Do you know if this will handle, or could easily be made to handle, changing the UID and GID of existing users and groups? I am hoping we can effectively implement https://github.com/NixOS/nix/pull/11075 just by changing the IDs we assign for those users.