summary refs log tree commit diff
path: root/options.nix
diff options
context:
space:
mode:
authorIrene Knapp <ireneista@internetsafetylabs.org>2025-09-09 16:31:35 -0700
committerIrene Knapp <ireneista@internetsafetylabs.org>2025-09-09 16:31:35 -0700
commitcd82f4a96839ad4b7907e0355a87ded23b5fe584 (patch)
treea28a5de07c2dce0717e133cd45217b127e090aaa /options.nix
parent2d2f73a9257035398e90d32dcfb7db74313d8fe6 (diff)
add the mechanism by which Rust will ask the nix config for details
this also adds the beginnings of a test harness; the test harness will
become useful in a future CL, but for now `nix flake check` should
continue to do what we want it to, and maybe slightly more

Change-Id: I7f05bcb5588f2b52d79cf05cf22263f084e8be49
Diffstat (limited to 'options.nix')
-rw-r--r--options.nix125
1 files changed, 97 insertions, 28 deletions
diff --git a/options.nix b/options.nix
index 044833b..5fa70dc 100644
--- a/options.nix
+++ b/options.nix
@@ -1,38 +1,107 @@
-
 { pkgs, lib }:
 
-let
-  scriptRegistry = {
-    bigsecret = ''head -c 64 /dev/urandom | base32'';
-    medsecret = ''head -c 32 /dev/urandom | base32'';
-    smallsecret = ''head -c 16 /dev/urandom | base32'';
-  };
-in {
-  secrets.secrets = lib.mkOption {
-    description = ''
+{
+  options.secrets = {
+    secrets = lib.mkOption {
+      description = ''
         A set of secrets, each identified by a name (e.g. mattermost, gitlabce).
         Each secret has a filename and a script to generate it.
-    '';
-    default = { };
-    type = lib.types.attrsOf (lib.types.submodule {
-      options = {
-        filename = lib.mkOption {
-          type = lib.types.str;
-          description = ''
-            The filename where this secret is stored, all
-            files at /etc/nixos/secrets
-          '';
-          example = "mysecret.key";
-        };
-        script = lib.mkOption {
-          type = lib.types.str;
-          description = ''
+      '';
+      default = { };
+      type = lib.types.attrsOf (lib.types.submodule {
+        options = {
+          filename = lib.mkOption {
+            type = lib.types.pathWith {
+              absolute = false;
+              inStore = false;
+            };
+            description = ''
+              The filename this secret should have. This is a relative path,
+              relative to the base of the secret store, which is normally
+              `/etc/nixos/secrets`. It is fine for it to be a bare filename.
+            '';
+            example = "mysecret.key";
+          };
+
+          script = lib.mkOption {
+            type = lib.types.lines;
+            description = ''
               Shell command that generates the secret.
-          ";
-          example = "head -c 32 /dev/urandom | base32";
+            '';
+            example = "head -c 32 /dev/urandom | base32";
+          };
+        };
+      });
+    };
+
+    # For modularity's sake, we export a cleanly-defined structure for the CLI
+    # tool to wrap around. That way we avoid inadvertently relying on the
+    # overall structure of the secrets options, and in particular we avoid
+    # relying on implementation details that will change.
+    export = lib.mkOption {
+      description = ''
+        An internal value used for the command-line secret-management tool to
+        query an assembled NixOS configuration about what secrets it expects
+        to exist, and their properties.
+      '';
+      example = {
+        mattermost = {
+          path = "/etc/nixos/secrets/mattermost.key";
+          script = "touch /etc/nixos/secrets/mattermost.key"
+        };
+
+        neooffice = {
+          path = "/etc/nixos/secrets/neooffice.key";
+          script = "head -c 32 /dev/urandom > /etc/nixos/secrets/neooffice.key"
+        };
+      };
+
+      type = lib.types.attrsOf lib.types.submodule = {
+        options = {
+          path = {
+            type = lib.types.pathWith {
+              absolute = true;
+              inStore = false;
+            };
+            description = ''
+              An internal value which is part of `secrets.export`, used by
+              the command-line secret-management tool. This is an absolute
+              path to the file which, if the secret exists, should contain it.
+              When the CLI tool is run, this directory is expected to exist;
+              whether the file exists is the thing the CLI tool is responsible
+              for managing.
+            '';
+            example = "/etc/nixos/secrets/neooffice.key";
+          };
+
+          script = {
+            type = lib.types.lines;
+            description = ''
+              An internal value which is part of `secrets.export`, used by
+              the command-line secret-management tool. This is a shell script
+              which will create the secret, destructively overwriting it if it
+              already exists. It runs in an empty shell environment with no
+              environment variables. It should start with an appropriate
+              `#!` line pointing to the correct shell to run it under.
+            '';
+            example = ''
+              #!/nix/store/s68ja06r60xbs51k8lrdciva4di46y61-bash-5.2/bin/bash
+              head -c 32 /dev/urandom > /etc/nixos/secrets/neooffice.key
+            '';
+          };
         };
       };
-    });
+    };
   };
+
+  config.secrets.export = { config, pkgs, ... }:
+      let exportSecret = name: secret: {
+            path = "/etc/nixos/secrets/${secret.file}";
+            script = ''
+              #!${pkgs.bash}/bin/bash
+              ${secret.script}
+            '';
+          };
+      in mapAttrs exportSecret config.secrets.secrets;
 }