Skip to content

zzantares/dotfiles

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

README

Installation

First, install Nix, then:

$ nix shell nixpkgs#git nixpkgs#home-manager
$ git clone <this repo>
$ home-manager --switch --extra-experimental-features "nix-command flakes" init --flake .#

The --impure flag might need to be given as well. The above instructions are only for the very first time using this.

Repository structure

  • config/: contains stuff that should be placed under ~/.config but without using the HM way of doing things.
  • legacy/: contains scripts and configurations of tools used in the past, not used by any configuration at the moment but that might be useful if I decide to start using them again.
  • nix/: all nix code organized on this directory, home-manager and nixos configuration live here.
  • resources/: mainly icons and fonts, I could add also wallpapers or other stuff here in the future.
  • secrets/: declares encrypted secrets using sops integrated into the configuration with sops-nix.

Secrets management

There are two solutions in place to manage secrets, whenever possible sops is recommended.

Managing secrets with sops

This approach only works for programs that need a secret at run-time provided via CLI arguments, configuration files or environment variables, if you need a secret to pass into a nix option somewhere (e.g. kagi search token configured by url using nix) then using sops won’t work (easily), for those cases you can look into nix run nixpkgs#sops -- secrets/<profile>/secrets.yaml

Note that adding or removing keys into the .sops.yaml file requires re-encrypting the secrets file, so one might need to edit it even though we do no wish to change its contents just trigger re-encryption of the secrets in the file.

On the nix side, secrets have to be “declared” under the sops.secrets option, see jgutierrez/secrets.nix for an example on how to declare and access secrets. The important think is that the attribute name declaring the secret must match the key of that secret used in the secrets/<profile>/secrets.yaml file to be mapped correctly.

That module also contains an example on how to use the secrets to source them into environment variables, note that using home.sessionVariables won’t work because when the configuration is evaluated the file containing the secret value isn’t available yet and even if it was the secret would then leak into the /nix/store because in that case it would be used as the value to a Nix option meaning it would end-up rendered in plain text in the derivation that builds our shell environment.

In order to start using this mechanism:

  1. Add your encryption GPG key ID under keys in the .sops.yaml configuration file. And refer to it in the list of key_groups.pgp keys under the creation_rules section.
  2. Create your secrets file in secrets/<your profile>/secrets.yaml using sops as instructed above.
  3. Add the secret as an object, that is a YAML key value pair, just remember only the value will be encrypted so do not include sensitive data as part of the key.
  4. Declare your secrets in your Home-Manager configuration under the sops.secrets option.
  5. The secret will be decrypted and written to a file at run-time, the path to this file is under the config.sops.secrets.<declared secret>.path option. Make your program read the secret from there or load it to an environment variable accordingly.

The above will work provided that your configuration imports the workstation or minimal configuration modules these include the presets/sops preset which configures Home-Manager appropriately.

Managing sensitive values with nix-plugins’s extra-builtins-file mechanism

Nix itself is configured by home-manager with the following options set:

{
  nix.settings = {
    # The `nix-plugins` package makes nix configuration to expose a new `extra-builtins-file` setting
    plugin-files = "${pkgs.nix-plugins}/lib/nix/plugins";
    # After the plugin is bootstraped this option is visible and we add "extra" builtins to our nix
    extra-builtins-file = "${inputs.self}/nix/extra-builtins.nix";
  };
}

By using nix-plugins we’re able to use the exec function to do impure things during evaluation time (see nix/extra-builtins.nix and nix/decrypt.sh), such as decrypting a GPG secrets file in secrets/<profile>/sensitive.nix.gpg. When using this we must be very careful to not break Nix’s assumptions (immutability, observable side-effects, etc).

This is loaded in a sensitive attribute for every profile in the flake.nix using:

sensitive = builtins.extraBuiltins.readEncrypted ./secrets/<profile>/sensitive.nix.gpg;

Any profile has this sensitive attribute set in scope, so sensitive values can be accessed by attribute, e.g. profile.sensitive.kagiAuthToken.

Note that the sensitive.nix.gpg file needs to be decrypted and re-encrypted if one adds a new key to the gpg keyring (in case multiple machines with different keys have to access sensitive values under the same profile). Albeit in that case it would be simpler to use different profiles per machine.

Also note that values stored in this way are not really secrets, they are decrypted at evaluation time and injected into some nix expression which stores them as plain text somewhere in the /nix/store as part of the derivation that needs them. If this is a concern look at the approach described above which doesn’t have this shortcomings Managing secrets with =sops= .

Note that in order to bootstrap this mechanism into a configuration that attempts to use this for the first time it is necessary to apply the configuration twice, first to load the nix plugin and a second time to load the extra-builtins-file option values. Only then we should refer to a sensitive value within our configuration, doing it any sooner will result in an error as that would mean that either the plugin hasn’t been loaded or if the plugin has been loaded then the extra-builtins haven’t been defined yet.

So to setup this for the first time:

  1. Make sure you have a GPG encryption key loaded into your keyring, i.e. gpg --list-secret-keys.
  2. Add your GPG encrypted sensitive file in secrets/<profile>/sensitive.nix.gpg it can be created with standard GPG options or use Emacs support for GPG files (which triggers when editing files with the .gpg extension). The file must be a Nix attribute set of key value pairs.
  3. Activate your configuration to install and configure the necessary nix-plugins so that your nix.conf file has the plugin-files setting enabled.
  4. Activate your configuration a second time to enable the necessary extra-builtins (like readEncrypted), this would only work if the nix-plugins are loaded by the previous step.
  5. Finally refer to sensitive values within your configuration, these would be available under the profile.sensitive option, i.e. profile.sensitive.bank_account.

It may be possible that unknowingly you have applied the Nix configuration multiple times before without actually declaring senstive values, in that case most-likely you can skip the double activation, to ensure this is the case it is enough to inspect the nix.conf file and see if the extra-builtins option is there.

Notes

Tridactyl on Firefox & Librewolf

Browser extension settings aren’t declared in the configuration (yet) these are sometimes lost, it is suggested to evaluate the following tridactyl settings to restore familiar bindings for colemak users:

:unbindurl youtube\.com/watch\?v=.* f
:unbindurl youtube\.com/watch\?v=.* j
:unbindurl youtube\.com/watch\?v=.* l
:unbindurl lichess.org f
:bind k scrollline 10
:bind h scrollline -10
:bind j scrollpx -50
:bind l scrollpx 50
:bind J tabprev
:bind L tabnext
:bind H forward
:bind K back

CONTRIBUTING guidelines

  • Make sure code is properly formatted: nix fmt.
  • Make sure configuration checks are green: nix flake check.

About

dot files for sharing among workstations

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published