Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add darwin support #6

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
};

}) // {
nixosModules.default = import ./modules/op-secrets.nix;
darwinModules.default = import ./modules/darwin.nix;
nixosModules.default = import ./modules/nixos.nix;

# test is a hostname for our machine
nixosConfigurations.test = nixpkgs.lib.nixosSystem {
Expand Down
61 changes: 61 additions & 0 deletions modules/common.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{ lib, pkgs, config, ... }:
with lib;
let
inherit (import ./types.nix {
inherit lib;
inherit config;
})
secretFileDeclaration;
in {
options.opnix = {
opBin = mkOption {
type = types.str;
default = "${pkgs._1password-cli}/bin/op";
description = "The 1Password CLI `op` executable to use";
};
environmentFile = mkOption {
type = types.str;
description = ''
Path to a environment file which contains your service account token. Format should be `OP_SERVICE_ACCOUNT_TOKEN="{ your token here }"`. This is used to authorize the 1Password CLI.'';
};
secretsDir = mkOption {
type = types.path;
default = "/run/opnix";
description = ''
Directory where secrets are symlinked to
'';
};
secretsMountPoint = mkOption {
type = types.addCheck types.str (s:
(trim s) != "" # non-empty
&& (builtins.match ".+/" s) == null) # without trailing slash
// {
description =
"${types.str.description} (with check: non-empty without trailing slash)";
};
default = "/run/opnix.d";
};
secrets = mkOption {
type = types.attrsOf secretFileDeclaration;
description = "The secrets you want to use in your NixOS deployment";
default = { };
example = {
my-secret = {
source = "{{ op://VaultName/ItemName/FieldName }}";
mode = "0400";
inherit (config.services.some_service) user;
inherit (config.services.some_service) group;
};
another-secret.source = ''
[SomeTomlHeader]
SomeValue = "{{ op://AnotherVault/AnotherItem/AnotherField }}"
'';
};
};
debug = mkOption {
type = types.bool;
description = "Whether to enable debug logs";
default = false;
};
};
}
65 changes: 65 additions & 0 deletions modules/darwin.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
toplevel @ {
config,
lib,
pkgs,
...
}: let
inherit
(lib)
mkAfter
mkIf
mkMerge
;

cfg = config.opnix;
scripts = import ./scripts.nix toplevel;
in {
imports = [./common.nix];

config = let
opnixScript = ''
${scripts.installSecrets}
${scripts.chownSecrets}
'';
in
mkIf (cfg.secrets != {}) (mkMerge [
{
launchd.daemons.activate-opnix = {
script = ''
set -euo pipefail
export PATH="${pkgs.gnugrep}/bin:${pkgs.coreutils}/bin:@out@/sw/bin:/usr/bin:/bin:/usr/sbin:/sbin"
source ${cfg.environmentFile}
export OP_SERVICE_ACCOUNT_TOKEN
${opnixScript}
'';
serviceConfig = {
RunAtLoad = true;
KeepAlive.SuccessfulExit = false;
};
};
}
{
system.activationScripts = {
# if no generation already exists, rely on the launchd startup job;
# otherwise, if there already is an existing generation, reprovision
# secrets because we did a darwin-rebuild
preActivation.text = ''
${scripts.setOpnixGeneration}
(( _opnix_generation > 1 )) && {
# shellcheck disable=SC1091
source ${cfg.environmentFile}
export OP_SERVICE_ACCOUNT_TOKEN
${scripts.installSecrets}
}
'';

users.text = mkAfter ''
${scripts.setOpnixGeneration}
(( _opnix_generation > 1 )) && {
${scripts.chownSecrets}
}
'';
};
}
]);
}
77 changes: 77 additions & 0 deletions modules/nixos.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
toplevel @ {
config,
lib,
...
}: let
inherit
(lib)
mkIf
mkMerge
mkOption
types
;

cfg = config.opnix;
scripts = import ./scripts.nix toplevel;
in {
imports = [./common.nix];

options.opnix = {
systemdWantedBy = mkOption {
type = types.listOf types.str;
default = [];
description = ''
A list of `systemd` service names that depend on secrets from `opnix`. This option will set `after = [ "opnix.service" ]` and `wants = [ "opnix.service" ]` for each specified `systemd` unit.'';
example = ["homepage-dashboard" "wg-quick-vpn"];
};
};

config = let
opnixScript = ''
${scripts.installSecrets}
${scripts.chownSecrets}
'';
in
mkIf (cfg.secrets != {}) (mkMerge [
{
systemd.services.opnix = {
wants = ["network-online.target"];
after = ["network.target" "network-online.target"];

serviceConfig = {
Type = "oneshot";
EnvironmentFile = cfg.environmentFile;
RemainAfterExit = true;
};

script = opnixScript;
};
}
{
system.activationScripts.opnix-on-rebuild = {
# if no generation already exists, rely on the systemd startup job;
# otherwise, if there already is an existing generation, reprovision
# secrets because we did a nixos-rebuild
text = ''
${scripts.setOpnixGeneration}
(( _opnix_generation > 1 )) && {
source ${cfg.environmentFile}
export OP_SERVICE_ACCOUNT_TOKEN
${opnixScript}
}
'';
deps = ["usrbinenv"];
};
}
{
systemd.services = builtins.listToAttrs (builtins.map (systemdName: {
name = systemdName;
value = {
after = ["opnix.service"];
wants = ["opnix.service"];
};
})
cfg.systemdWantedBy);
}
]);
}
112 changes: 0 additions & 112 deletions modules/op-secrets.nix

This file was deleted.

Loading