diff --git a/platform/smallstep-agent.mdx b/platform/smallstep-agent.mdx index c02a2d42..2a4ce41a 100644 --- a/platform/smallstep-agent.mdx +++ b/platform/smallstep-agent.mdx @@ -1,5 +1,5 @@ --- -updated_at: June 9, 2026 +updated_at: July 27, 2026 title: Install the Smallstep Agent html_title: Install the Smallstep Agent on macOS, Windows, and Linux description: Install, configure, and deploy the Smallstep Agent on macOS, Windows, and Linux endpoints. Includes manual install, MDM integration, system requirements, and network endpoints. @@ -47,6 +47,7 @@ Running into trouble? See the [Smallstep Agent troubleshooting guide](./troubles - Ubuntu (Current Stable and LTS) - Debian (Current Releases) - Fedora (Current Releases) + - NixOS - `systemd`-based service manager - A TPM 2.0 module is required. Smallstep depends on TPMs to create a high-assurance device inventory. - `p11-kit`, `tpm-tss2` @@ -284,6 +285,177 @@ curl -fsSL https://packages.smallstep.com/scripts/smallstep-agent-install.sh | s ``` +### NixOS + +The [`step-agent`](https://search.nixos.org/packages?query=step-agent) package is in nixpkgs, on the `nixos-unstable` channel. +NixOS has no `services.step-agent` module yet, +so the system user, systemd service, and PKCS#11 wiring that the Debian and RPM packages install are declared in your own configuration instead. + + +
+The agent requires a hardware TPM 2.0 on NixOS. +The Debian and RPM packages fall back to a software TPM on hosts without one, +but the helper scripts that set that up are not part of the nixpkgs package, +so a host with no /dev/tpmrm0 cannot enroll yet. +
+
+ +1. If you track a stable NixOS channel, add an overlay so that `pkgs.step-agent` resolves. + Skip this step on `nixos-unstable`. + + ```nix + nixpkgs.overlays = [ + (final: prev: { + inherit + (import (builtins.fetchTarball "https://github.com/NixOS/nixpkgs/archive/nixos-unstable.tar.gz") { + system = prev.stdenv.hostPlatform.system; + config.allowUnfreePredicate = pkg: prev.lib.getName pkg == "step-agent"; + }) + step-agent + ; + }) + ]; + ``` + +2. Save the following as `step-agent.nix` alongside your `configuration.nix`, + and add `./step-agent.nix` to its `imports` list: + + ```nix + { config, lib, pkgs, ... }: + + { + # The step-agent package is unfree. + nixpkgs.config.allowUnfreePredicate = pkg: lib.getName pkg == "step-agent"; + + environment.systemPackages = [ pkgs.step-agent ]; + + # The agent talks to the TPM from user space, so it needs read/write access + # to the TPM resource manager. This creates the tss group and the udev rules + # that grant that group /dev/tpmrm0. + security.tpm2.enable = true; + + users.groups.step-agent = { }; + users.users.step-agent = { + isSystemUser = true; + group = "step-agent"; + home = "/var/lib/step-agent"; + extraGroups = [ "tss" ]; + }; + + # /run/step-agent holds the PKCS#11 and SSH sockets that other users connect + # to. Create it with tmpfiles rather than systemd's RuntimeDirectory=, which + # deletes the directory every time the service stops. + systemd.tmpfiles.rules = [ + "d /run/step-agent 0755 step-agent step-agent - -" + ]; + + systemd.services.step-agent = { + description = "Smallstep Agent"; + documentation = [ "https://u.step.sm/docs/agent" ]; + after = [ "network-online.target" ]; + requires = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + + # The agent starts once the device is registered and agent.yaml exists. + unitConfig.ConditionPathIsReadWrite = "/etc/step-agent/agent.yaml"; + + environment = { + HOME = "/var/lib/step-agent"; + RUNTIME_DIRECTORY = "/run/step-agent"; + }; + + serviceConfig = { + Type = "notify"; + WatchdogSec = "60s"; + ExecStart = "${lib.getExe pkgs.step-agent} start"; + ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + User = "step-agent"; + Group = "step-agent"; + ConfigurationDirectory = "step-agent"; + StateDirectory = "step-agent"; + Restart = "always"; + RestartSec = 10; + + ProtectSystem = true; + ProtectHome = "read-only"; + PrivateTmp = true; + SecureBits = "keep-caps"; + AmbientCapabilities = [ "CAP_IPC_LOCK" "CAP_CHOWN" "CAP_DAC_OVERRIDE" "CAP_FOWNER" ]; + CapabilityBoundingSet = [ "CAP_SYSLOG" "CAP_IPC_LOCK" "CAP_CHOWN" "CAP_DAC_OVERRIDE" "CAP_FOWNER" ]; + DeviceAllow = [ "/dev/tpmrm0 rw" ]; + ReadWritePaths = [ "-/dev/tpmrm0" ]; + + LimitNOFILE = 65536; + LimitMEMLOCK = "infinity"; + }; + }; + + # Restart the agent when its configuration changes, such as after registering. + systemd.paths.step-agent-restart = { + wantedBy = [ "multi-user.target" ]; + pathConfig.PathChanged = "/etc/step-agent/agent.yaml"; + }; + + systemd.services.step-agent-restart.serviceConfig = { + Type = "oneshot"; + ExecStart = "${config.systemd.package}/bin/systemctl restart step-agent.service"; + }; + + # Let the agent restart units and manage NetworkManager connections. + security.polkit.enable = true; + security.polkit.extraConfig = '' + polkit.addRule(function(action, subject) { + if (subject.user == "step-agent") { + if (action.id == "org.freedesktop.systemd1.manage-units") { + return polkit.Result.YES; + } + if (action.id.indexOf("org.freedesktop.NetworkManager.") == 0) { + return polkit.Result.YES; + } + } + }); + ''; + + # Publish the agent's PKCS#11 server to p11-kit clients. The module path has + # to be explicit: the agent searches FHS locations that do not exist on NixOS. + environment.etc."pkcs11/modules/step-agent.module".text = '' + module: ${pkgs.p11-kit}/lib/pkcs11/p11-kit-client.so + server-address: unix:path=/run/step-agent/step-agent-pkcs11.sock + ''; + } + ``` + +3. Rebuild your system: + + ```bash + sudo nixos-rebuild switch + ``` + +4. Register the device with your team: + + ```bash + sudo step-agent register [team name] + ``` + + Registration writes `agent.yaml` into `/etc/step-agent`, + which systemd creates and keeps writable through `ConfigurationDirectory=`. + Do not manage `agent.yaml` with `environment.etc`: + that produces a read-only symlink into the Nix store, and the service refuses to start. + +5. Check that it was installed correctly: + + ```bash + step-agent version + ``` + + Output: + + ```bash + step-agent/0.67.3 (linux/amd64) + Release Date: 2026-05-19 15:50 UTC + ``` + + ## Registering and approving endpoints ### Self-registration @@ -327,6 +499,8 @@ sudo systemctl enable --now step-agent sudo systemctl enable --now step-agent-restart.path ``` +On NixOS, `nixos-rebuild switch` enables and starts both units, so skip this step. + If you get any errors, check the agent’s status: ```bash @@ -360,6 +534,9 @@ modutil -dbdir ~/.pki/nssdb -add step-agent \ Export `P11_KIT_SERVER_ADDRESS` and point it at the running agent's socket **before** you run `modutil`. `modutil` loads and initializes the module as it adds it, so running it first fails with a load error and can leave a broken module registered in the NSS database. If you hit this, see [Recovering from a failed `modutil` add](./troubleshooting-agent.mdx#recovering-from-a-failed-modutil-add). +On NixOS, `p11-kit-client.so` lives in the Nix store rather than under `/usr/lib`. +Point `modutil` at it with `-libfile $(nix eval --raw nixpkgs#p11-kit)/lib/pkcs11/p11-kit-client.so`. + Next, start Chrome from the command line. In Chrome, you should now have access to certificates managed by Smallstep. @@ -384,6 +561,8 @@ To uninstall the Smallstep Agent from a Linux system: sudo apt-get remove step-agent ``` + **For NixOS:** remove `./step-agent.nix` from your `imports` list, then run `sudo nixos-rebuild switch`. + 2. Optionally, remove configuration and certificate files: ```bash diff --git a/platform/troubleshooting-agent.mdx b/platform/troubleshooting-agent.mdx index 6c3db595..4ea7ff27 100644 --- a/platform/troubleshooting-agent.mdx +++ b/platform/troubleshooting-agent.mdx @@ -1,5 +1,5 @@ --- -updated_at: February 03, 2026 +updated_at: July 27, 2026 title: Troubleshooting Guide html_title: Smallstep Troubleshooting Guide description: Troubleshoot Smallstep Device Identity issues. Diagnose platform, MDM, and endpoint problems with step-by-step guidance. @@ -593,6 +593,11 @@ Quick reference for platform-specific commands and file locations. | Collect logs | `step-agent logs collect --log-dir /var/lib/step-agent/logs` | | Agent configuration | `/etc/step-agent/agent.yaml` | +On NixOS these paths are the same, with two differences. +There is no `/usr/bin/step-agent`: the binary is a Nix store path on your `PATH`. +And `step-agent doctor` reports p11-kit as missing unless the client module is registered by its store path, +as shown in [the NixOS install instructions](./smallstep-agent.mdx#nixos). + If the agent won't start, check for this message in the logs: ``` diff --git a/step-cli/installation.mdx b/step-cli/installation.mdx index a5fdf013..701af9db 100644 --- a/step-cli/installation.mdx +++ b/step-cli/installation.mdx @@ -124,7 +124,7 @@ Big shout out to the maintainers of these packages! We appreciate you. #### NixOS -Install the [`step-cli`](https://search.nixos.org/packages?channel=20.09&show=step-cli&from=0&size=50&sort=relevance&query=step-cli) package on NixOS. +Install the [`step-cli`](https://search.nixos.org/packages?show=step-cli&from=0&size=50&sort=relevance&query=step-cli) package on NixOS. #### FreeBSD