WIP janus secrets
This commit is contained in:
@@ -17,6 +17,9 @@ Insert generated runtime CA material into `modules/hosts/janus/secrets.yaml` und
|
|||||||
- `/tmp/janus-step-ca-bootstrap/step/secrets/intermediate_ca_key` -> `intermediate_ca_key`
|
- `/tmp/janus-step-ca-bootstrap/step/secrets/intermediate_ca_key` -> `intermediate_ca_key`
|
||||||
- `/tmp/janus-step-ca-bootstrap/step/secrets/ssh_host_ca_key` -> `ssh_host_ca_key`
|
- `/tmp/janus-step-ca-bootstrap/step/secrets/ssh_host_ca_key` -> `ssh_host_ca_key`
|
||||||
- `/tmp/janus-step-ca-bootstrap/step/secrets/ssh_user_ca_key` -> `ssh_user_ca_key`
|
- `/tmp/janus-step-ca-bootstrap/step/secrets/ssh_user_ca_key` -> `ssh_user_ca_key`
|
||||||
|
- `/tmp/janus-step-ca-bootstrap/step/config/ca.json` -> `admin_provisioner_encrypted_key` (copy `authority.provisioners[].encryptedKey` for the `admin` JWK provisioner)
|
||||||
|
|
||||||
|
If you are only validating wiring first, `admin_provisioner_encrypted_key` can be an encrypted placeholder and replaced later.
|
||||||
|
|
||||||
If rotating provisioner password, also set:
|
If rotating provisioner password, also set:
|
||||||
|
|
||||||
@@ -24,7 +27,7 @@ If rotating provisioner password, also set:
|
|||||||
|
|
||||||
Secret source-of-truth after this split:
|
Secret source-of-truth after this split:
|
||||||
|
|
||||||
- `modules/hosts/janus/secrets.yaml`: Janus runtime CA secrets only (`ca_password`, `intermediate_ca_crt`, `intermediate_ca_key`, `ssh_host_ca_key`, `ssh_user_ca_key`)
|
- `modules/hosts/janus/secrets.yaml`: Janus runtime CA secrets (`ca_password`, `intermediate_ca_crt`, `intermediate_ca_key`, `ssh_host_ca_key`, `ssh_user_ca_key`, `admin_provisioner_encrypted_key`)
|
||||||
- `keys/secrets.yaml`: shared Janus provisioner secret (`janus.admin_jwk`) consumed by `step-ssh-host` across hosts
|
- `keys/secrets.yaml`: shared Janus provisioner secret (`janus.admin_jwk`) consumed by `step-ssh-host` across hosts
|
||||||
|
|
||||||
Then update public artifacts in repo from generated output:
|
Then update public artifacts in repo from generated output:
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ in
|
|||||||
intermediateKey = "janus/intermediate_ca_key";
|
intermediateKey = "janus/intermediate_ca_key";
|
||||||
sshHostCaKey = "janus/ssh_host_ca_key";
|
sshHostCaKey = "janus/ssh_host_ca_key";
|
||||||
sshUserCaKey = "janus/ssh_user_ca_key";
|
sshUserCaKey = "janus/ssh_user_ca_key";
|
||||||
|
adminProvisionerEncryptedKey = "janus/admin_provisioner_encrypted_key";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
mtls = {
|
mtls = {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ janus:
|
|||||||
intermediate_ca_key: ENC[AES256_GCM,data:wrzE8pgSZrtMA2jyLuVhMFxr47ICDBUkqOFyFJex9h3g,iv:I3Sz07e+cFDOUunCu7ZGcAjckRJDy3NmTXoB0vtA0HI=,tag:inANSVzyAzWlX4J5pheY8A==,type:str]
|
intermediate_ca_key: ENC[AES256_GCM,data:wrzE8pgSZrtMA2jyLuVhMFxr47ICDBUkqOFyFJex9h3g,iv:I3Sz07e+cFDOUunCu7ZGcAjckRJDy3NmTXoB0vtA0HI=,tag:inANSVzyAzWlX4J5pheY8A==,type:str]
|
||||||
ssh_host_ca_key: ENC[AES256_GCM,data:IT3PcnbrexRDvxoVEyyxYBx7+Brm3SzVP3Yr2UGkFjeH,iv:edfMiRR+EVx9veTH+mEAFtEdC/rlW8uU5jMD8UX2Ylo=,tag:KKS/2GQE8V6obbjfMLspug==,type:str]
|
ssh_host_ca_key: ENC[AES256_GCM,data:IT3PcnbrexRDvxoVEyyxYBx7+Brm3SzVP3Yr2UGkFjeH,iv:edfMiRR+EVx9veTH+mEAFtEdC/rlW8uU5jMD8UX2Ylo=,tag:KKS/2GQE8V6obbjfMLspug==,type:str]
|
||||||
ssh_user_ca_key: ENC[AES256_GCM,data:w3gc97CYUODNxk0gIyghd9PCksDVvrdvl8j/NQe/tCtw,iv:WbWlVCPV7niVHEJ9sVcO9SAcLSfquE/bvcR5KClxszk=,tag:08uj+lv9MflYOtQh28K6pw==,type:str]
|
ssh_user_ca_key: ENC[AES256_GCM,data:w3gc97CYUODNxk0gIyghd9PCksDVvrdvl8j/NQe/tCtw,iv:WbWlVCPV7niVHEJ9sVcO9SAcLSfquE/bvcR5KClxszk=,tag:08uj+lv9MflYOtQh28K6pw==,type:str]
|
||||||
|
admin_provisioner_encrypted_key: ENC[AES256_GCM,data:/EdlRiPn/LHpQk5sA9VVYTz/U4i6Ag==,iv:r6Rm38L1R4xsnyR97e3J2FdH4KWYewZdADosv9WLAXw=,tag:MnWq9lI7GAXN0FmGTa9zmQ==,type:str]
|
||||||
sops:
|
sops:
|
||||||
age:
|
age:
|
||||||
- enc: |
|
- enc: |
|
||||||
@@ -24,7 +25,7 @@ sops:
|
|||||||
ZT3ScL4PAYhH+lxciJK4tit53taevbp5o0jFibaup4ByDvgj7HPclw==
|
ZT3ScL4PAYhH+lxciJK4tit53taevbp5o0jFibaup4ByDvgj7HPclw==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
recipient: age1gvplss0ddmyf6vpjy363wu3n057vhm0j6n7tc94cxd8kadapypws5mtaj0
|
recipient: age1gvplss0ddmyf6vpjy363wu3n057vhm0j6n7tc94cxd8kadapypws5mtaj0
|
||||||
lastmodified: "2026-07-04T03:42:39Z"
|
lastmodified: "2026-07-04T04:20:22Z"
|
||||||
mac: ENC[AES256_GCM,data:qBuVJo9F5IiQGDqji0ZfNH6MYYLgaVuEoHGsvejw1ffFjYeqGI5LrZmez8xTx8dymQADCDYINZNYlKxgXaXdGqrlKaU8GzuWeF7M0Ad43+S/8DbP2OGPXERHAH+IWVjvzlurXs4tWE4ULw4PbsVpWqOBaSk603N7cuy7Ztwfk8M=,iv:lceVJAeZi8FwKo8DAET1hgUi54Bu+0kjWcGEZxs5wCA=,tag:mFkqan9BHtI6NkxqbjkIcQ==,type:str]
|
mac: ENC[AES256_GCM,data:N0+lAFghaas9fg9PMcsaMPKJbYmnSrgPIFPsEuC749nzMX1IfQVaTLYm6ziZiq8TpscGR1tBqzw2eXiSZG4XfI44naEzO8CvY87aaZAL19/c/j4XE8eBqv1RLsLMbBIYYs8h6aZXCwhWUa3bwFukjueD0iu2X3md6V4T+4RnYSE=,iv:Xd/DCSDymp+KURHjM3Cht8oqbyN/k5+eybdi3pK5eww=,tag:tmDJoo5RKXQTnVjqkXsZ1w==,type:str]
|
||||||
unencrypted_suffix: _unencrypted
|
unencrypted_suffix: _unencrypted
|
||||||
version: 3.13.1
|
version: 3.13.1
|
||||||
|
|||||||
@@ -1,129 +0,0 @@
|
|||||||
{
|
|
||||||
"root": "/etc/step-ca/certs/root_ca.crt",
|
|
||||||
"federatedRoots": null,
|
|
||||||
"crt": "/etc/step-ca/certs/intermediate_ca.crt",
|
|
||||||
"key": "/etc/step-ca/secrets/intermediate_ca_key",
|
|
||||||
"address": ":443",
|
|
||||||
"insecureAddress": "",
|
|
||||||
"dnsNames": [
|
|
||||||
"janus.john-stream.com",
|
|
||||||
"192.168.1.113"
|
|
||||||
],
|
|
||||||
"ssh": {
|
|
||||||
"hostKey": "/etc/step-ca/secrets/ssh_host_ca_key",
|
|
||||||
"userKey": "/etc/step-ca/secrets/ssh_user_ca_key"
|
|
||||||
},
|
|
||||||
"logger": {
|
|
||||||
"format": "text"
|
|
||||||
},
|
|
||||||
"db": {
|
|
||||||
"type": "badgerv2",
|
|
||||||
"dataSource": "/var/lib/step-ca/db",
|
|
||||||
"badgerFileLoadingMode": ""
|
|
||||||
},
|
|
||||||
"authority": {
|
|
||||||
"provisioners": [
|
|
||||||
{
|
|
||||||
"type": "ACME",
|
|
||||||
"name": "acme"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "SSHPOP",
|
|
||||||
"name": "sshpop",
|
|
||||||
"claims": {
|
|
||||||
"enableSSHCA": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "JWK",
|
|
||||||
"name": "admin",
|
|
||||||
"key": {
|
|
||||||
"use": "sig",
|
|
||||||
"kty": "EC",
|
|
||||||
"kid": "xoxgOJFbveSLIL2gm1Yu5ZiRb9v8Jxe44F56i3v-Nf8",
|
|
||||||
"crv": "P-256",
|
|
||||||
"alg": "ES256",
|
|
||||||
"x": "zFO8hPx_eH0Iyz7UJI-w8ODMusEKCZ28M76sGWmWYxA",
|
|
||||||
"y": "XIWLLyKDzqxV9UH-2KeAkKPDrgLoPrxxW9-PzkXggME"
|
|
||||||
},
|
|
||||||
"encryptedKey": "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJjdHkiOiJqd2sranNvbiIsImVuYyI6IkEyNTZHQ00iLCJwMmMiOjYwMDAwMCwicDJzIjoiUVJnTnJVTF9KcmxJYkJMVTlGNVRPZyJ9.DMu7xBNCq5pr-_--YTxNr5Hrcqy6ZmSVHsWurfVXL7Hk0Q3vyYRxiw.h-CnFiYc-DhxThI3.plx3_Qa_0kU-2TwnqFNfAfGnCpfQ2e0iiCMLruNHbLMnHeXQ1BysHBqps45_02zZXIRdHoDgYGtXRSfcdUYYoS0pLoPzC6m301ZFNSAFdRVlSZ3Q6VmWdixPXXnEB4EgSKTT_wxR33L8t9OpFzD85KfY-b_Un1l99ufjCnfg-EYkcICTn_G4-8bcW3eFIvJ6setzu-l0jHMhLQdIweqncn9on9xBXBD-ANhZfP95P2BJt-APqCi8eqiAvn_vClovdg0PxzRwOVDvWREz66FDw-HTU7xDtGO9hACopT5tfZOXDoykgZw1mJsq9NEq9ZzvKG2hvyk1UXtExxrNtFo.5q1OfGU4Amo4Si-vpeI42g",
|
|
||||||
"claims": {
|
|
||||||
"enableSSHCA": true,
|
|
||||||
"disableRenewal": false,
|
|
||||||
"allowRenewalAfterExpiry": false,
|
|
||||||
"disableSmallstepExtensions": false
|
|
||||||
},
|
|
||||||
"options": {
|
|
||||||
"x509": {},
|
|
||||||
"ssh": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"template": {},
|
|
||||||
"backdate": "1m0s"
|
|
||||||
},
|
|
||||||
"tls": {
|
|
||||||
"cipherSuites": [
|
|
||||||
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
|
|
||||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
|
|
||||||
],
|
|
||||||
"minVersion": 1.2,
|
|
||||||
"maxVersion": 1.3,
|
|
||||||
"renegotiation": false
|
|
||||||
},
|
|
||||||
"templates": {
|
|
||||||
"ssh": {
|
|
||||||
"user": [
|
|
||||||
{
|
|
||||||
"name": "config.tpl",
|
|
||||||
"type": "snippet",
|
|
||||||
"template": "templates/ssh/config.tpl",
|
|
||||||
"path": "~/.ssh/config",
|
|
||||||
"comment": "#"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "step_includes.tpl",
|
|
||||||
"type": "prepend-line",
|
|
||||||
"template": "templates/ssh/step_includes.tpl",
|
|
||||||
"path": "${STEPPATH}/ssh/includes",
|
|
||||||
"comment": "#"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "step_config.tpl",
|
|
||||||
"type": "file",
|
|
||||||
"template": "templates/ssh/step_config.tpl",
|
|
||||||
"path": "ssh/config",
|
|
||||||
"comment": "#"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "known_hosts.tpl",
|
|
||||||
"type": "file",
|
|
||||||
"template": "templates/ssh/known_hosts.tpl",
|
|
||||||
"path": "ssh/known_hosts",
|
|
||||||
"comment": "#"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"host": [
|
|
||||||
{
|
|
||||||
"name": "sshd_config.tpl",
|
|
||||||
"type": "snippet",
|
|
||||||
"template": "templates/ssh/sshd_config.tpl",
|
|
||||||
"path": "/etc/ssh/sshd_config",
|
|
||||||
"comment": "#",
|
|
||||||
"requires": [
|
|
||||||
"Certificate",
|
|
||||||
"Key"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ca.tpl",
|
|
||||||
"type": "snippet",
|
|
||||||
"template": "templates/ssh/ca.tpl",
|
|
||||||
"path": "/etc/ssh/ca.pub",
|
|
||||||
"comment": "#"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"commonName": "Step Online CA"
|
|
||||||
}
|
|
||||||
@@ -3,96 +3,22 @@
|
|||||||
flake.modules.nixos.step-ca = { config, pkgs, lib, ... }:
|
flake.modules.nixos.step-ca = { config, pkgs, lib, ... }:
|
||||||
let
|
let
|
||||||
cfg = config.step-ca;
|
cfg = config.step-ca;
|
||||||
|
caAddress = "0.0.0.0";
|
||||||
|
caPort = 443;
|
||||||
|
|
||||||
caPasswordPath = (lib.getAttr cfg.secrets.caPassword config.sops.secrets).path;
|
caPasswordPath = (lib.getAttr cfg.secrets.caPassword config.sops.secrets).path;
|
||||||
intermediateCrtPath = (lib.getAttr cfg.secrets.intermediateCrt config.sops.secrets).path;
|
intermediateCrtPath = (lib.getAttr cfg.secrets.intermediateCrt config.sops.secrets).path;
|
||||||
intermediateKeyPath = (lib.getAttr cfg.secrets.intermediateKey config.sops.secrets).path;
|
intermediateKeyPath = (lib.getAttr cfg.secrets.intermediateKey config.sops.secrets).path;
|
||||||
sshHostCaKeyPath = (lib.getAttr cfg.secrets.sshHostCaKey config.sops.secrets).path;
|
sshHostCaKeyPath = (lib.getAttr cfg.secrets.sshHostCaKey config.sops.secrets).path;
|
||||||
sshUserCaKeyPath = (lib.getAttr cfg.secrets.sshUserCaKey config.sops.secrets).path;
|
sshUserCaKeyPath = (lib.getAttr cfg.secrets.sshUserCaKey config.sops.secrets).path;
|
||||||
in
|
adminProvisionerEncryptedKeyValue =
|
||||||
{
|
(lib.getAttr cfg.secrets.adminProvisionerEncryptedKey config.sops.placeholder);
|
||||||
options.step-ca = {
|
|
||||||
rootCertPath = lib.mkOption {
|
|
||||||
description = "Path to the Step CA root certificate served by this host.";
|
|
||||||
type = lib.types.path;
|
|
||||||
};
|
|
||||||
dnsNames = lib.mkOption {
|
|
||||||
description = "DNS names and IP SANs advertised by this Step CA instance.";
|
|
||||||
type = with lib.types; listOf str;
|
|
||||||
};
|
|
||||||
secrets = {
|
|
||||||
sopsFile = lib.mkOption {
|
|
||||||
description = "Host-local SOPS file that stores Step CA secret material.";
|
|
||||||
type = lib.types.path;
|
|
||||||
};
|
|
||||||
caPassword = lib.mkOption {
|
|
||||||
description = "SOPS key for the Step CA intermediate password.";
|
|
||||||
type = lib.types.str;
|
|
||||||
};
|
|
||||||
intermediateCrt = lib.mkOption {
|
|
||||||
description = "SOPS key for the Step CA intermediate certificate.";
|
|
||||||
type = lib.types.str;
|
|
||||||
};
|
|
||||||
intermediateKey = lib.mkOption {
|
|
||||||
description = "SOPS key for the Step CA intermediate private key.";
|
|
||||||
type = lib.types.str;
|
|
||||||
};
|
|
||||||
sshHostCaKey = lib.mkOption {
|
|
||||||
description = "SOPS key for the Step SSH host CA private key.";
|
|
||||||
type = lib.types.str;
|
|
||||||
};
|
|
||||||
sshUserCaKey = lib.mkOption {
|
|
||||||
description = "SOPS key for the Step SSH user CA private key.";
|
|
||||||
type = lib.types.str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
renderedStepCaConfig = builtins.toJSON {
|
||||||
# Placeholders are expected initially until real material is inserted into sops.
|
|
||||||
sops.secrets."${cfg.secrets.caPassword}" = {
|
|
||||||
sopsFile = cfg.secrets.sopsFile;
|
|
||||||
owner = "step-ca";
|
|
||||||
group = "step-ca";
|
|
||||||
mode = "0400";
|
|
||||||
};
|
|
||||||
sops.secrets."${cfg.secrets.intermediateCrt}" = {
|
|
||||||
sopsFile = cfg.secrets.sopsFile;
|
|
||||||
owner = "step-ca";
|
|
||||||
group = "step-ca";
|
|
||||||
mode = "0400";
|
|
||||||
};
|
|
||||||
sops.secrets."${cfg.secrets.intermediateKey}" = {
|
|
||||||
sopsFile = cfg.secrets.sopsFile;
|
|
||||||
owner = "step-ca";
|
|
||||||
group = "step-ca";
|
|
||||||
mode = "0400";
|
|
||||||
};
|
|
||||||
sops.secrets."${cfg.secrets.sshHostCaKey}" = {
|
|
||||||
sopsFile = cfg.secrets.sopsFile;
|
|
||||||
owner = "step-ca";
|
|
||||||
group = "step-ca";
|
|
||||||
mode = "0400";
|
|
||||||
};
|
|
||||||
sops.secrets."${cfg.secrets.sshUserCaKey}" = {
|
|
||||||
sopsFile = cfg.secrets.sopsFile;
|
|
||||||
owner = "step-ca";
|
|
||||||
group = "step-ca";
|
|
||||||
mode = "0400";
|
|
||||||
};
|
|
||||||
|
|
||||||
# https://github.com/NixOS/nixpkgs/blob/nixos-23.05/nixos/modules/services/security/step-ca.nix
|
|
||||||
services.step-ca = {
|
|
||||||
enable = true;
|
|
||||||
openFirewall = true;
|
|
||||||
address = "0.0.0.0";
|
|
||||||
port = 443;
|
|
||||||
intermediatePasswordFile = caPasswordPath;
|
|
||||||
|
|
||||||
# https://smallstep.com/docs/step-ca/configuration/#configuration-options
|
|
||||||
settings = {
|
|
||||||
root = cfg.rootCertPath;
|
root = cfg.rootCertPath;
|
||||||
crt = intermediateCrtPath;
|
crt = intermediateCrtPath;
|
||||||
key = intermediateKeyPath;
|
key = intermediateKeyPath;
|
||||||
|
address = "${caAddress}:${toString caPort}";
|
||||||
dnsNames = cfg.dnsNames;
|
dnsNames = cfg.dnsNames;
|
||||||
|
|
||||||
ssh = {
|
ssh = {
|
||||||
@@ -129,7 +55,7 @@
|
|||||||
x = "zFO8hPx_eH0Iyz7UJI-w8ODMusEKCZ28M76sGWmWYxA";
|
x = "zFO8hPx_eH0Iyz7UJI-w8ODMusEKCZ28M76sGWmWYxA";
|
||||||
y = "XIWLLyKDzqxV9UH-2KeAkKPDrgLoPrxxW9-PzkXggME";
|
y = "XIWLLyKDzqxV9UH-2KeAkKPDrgLoPrxxW9-PzkXggME";
|
||||||
};
|
};
|
||||||
encryptedKey = "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJjdHkiOiJqd2sranNvbiIsImVuYyI6IkEyNTZHQ00iLCJwMmMiOjYwMDAwMCwicDJzIjoiUVJnTnJVTF9KcmxJYkJMVTlGNVRPZyJ9.DMu7xBNCq5pr-_--YTxNr5Hrcqy6ZmSVHsWurfVXL7Hk0Q3vyYRxiw.h-CnFiYc-DhxThI3.plx3_Qa_0kU-2TwnqFNfAfGnCpfQ2e0iiCMLruNHbLMnHeXQ1BysHBqps45_02zZXIRdHoDgYGtXRSfcdUYYoS0pLoPzC6m301ZFNSAFdRVlSZ3Q6VmWdixPXXnEB4EgSKTT_wxR33L8t9OpFzD85KfY-b_Un1l99ufjCnfg-EYkcICTn_G4-8bcW3eFIvJ6setzu-l0jHMhLQdIweqncn9on9xBXBD-ANhZfP95P2BJt-APqCi8eqiAvn_vClovdg0PxzRwOVDvWREz66FDw-HTU7xDtGO9hACopT5tfZOXDoykgZw1mJsq9NEq9ZzvKG2hvyk1UXtExxrNtFo.5q1OfGU4Amo4Si-vpeI42g";
|
encryptedKey = adminProvisionerEncryptedKeyValue;
|
||||||
claims = {
|
claims = {
|
||||||
enableSSHCA = true;
|
enableSSHCA = true;
|
||||||
disableRenewal = false;
|
disableRenewal = false;
|
||||||
@@ -154,7 +80,115 @@
|
|||||||
renegotiation = false;
|
renegotiation = false;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.step-ca = {
|
||||||
|
rootCertPath = lib.mkOption {
|
||||||
|
description = "Path to the Step CA root certificate served by this host.";
|
||||||
|
type = lib.types.path;
|
||||||
};
|
};
|
||||||
|
dnsNames = lib.mkOption {
|
||||||
|
description = "DNS names and IP SANs advertised by this Step CA instance.";
|
||||||
|
type = with lib.types; listOf str;
|
||||||
|
};
|
||||||
|
secrets = {
|
||||||
|
sopsFile = lib.mkOption {
|
||||||
|
description = "Host-local SOPS file that stores Step CA secret material.";
|
||||||
|
type = lib.types.path;
|
||||||
|
};
|
||||||
|
caPassword = lib.mkOption {
|
||||||
|
description = "SOPS key for the Step CA intermediate password.";
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
intermediateCrt = lib.mkOption {
|
||||||
|
description = "SOPS key for the Step CA intermediate certificate.";
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
intermediateKey = lib.mkOption {
|
||||||
|
description = "SOPS key for the Step CA intermediate private key.";
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
sshHostCaKey = lib.mkOption {
|
||||||
|
description = "SOPS key for the Step SSH host CA private key.";
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
sshUserCaKey = lib.mkOption {
|
||||||
|
description = "SOPS key for the Step SSH user CA private key.";
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
adminProvisionerEncryptedKey = lib.mkOption {
|
||||||
|
description = "SOPS key for the Step CA admin provisioner encrypted key.";
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
# Placeholders are expected initially until real material is inserted into sops.
|
||||||
|
sops.secrets."${cfg.secrets.caPassword}" = {
|
||||||
|
sopsFile = cfg.secrets.sopsFile;
|
||||||
|
owner = "step-ca";
|
||||||
|
group = "step-ca";
|
||||||
|
mode = "0400";
|
||||||
|
restartUnits = [ "step-ca.service" ];
|
||||||
|
};
|
||||||
|
sops.secrets."${cfg.secrets.intermediateCrt}" = {
|
||||||
|
sopsFile = cfg.secrets.sopsFile;
|
||||||
|
owner = "step-ca";
|
||||||
|
group = "step-ca";
|
||||||
|
mode = "0400";
|
||||||
|
restartUnits = [ "step-ca.service" ];
|
||||||
|
};
|
||||||
|
sops.secrets."${cfg.secrets.intermediateKey}" = {
|
||||||
|
sopsFile = cfg.secrets.sopsFile;
|
||||||
|
owner = "step-ca";
|
||||||
|
group = "step-ca";
|
||||||
|
mode = "0400";
|
||||||
|
restartUnits = [ "step-ca.service" ];
|
||||||
|
};
|
||||||
|
sops.secrets."${cfg.secrets.sshHostCaKey}" = {
|
||||||
|
sopsFile = cfg.secrets.sopsFile;
|
||||||
|
owner = "step-ca";
|
||||||
|
group = "step-ca";
|
||||||
|
mode = "0400";
|
||||||
|
restartUnits = [ "step-ca.service" ];
|
||||||
|
};
|
||||||
|
sops.secrets."${cfg.secrets.sshUserCaKey}" = {
|
||||||
|
sopsFile = cfg.secrets.sopsFile;
|
||||||
|
owner = "step-ca";
|
||||||
|
group = "step-ca";
|
||||||
|
mode = "0400";
|
||||||
|
restartUnits = [ "step-ca.service" ];
|
||||||
|
};
|
||||||
|
sops.secrets."${cfg.secrets.adminProvisionerEncryptedKey}" = {
|
||||||
|
sopsFile = cfg.secrets.sopsFile;
|
||||||
|
owner = "step-ca";
|
||||||
|
group = "step-ca";
|
||||||
|
mode = "0400";
|
||||||
|
restartUnits = [ "step-ca.service" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
sops.templates."step-ca-config" = {
|
||||||
|
owner = "step-ca";
|
||||||
|
group = "step-ca";
|
||||||
|
mode = "0400";
|
||||||
|
content = renderedStepCaConfig;
|
||||||
|
};
|
||||||
|
|
||||||
|
# https://github.com/NixOS/nixpkgs/blob/nixos-23.05/nixos/modules/services/security/step-ca.nix
|
||||||
|
services.step-ca = {
|
||||||
|
enable = true;
|
||||||
|
openFirewall = true;
|
||||||
|
address = caAddress;
|
||||||
|
port = caPort;
|
||||||
|
intermediatePasswordFile = caPasswordPath;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Keep modules/services/step-ca/ca.json as reference-only; runtime config comes from SOPS template.
|
||||||
|
environment.etc."smallstep/ca.json".source =
|
||||||
|
lib.mkForce config.sops.templates."step-ca-config".path;
|
||||||
|
systemd.services.step-ca.restartTriggers =
|
||||||
|
lib.mkAfter [ config.sops.templates."step-ca-config".path ];
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
step-ca
|
step-ca
|
||||||
|
|||||||
Reference in New Issue
Block a user