diff --git a/nixos/doc/manual/from_md/development/option-types.section.xml b/nixos/doc/manual/from_md/development/option-types.section.xml
index 4447292927021d..c748f091c7527d 100644
--- a/nixos/doc/manual/from_md/development/option-types.section.xml
+++ b/nixos/doc/manual/from_md/development/option-types.section.xml
@@ -37,6 +37,46 @@
+
+
+ types.secretFile
+
+
+
+ A string representing a filesystem path (starting with
+ /
) to a file which is supposed to remain
+ secret. Depending on how the module is implemented, setting
+ an option of type types.path to the
+ literal value /etc/secret_file can make
+ nix copy the secret file at nixos-rebuild
+ time to the store and thus make it world readable. To avoid
+ this behavior, it is enough to quote the path:
+ "/etc/secret_file". This
+ solution is simple, but it is easy to forget about it.
+ types.secretFile is design to prevent
+ such mistakes. Compared to types.path,
+ this type adds further restrictions:
+
+
+
+
+ only strings (as opposed to unquoted paths) are accepted
+ as input.
+
+
+
+
+ the string must not start by
+ /nix/store/. To bypass these
+ restrictions you can pass the value to the function
+ types.secretFile.makeWorldReadable.
+ This can be useful when writing NixOS tests, as in this
+ case the secret file is only an example value.
+
+
+
+
+
types.package
diff --git a/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml
index 8bbb8665219aee..defa9332deaee1 100644
--- a/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml
+++ b/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml
@@ -36,6 +36,36 @@
PHP now defaults to PHP 8.1, updated from 8.0.
+
+
+ The NixOS module system now has a type
+ secretFile for options which contain the
+ path to a file that should remain secret. This is to avoid
+ mistakes where one writes
+ services.miniflux.adminCredentialsFile = /etc/secret
+ instead of
+ services.miniflux.adminCredentialsFile = "/etc/secret";
+ which makes nix copy /etc/secret to the
+ store where everyone could read it. A number of modules have
+ been converted to use it. This is a breaking change visible by
+ an error message like this:
+
+
+error: A definition for option `services.miniflux.adminCredentialsFile' is not of type `quoted path to a secret file'. Definition values:
+ - In `nixos/lib/build-vms.nix': /etc/secret
+
+
+ To fix the issue you must assess whether leaking
+ /etc/secret to the store and thus all local
+ users is a problem. If it is the case, then add quotes:
+ services.miniflux.adminCredentialsFile = "/etc/secrets".
+ If you notice this during upgrade, your secret probably has
+ already leaked and it may be a good time to change it. If
+ leaking this file is acceptable (for example in a NixOS test),
+ you can keep the old behavior like this:
+ services.miniflux.adminCredentialsFile = lib.types.secretFile.makeWorldReadable /etc/secret.
+
+
diff --git a/nixos/doc/manual/release-notes/rl-2211.section.md b/nixos/doc/manual/release-notes/rl-2211.section.md
index 5dc8e958c89669..4bb9aabc70e234 100644
--- a/nixos/doc/manual/release-notes/rl-2211.section.md
+++ b/nixos/doc/manual/release-notes/rl-2211.section.md
@@ -19,6 +19,25 @@ In addition to numerous new and upgraded packages, this release has the followin
- PHP now defaults to PHP 8.1, updated from 8.0.
+- The NixOS module system now has a type `secretFile` for options which contain
+ the path to a file that should remain secret. This is to avoid mistakes where
+ one writes `services.miniflux.adminCredentialsFile = /etc/secret` instead of
+ `services.miniflux.adminCredentialsFile = "/etc/secret";` which makes nix
+ copy `/etc/secret` to the store where everyone could read it. A number of
+ modules have been converted to use it. This is a breaking change visible by
+ an error message like this:
+ ```
+ error: A definition for option `services.miniflux.adminCredentialsFile' is not of type `quoted path to a secret file'. Definition values:
+ - In `nixos/lib/build-vms.nix': /etc/secret
+ ```
+ To fix the issue you must assess whether leaking `/etc/secret` to the store
+ and thus all local users is a problem. If it is the case, then add quotes:
+ `services.miniflux.adminCredentialsFile = "/etc/secrets"`. If you notice this
+ during upgrade, your secret probably has already leaked and it may be a good
+ time to change it. If leaking this file is acceptable (for example in a NixOS
+ test), you can keep the old behavior like this:
+ `services.miniflux.adminCredentialsFile = lib.types.secretFile.makeWorldReadable /etc/secret`.
+
## New Services {#sec-release-22.11-new-services}