-
Notifications
You must be signed in to change notification settings - Fork 46
Document NixOS as a supported OS for the Smallstep Agent #540
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
joshdrake
wants to merge
3
commits into
main
Choose a base branch
from
docs/nixos-agent
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+187
−3
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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. | ||
|
|
||
| <Alert severity="info"> | ||
| <div> | ||
| 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 <code>/dev/tpmrm0</code> cannot enroll yet. | ||
| </div> | ||
| </Alert> | ||
|
|
||
| 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: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since this is just a static file, let's throw it into S3 and have them download it. |
||
|
|
||
| ```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). | ||
| </Alert> | ||
|
|
||
| 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 | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But nixos-unstable is currently the only channel it's available on?