jordanisaacs / homeage Goto Github PK
View Code? Open in Web Editor NEWruntime decrypted age secrets for nix home manager
License: MIT License
runtime decrypted age secrets for nix home manager
License: MIT License
Currently all symbolic links that point to the /run
secrets folder do not get cleaned up. Also decrypted secrets in /run
are not deleted. Need a cleanup solution that removes old symbolic links. This also enables copying as the files can be cleaned up.
Run a cleanup script on activation. See PR for how it works.
Should perform checks so it fails before applying if anything is wrong. Checks to perform:
activationMount
/startupMount
if needed.Files do not appear until reboot. Is this intended behavior? I think it would make sense to comment on this in the README?
Hi there!
Thanks for this project, I'm trying to add support for the rage YubiKey plugin.
What I've tried so far:
home.nix
configuration:
{
homeage = {
pkg = pkgs.rage;
identityPaths = [ "${config.home.homeDirectory}/yubikey.txt" ];
installationType = "activation";
file."test" = {
source = ./data.age;
symlinks = [ "${config.xdg.configHome}/secret" ];
};
};
# ...other config
}
Create the secret data & create ~/yubikey.txt
:
echo "foobar" | rage -i ~/yubikey.txt -e > ~/.config/nixpkgs/data.age
age-plugin-yubikey -i > ~/yubikey.txt
Changes to homeage itself:
diff --git a/homeage/default.nix b/homeage/default.nix
index 45b2ea8..df9130a 100644
--- a/homeage/default.nix
+++ b/homeage/default.nix
@@ -37,7 +37,16 @@ with lib; let
}: let
linksCmds = createFiles "ln -sf" path symlinks;
copiesCmds = createFiles "cp -f" path copies;
+ yubikeyPlugin = pkgs.age-plugin-yubikey + "/bin";
+ pinentry = pkgs.pinentry-gtk2 + "/bin";
+ identity = builtins.head cfg.identityPaths;
in ''
+ PATH="${yubikeyPlugin}:${pinentry}:$PATH"
+ echo "GETTING IDENTITY FILE CONTENT:"
+ cat ${identity}
+ echo "IDENTITIES PROVIDED: ${identities}"
+ echo "YUBIKEYS CONNECTED:"
+ age-plugin-yubikey -l
echo "Decrypting secret ${source} to ${path}"
TMP_FILE="${path}.tmp"
$DRY_RUN_CMD mkdir $VERBOSE_ARG -p $(dirname ${path})
I added in pinentry-gtk2
after finding str4d/rage#280 and assuming that home.activation
is unable to open pinentry-curses.
I'm logging the identity file content, identities provided, and yubikeys connected really only as sanity checks, which produces an output like this:
On an unrelated note, on macOS I'm getting an error mounting the secret tmpfs:
Edit: just learned about homeage.mount
, my bad.
Add option to use script instead of systemd for startup secret decryption.
Waiting on v0.1 stabilization of option set and writing checks/cleanup.
Call the script on login using a oneshot systemd service. Inspiration from: https://christine.website/blog/nixos-encrypted-secrets-2021-01-20.
Allow for choosing between startup and activation decrypted secrets. Goes along with tmpfs/ramfs mounted secrets vs disk mounted secrets.
error: Found argument '-d' which wasn't expected, or isn't valid in this context
If you tried to supply '-d' as a value rather than a flag, use '-- -d'
Usage: ragenix [OPTIONS] <--edit <FILE>|--rekey|--schema>
For more information try '--help'
Neither ragenix
nor agenix
have a -d
option, perhaps -i
?
https://github.com/jordanisaacs/homeage/blob/main/module/default.nix#L269
Unfortunately, the change in #4 prevented users on MacOS from using this tool on those machines going forward, as we do not have access to systemd or a useful-parity replacement, even with nix-darwin
in play. Can you recommend any compatible alternatives that are not systemd-based, and/or would you be interested in including that support here?
Some services don't allow the use of symlinked files. Therefore they need to be copied.
Single option called copies
that takes a list of paths. Depending on the installation type it will be copied on activation or when the systemd unit runs. If cleanup is enabled they are attempted to be deleted.
I just noticed #31 introduced a regression when running homeage
as a service, symlinks are no longer created on startup. Haven't had time to investigate yet, I simply reverted to the previous commit for now.
I only have a Github token as a secret and the symlink is not being created when activating new HM builds.
let secrets = { pkgs, config, ... }: {
homeage = {
identityPaths = [ "~/.ssh/id_ed25519" ];
pkg = pkgs.rage;
file."github-token" = {
source = ./github.age;
path = "github-notifications-token";
symlinks = [ "${config.xdg.configHome}/secrets/github" ];
};
};
};
in [ secrets ]
What I see:
Starting Home Manager activation
Activating checkFilesChanged
Activating checkLinkTargets
Activating homeageDecryptCheck
Enter passphrase for "/home/jacob/.ssh/id_ed25519":
Activating writeBoundary
Activating linkGeneration
Cleaning up orphan links from /home/jacob
Creating profile generation 1235
Creating home file links in /home/jacob
Activating createXdgUserDirectories
Activating installPackages
replacing old 'home-manager-path'
installing 'home-manager-path'
Activating dconfSettings
Activating homeageCleanup
/nix/store/indhsz7vhjnfdj8kb6hnsrsbq8rmxmgj-home-manager-generation/activate: line 279: jq: command not found
The problem:
https://gist.github.com/spikespaz/ef2cfe46f4e3978e599ac76a6bbebf9d#file-activate-sh-L279
Source:
https://github.com/jordanisaacs/homeage/blob/main/module/default.nix#L141
I am not sure what needs to be done to add jq
to the dependencies of the activation script.
Looks like te activation fails with recent versions of nix/nixpkgs as jq doesn't offer the argument argfile anymore:
× home-manager-thomas.service - Home Manager environment for thomas
Loaded: loaded (/etc/systemd/system/home-manager-thomas.service; enabled; preset: enabled)
Active: failed (Result: exit-code) since Mon 2024-07-01 22:21:59 CEST; 2min 6s ago
Process: 57630 ExecStart=/nix/store/cv17kn1r2d7im3bjkj4qca1ig0myn3s2-hm-setup-env /nix/store/9zfm91hda4fxsl5rnr91vbnhcr2pz9j2-home-manager-generation (code=exited, status=2)
Main PID: 57630 (code=exited, status=2)
IP: 0B in, 0B out
CPU: 1.633s
Jul 01 22:21:59 chnum hm-activate-thomas[57630]: Activating writeBoundary
Jul 01 22:21:59 chnum hm-activate-thomas[57630]: Activating createGpgHomedir
Jul 01 22:21:59 chnum hm-activate-thomas[57630]: Activating homeageCleanup
Jul 01 22:21:59 chnum hm-activate-thomas[58525]: /nix/store/43x59xa6fidzd9jys7jvhv66bjfjm4cp-jq-1.7.1-bin/bin/jq: Unknown option --argfile
Jul 01 22:21:59 chnum hm-activate-thomas[58525]: Use /nix/store/43x59xa6fidzd9jys7jvhv66bjfjm4cp-jq-1.7.1-bin/bin/jq --help for help with command-line options,
Jul 01 22:21:59 chnum hm-activate-thomas[58525]: or see the jq manpage, or online docs at https://jqlang.github.io/jq
Jul 01 22:21:59 chnum systemd[1]: home-manager-thomas.service: Main process exited, code=exited, status=2/INVALIDARGUMENT
Jul 01 22:21:59 chnum systemd[1]: home-manager-thomas.service: Failed with result 'exit-code'.
Jul 01 22:21:59 chnum systemd[1]: Failed to start Home Manager environment for thomas.
Looking at the commit history I guess this project is not really maintained anymore?
Option to encrypt file at build time using a public key. This allows for non encrypted files to be encrypted in the nix store.
Hey, I set up my NixOS system with home-manager as NixOS module. Therefore, the activation script will run inside a systemd service that also runs on system boot. During that phase I get the following error:
Activating homeage
Decrypting secret /nix/store/<path>.age to /run/user/1000/secrets/<path>
mkdir: cannot create directory ‘/run/user/1000’: Permission denied
It looks like the directory was not created yet. I don't know how and when this directory is created (hopefully a system service) than home-manager should specify that as dependency for its systemd service.
The title says it all. There should be a way to remove every via hm deployed secret that is not in the current generation. Otherwise the system could end up in a non reproducible state.
agenix has the same issue as mentioned in my ryantm/agenix#27 (comment).
I see this for some reason:
error: The option `homeage.file' in `/nix/store/8zj2n61ialjsqbjk7i15pci0py12n46h-source/users/jacob/profile.nix' is already declared in `/nix/store/8zj2n61ialjsqbjk7i15pci0py12n46h-source/users/jacob/profile.nix'.
This is funny because that file does not contain that attrkey.
profile.nix
homeage.pkg = pkgs.ragenix;
homeage.mount = "${config.home.homeDirectory}/.secrets";
homeage.identityPaths = [
"~/.ssh/id_ed25519"
];
{
config,
pkgs,
lib,
hmModules,
...
}: {
imports = [hmModules.homeage];
homeage.file."spotifyd" = {
source = ./jacob.spotifyd.age;
};
services.spotifyd = {
# enable = true;
package = pkgs.spotifyd.override {
withKeyring = true;
withMpris = true;
withPulseAudio = true;
};
settings = {
global = {
backend = "pulseaudio";
bitrate = 320;
use_mpris = true;
username = "[email protected]";
password_cmd = "cat '${config.homeage.mount}/jacob.spotifyd.age'";
};
};
};
home.packages = with pkgs; [
config.services.spotifyd.package
# spotify-tui
spotify-qt
];
xdg.configFile."spotifyd/spotifyd.conf".source = (
(pkgs.formats.toml {}).generate
"spotifyd.conf"
config.services.spotifyd.settings
);
}
Would it be possible for you to add a minimal example of the secrets flake you use in your own dotfiles? I can't seem to replicate your setup.
Giving homeage
a try, I noticed the decryption command fails when using rage
and only succeeds when using age
. So basically setting homeage.isRage = true;
would always fail, at least when having one or more symlinks.
I looked into the script and I don't see much wrong with the command, perhaps you get an idea?
Here's the log:
× github-notifications-token-secret.service - Decrypt github-notifications-token secret
Loaded: loaded (/home/gvolpe/.config/systemd/user/github-notifications-token-secret.service; enabled; preset: enabled)
Active: failed (Result: exit-code) since Fri 2022-09-09 14:34:03 CEST; 1min 38s ago
Process: 1122308 ExecStart=/nix/store/v6cbpfzxixvsp63wdw6pkk1rgcn1cx4z-github-notifications-token-decrypt (code=exited, status=127)
Main PID: 1122308 (code=exited, status=127)
CPU: 6ms
Sep 09 14:34:03 tongfang-amd systemd[1937]: Starting Decrypt github-notifications-token secret...
Sep 09 14:34:03 tongfang-amd v6cbpfzxixvsp63wdw6pkk1rgcn1cx4z-github-notifications-token-decrypt[1122308]: Decrypting secret /nix/store/5v64cvw535zd3rvcks0q1r561xcbzwin-github.age to /run/user/1000/secrets/github-notifications-token
Sep 09 14:34:03 tongfang-amd systemd[1937]: github-notifications-token-secret.service: Main process exited, code=exited, status=127/n/a
Sep 09 14:34:03 tongfang-amd systemd[1937]: github-notifications-token-secret.service: Failed with result 'exit-code'.
Sep 09 14:34:03 tongfang-amd systemd[1937]: Failed to start Decrypt github-notifications-token secret.
Hey, maybe a stupid question but why are the secrets saved to /run/user/$UID/secrets
per defaullt? If they would be saved in the home directory like ${XDG_DATA_DIR:-~/.local/share}/secrets
there would be no need of systemd services because the secrets will remain there after reboots..
Copy pasting and trying to build a vm based on the example:
$ cat flake.nix && nixos-rebuild build-vm --flake .#jd
{
inputs = {
nixpkgs.url = "nixpkgs/nixos-unstable";
home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
homeage = {
url = "github:jordanisaacs/homeage";
# Optional
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { nixpkgs, homeage, ... }@inputs:
let
pkgs = import nixpkgs {
inherit system;
};
system = "x86_64-linux";
username = "jd";
stateVersion = "21.05";
in {
homeManagerConfigurations = {
jd = home-manager.lib.homeManagerConfiguration {
inherit system stateVersion username pkgs;
home.homeDirectory = "/home/${username}";
configuration = {
home.stateVersion = stateVersion;
home.username = username;
home.homeDirectory = "/home/${username}";
# CHECK HERE for homeage configuration
homeage.identityPaths = [ "~/.ssh/id_ed25519" ];
homeage.file."pijulsecretkey" = {
source = ./secretkey.json.age;
path = "pijul/secretkey.json";
# symlinks = [ "${config.xdg.configHome}/pijul/secretkey.json" ];
};
imports = [ homeage.homeManagerModules.homeage ];
};
};
};
};
}
building the system configuration...
warning: Git tree '/home/ParetoOptimalDev/org-roam' is dirty
error: undefined variable 'home-manager'
at /nix/store/rwl24js4s3gjha7cf7bi8dhvh3xywagb-source/data/fd/95465e-2846-4a45-8359-15212d2a8df1/example-homeage/flake.nix:26:14:
25| homeManagerConfigurations = {
26| jd = home-manager.lib.homeManagerConfiguration {
| ^
27| inherit system stateVersion username pkgs;
Error from full run above:
error: undefined variable 'home-manager'
at /nix/store/rwl24js4s3gjha7cf7bi8dhvh3xywagb-source/data/fd/95465e-2846-4a45-8359-15212d2a8df1/example-homeage/flake.nix:26:14:
25| homeManagerConfigurations = {
26| jd = home-manager.lib.homeManagerConfiguration {
| ^
27| inherit system stateVersion username pkgs;
I think the fix here is to add home-manager
to outputs like this:
- outputs = { nixpkgs, homeage, ... }@inputs:
+ outputs = { nixpkgs, home-manager, homeage, ... }@inputs:
Here's a run with that change below, but it uncovers another error:
$ cat flake.nix && nixos-rebuild build-vm --flake .#jd
{
inputs = {
nixpkgs.url = "nixpkgs/nixos-unstable";
home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
homeage = {
url = "github:jordanisaacs/homeage";
# Optional
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { nixpkgs, home-manager, homeage, ... }@inputs:
let
pkgs = import nixpkgs {
inherit system;
};
system = "x86_64-linux";
username = "jd";
stateVersion = "21.05";
in {
homeManagerConfigurations = {
jd = home-manager.lib.homeManagerConfiguration {
inherit system stateVersion username pkgs;
home.homeDirectory = "/home/${username}";
configuration = {
home.stateVersion = stateVersion;
home.username = username;
home.homeDirectory = "/home/${username}";
# CHECK HERE for homeage configuration
homeage.identityPaths = [ "~/.ssh/id_ed25519" ];
homeage.file."pijulsecretkey" = {
source = ./secretkey.json.age;
path = "pijul/secretkey.json";
# symlinks = [ "${config.xdg.configHome}/pijul/secretkey.json" ];
};
imports = [ homeage.homeManagerModules.homeage ];
};
};
};
};
}
building the system configuration...
warning: Git tree '/home/ParetoOptimalDev/org-roam' is dirty
error: flake 'git+file:///home/ParetoOptimalDev/org-roam?dir=data%2ffd%2f95465e-2846-4a45-8359-15212d2a8df1%2fexample-homeage' does not provide attribute 'packages.x86_64-linux.nixosConfigurations."jd".config.system.build.vm', 'legacyPackages.x86_64-linux.nixosConfigurations."jd".config.system.build.vm' or 'nixosConfigurations."jd".config.system.build.vm'
Error from full run above:
building the system configuration...
warning: Git tree '/home/ParetoOptimalDev/org-roam' is dirty
error: flake 'git+file:///home/ParetoOptimalDev/org-roam?dir=data%2ffd%2f95465e-2846-4a45-8359-15212d2a8df1%2fexample-homeage'
does not provide attribute 'packages.x86_64-linux.nixosConfigurations."jd".config.system.build.vm', 'legacyPackages.x86_64-linux.nixosConfigurations."jd".config.system.build.vm' or 'nixosConfigurations."jd".config.system.build.vm'
And indeed, using nix flake show
I can see there is no such configuration:
$ nix flake show
warning: Git tree '/home/ParetoOptimalDev/org-roam' is dirty
git+file:///home/ParetoOptimalDev/org-roam?dir=data%2ffd%2f95465e-2846-4a45-8359-15212d2a8df1%2fexample-homeage
└───homeManagerConfigurations: unknown
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.