diff --git a/.github/instructions/step-ssh-host.instructions.md b/.github/instructions/step-ssh-host.instructions.md new file mode 100644 index 0000000..b4e6b0b --- /dev/null +++ b/.github/instructions/step-ssh-host.instructions.md @@ -0,0 +1,54 @@ +--- +description: "Use when modifying modules/services/step-ca/ssh-host.nix. Covers Step SSH host certificate wiring, secret key contract, and host-side expectations required by consumers." +name: "Step SSH Host Module Instructions" +applyTo: "modules/services/step-ca/ssh-host.nix" +--- + +# Step SSH Host Module Instructions + +Use this instruction when changing the shared NixOS module in modules/services/step-ca/ssh-host.nix. + +## Module Contract + +- Keep this module reusable across hosts; do not hard-code host-local file paths beyond SSH system paths under /etc/ssh. +- Preserve the option interface unless the task explicitly changes it: + - step-ssh-host.hostname (required host identity used for cert principals) + - step-ssh-host.provisioner (default: "admin") +- Keep imports = [ inputs.self.modules.nixos.ssh ] so OpenSSH host certificate settings stay composed through the shared SSH module. + +## Secret Key Contract + +- This module currently consumes `config.sops.secrets."janus/admin_jwk"` as the Step provisioner password file. +- Treat `janus/admin_jwk` as a public contract key name for current consumers. If you rename it, update all consumers and host secret files in the same change. +- Keep secret permissions strict (root ownership and 0400 mode). +- Do not assume a local sops file path in this module. The consuming host must define sops.defaultSopsFile. + +## Host Expectations + +When this module is enabled by a host, the host is expected to provide: + +- A working Step trust/bootstrap path (for example via janus-ca or equivalent trust material). +- `sops.defaultSopsFile` containing `janus.admin_jwk` (or equivalent if contract is intentionally changed everywhere). +- `step-ssh-host.hostname` matching deployed host identity and DNS naming expectations. + +## SSH Certificate Paths And Principals + +- Preserve the default host key path contract at `/etc/ssh/ssh_host_ed25519_key` unless task scope requires coordinated changes. +- Keep host certificate path aligned to `${sshKeyPath}-cert.pub`. +- Keep principal issuance based on hostname and hostname.john-stream.com unless domain policy is intentionally migrated. +- If changing key/cert filenames or principal naming, update `modules/services/ssh.nix` integration and host rollout notes in the same change. + +## Renewal Behavior + +- Maintain timer/service cadence unless explicitly requested: + - timer OnUnitActiveSec = 4h + - randomized delay enabled +- Keep explicit handling for step ssh needs-renewal return codes to avoid silent failures. +- If changing renewal semantics, document whether the service now only checks state or also performs certificate issuance. + +## Validation Checklist + +After editing this module, validate at least one consuming host with: + +1. nix eval .#nixosConfigurations.janus.config.system.build.toplevel.drvPath +2. nix build .#nixosConfigurations.janus.config.system.build.toplevel --no-link --dry-run