summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--flake.nix13
-rw-r--r--options.nix38
-rw-r--r--secrets-lengths.md119
3 files changed, 170 insertions, 0 deletions
diff --git a/flake.nix b/flake.nix
index 2c67d17..9e73b80 100644
--- a/flake.nix
+++ b/flake.nix
@@ -1,4 +1,11 @@
 {
+  description = ''
+    A tool to manage credentials and other secrets as mutable state within a NixOS environment,
+    consisting of a Rust executable, NixOS configuration, and associated documentation.
+    Published as part of the Small Tech Kit, ISL's public resource for small organizations
+    that want to host their own infrastructure, but usable independently.
+  '';
+
   inputs = {
     nixpkgs = {
       type = "github";
@@ -25,6 +32,12 @@
       };
     });
 
+    nixosModules.default = { ... }: {
+      imports = [
+        ./options.nix
+      ];
+    };
+
     devShells = forAllSystems (system: let pkgs = nixpkgsFor.${system}; in {
       default = pkgs.mkShell {
         nativeBuildInputs = with pkgs; [
diff --git a/options.nix b/options.nix
new file mode 100644
index 0000000..044833b
--- /dev/null
+++ b/options.nix
@@ -0,0 +1,38 @@
+
+{ 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 = ''
+        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 = ''
+              Shell command that generates the secret.
+          ";
+          example = "head -c 32 /dev/urandom | base32";
+        };
+      };
+    });
+  };
+}
+
diff --git a/secrets-lengths.md b/secrets-lengths.md
new file mode 100644
index 0000000..efa00ed
--- /dev/null
+++ b/secrets-lengths.md
@@ -0,0 +1,119 @@
+# If we have a couple of applications, lets say mattermost, jenkins, opengrok for example - 
+# do they all require secrets of the same length and if so, we would need to create them at that length - so we would need scripts for each desired length, or have the length be a parameter.
+   # - Mattermost: MM_SECRET (Session/Encryption Key) - 64 chars or more
+   # - Mattermost: database passwords - 24 to 32 chars reccommended
+   # - Jenkins master key: 128 bit key, around 24 chars
+   # - Jenkins API tokens - 32 chars typically
+   # - Jenkins misc tokens - at least 32 to 64 chars
+   # - opengrok - between 16 and 64 chars depending on what for
+
+
+# There are multiple ways to generate secrets, here's a by no means complete set of examples - we could even generate the long ones and cut them down. 
+
+# Generate a random 32-byte secret and output as base32
+    head -c 32 /dev/urandom | base32
+
+# You can programmatically access or generate secrets:
+    nix eval --raw '(import <nixpkgs> {}).lib.mkSecret "mysecret"'
+
+# You can also store secrets outside the config with systemd:
+    {
+      systemd.services.myService.environment = {
+        SECRET_KEY = builtins.readFile /etc/secrets/mysecret;
+      };
+    }
+# mkpasswd
+  # variety of encryption methods, of different lengths
+
+# Many NixOS users integrate password managers to generate secrets dynamically:
+    pass generate my-service/secret 32
+
+# Here's reusable secrets.nix template for NixOS. It generates multiple secrets for different services and can be imported into configuration.nix without exposing them in Git.
+
+    { lib, pkgs, ... }:
+
+    let
+      # Helper to generate a random base32 secret of given length
+      randomSecret = length:
+        builtins.toString (builtins.base32Encode (pkgs.lib.randomString length));
+
+    in {
+      # Example: PostgreSQL password
+      postgresPassword = lib.mkSecret (randomSecret 32);
+
+      # Example: Redis password
+      redisPassword = lib.mkSecret (randomSecret 32);
+
+      # Example: API token for some internal service
+      internalApiToken = lib.mkSecret (randomSecret 40);
+
+      # Example: Web application secret key
+      webAppSecretKey = lib.mkSecret (randomSecret 64);
+
+      # Example: SSH authorized key for automated tasks
+      automatedSshKey = lib.mkSecret (randomSecret 32);
+
+      # You can add more services as needed
+    }
+# and how to use in configuration.nix:
+    { config, pkgs, ... }:
+
+    let
+      secrets = import ./secrets.nix { inherit pkgs lib; };
+    in
+    {
+      services.postgresql = {
+        enable = true;
+        authentication = {
+          password = secrets.postgresPassword;
+        };
+      };
+
+      services.redis.enable = true;
+      services.redis.password = secrets.redisPassword;
+
+      # Example environment variable for web service
+      systemd.services.myWebApp.environment = {
+        SECRET_KEY = secrets.webAppSecretKey;
+        API_TOKEN = secrets.internalApiToken;
+      };
+    }
+
+# ==========================================================================================
+  # 1. Short secrets (8–16 characters)
+  #    •	Use: Low-security tokens, simple service passwords, or internal tools with limited exposure.
+  #    •	Example Applications:
+  #    •	Temporary API keys for internal scripts
+  #    •	Simple Redis instance with limited access
+  #    •	Example:
+  shortToken = lib.mkSecret (builtins.toString (pkgs.lib.randomString 12));
+      
+  # 2. Medium secrets (20–32 characters)
+  #	•	Use: Standard passwords for services, moderate security tokens, session keys.
+  #	•	Example Applications:
+  #	•	PostgreSQL or MySQL passwords
+  #	•	Redis passwords
+  #	•	Docker registry tokens
+  #	•	Example:
+  postgresPassword = lib.mkSecret (builtins.toString (pkgs.lib.randomString 24));
+  redisPassword    = lib.mkSecret (builtins.toString (pkgs.lib.randomString 32));
+
+  # 3. Long secrets (40–64 characters)
+  #	•	Use: Cryptographic keys, high-security API tokens, web application secrets.
+  #	•	Example Applications:
+  #	•	Web framework SECRET_KEY for session encryption (Django, Flask, etc.)
+  #	•	JWT signing keys
+  #	•	OAuth2 client secrets
+  #	•	Example:
+  webAppSecretKey   = lib.mkSecret (builtins.toString (pkgs.lib.randomString 64));
+  internalApiToken  = lib.mkSecret (builtins.toString (pkgs.lib.randomString 48));
+
+  # 4. Very long secrets (128+ characters)
+  # •	Use: Encryption keys, long-lived service-to-service authentication, blockchain keys.
+  # •	Example Applications:
+  # •	SSH private keys or passphrases
+  # •	TLS certificates private keys
+  # •	End-to-end encryption secrets for messaging apps
+  # •	Example:
+  tlsPrivateKey = lib.mkSecret (builtins.toString (pkgs.lib.randomString 128));
+  sshKeyPassphrase = lib.mkSecret (builtins.toString (pkgs.lib.randomString 256));
\ No newline at end of file