A secret can be stored in a file. It is written at runtime in the configuration file. Note it is also possible to write them in the nix store for dev purposes.
···1+{ lib }:
2+3+with lib;
4+5+rec {
6+ # A shell script string helper to get the value of a secret at
7+ # runtime.
8+ getSecret = secretOption:
9+ if secretOption.storage == "fromFile"
10+ then ''$(cat ${secretOption.value})''
11+ else ''${secretOption.value}'';
12+13+14+ # A shell script string help to replace at runtime in a file the
15+ # pattern of a secret by its value.
16+ replaceSecret = secretOption: filename: ''
17+ sed -i "s/${secretOption.pattern}/${getSecret secretOption}/g" ${filename}
18+ '';
19+20+ # This generates an option that can be used to declare secrets which
21+ # can be stored in the nix store, or not. A pattern is written in
22+ # the nix store to represent the secret. The pattern can
23+ # then be overwritten with the value of the secret at runtime.
24+ mkSecretOption = {name, description ? ""}:
25+ mkOption {
26+ description = description;
27+ type = types.submodule ({
28+ options = {
29+ pattern = mkOption {
30+ type = types.str;
31+ default = "##${name}##";
32+ description = "The pattern that represent the secret.";
33+ };
34+ storage = mkOption {
35+ type = types.enum [ "fromNixStore" "fromFile" ];
36+ description = ''
37+ Choose the way the password is provisionned. If
38+ fromNixStore is used, the value is the password and it is
39+ written in the nix store. If fromFile is used, the value
40+ is a path from where the password will be read at
41+ runtime. This is generally used with <link
42+ xlink:href="https://nixos.org/nixops/manual/#opt-deployment.keys">
43+ deployment keys</link> of Nixops.
44+ '';};
45+ value = mkOption {
46+ type = types.str;
47+ description = ''
48+ If the storage is fromNixStore, the value is the password itself,
49+ otherwise it is a path to the file that contains the password.
50+ '';
51+ };
52+ };});
53+ };
54+}