NixOS 18.09 makes execution and configuration boundaries explicit
NixOS 18.09 updates Nix and the system base while changing sandbox defaults, application wrappers, platform meanings, and Kubernetes permissions.
Enabling isolation for package builds does not isolate every application a user starts. NixOS 18.09 includes changes at both levels, but they have separate mechanisms and scope. The Jellyfish release notes, dated October 5, make nix.useSandbox true by default and introduce declarative Firejail wrappers for selected application binaries. Understanding the difference is more useful than treating both as one system-wide security switch.
The release updates Nix to 2.1, glibc to 2.27, and systemd to 239. Linux remains on the 4.14 LTS series and GCC remains at 7. Desktop updates include GNOME 3.28 and Plasma Desktop 5.13. Alongside those package changes, several configuration interfaces acquire more precise meanings or new defaults.
I am interested in NixOS because it lets infrastructure policy be expressed in configuration. That is valuable when the policy names what it controls. A build sandbox, an application launch wrapper, and a Kubernetes role binding operate at different points, so a useful configuration has to distinguish them.
A wrapper controls a particular launch path
The release notes show programs.firejail.wrappedBinaries mapping command names to application binaries. Enabling the module installs commands into the global path that invoke the selected binaries through Firejail. The attribute name determines the wrapper command, while the value identifies the actual executable.
{ lib, pkgs, ... }:
{
programs.firejail = {
enable = true;
wrappedBinaries.firefox = "${lib.getBin pkgs.firefox}/bin/firefox";
};
}
The module implementation at the release tag generates a small executable script for each mapping. That script calls /run/wrappers/bin/firejail with the selected application and forwards the command arguments. The module also configures the Firejail wrapper source and adds the generated commands to environment.systemPackages.
The option documentation identifies two consequences. Installing the original application binary into the same global environment can create file collisions. Applications launched from desktop files that specify an absolute binary path do not go through these generated wrappers. The wrapper arrangement therefore depends on which executable path the caller selects.
This is a concrete limit to what the declaration establishes. A command found through the configured global path can use the generated wrapper. Another caller can refer directly to an application binary by its store path. The module does not claim to intercept every possible invocation of that binary throughout the system.
The distinction helps explain the interface without overstating it. The mapping provides an explicit launch route with arguments forwarded to the selected program. It does not rewrite every desktop entry or replace the meaning of all executable references. The documented path and collision conditions are part of using the module correctly.
Build sandboxing belongs to the builder
The nix.useSandbox default concerns package builds. Its appearance in the same release as application wrappers does not give it the wrapper module scope, nor does installing a wrapper define how a package was built. The release notes list them independently because they configure different execution contexts.
A declarative system can express both choices, but a single statement that the machine is sandboxed would omit their subjects. One option selects the build setting. Another declaration creates named launch wrappers. That difference remains even when the same application is involved in a build and later in interactive use.
I prefer these mechanisms to be described by the operation they affect. It makes a configuration review more concrete, since the reader can ask whether a particular build uses the setting or whether a particular launch resolves through the wrapper. The module source gives an exact answer for its generated commands.
Platform names change meaning for cross builds
The release also changes stdenv.system and the top-level system in Nixpkgs to refer to the host platform instead of the build platform. For native builds those platforms coincide, so the notes say the change is not breaking there. Cross builds expose the difference and need the intended platform stated explicitly.
Code that needs the previous build-platform meaning can use stdenv.buildPlatform.system. The notes also deprecate top-level buildPlatform, hostPlatform, and targetPlatform in favour of their equivalents inside stdenv. These names make the role of the platform explicit within the package environment.
This is more than cosmetic terminology. A conditional selecting behaviour for the machine performing a build asks a different question from one selecting behaviour for the machine that runs the result. A name that worked for native builds can conceal that difference until cross compilation makes the two machines distinct.
The release notes separately qualify AArch64 Linux distribution support. They describe continuing efforts towards parity with x86_64 Linux, without claiming equivalence. Package-expression platform semantics and release-platform support are related concerns, but one does not prove the other. A cross-build interface can become clearer while the released system still has platform-specific limitations.
Package selection can include a license choice
Jellyfish updates the default Elasticsearch, Logstash, and Kibana packages to the 6.3 series. The notes explain that these packages include X-Pack under the Elastic License and require allowing unfree packages in Nixpkgs configuration. Free variants without X-Pack are available under names ending in -oss.
That means a package name can imply more than the upstream version. It also selects the included components and the corresponding licensing policy. A configuration that previously chose the ordinary attribute must account for the changed package contents and acceptance setting. The release provides distinct attributes for the free variants, so the choice can remain explicit.
The same notes describe older 5-series attributes as available alternatives after removing the 2-series packages. This is a package-set transition with several supported choices, not a statement that every existing deployment must adopt the same contents immediately. The appropriate attribute conveys which version and variant the system description selects.
Docker-related interfaces also become more precise. dockerTools.pullImage uses an image digest instead of a tag, requiring the fixed hash to be updated. dockerTools.buildImage defaults its tag to null, meaning the Nix output hash supplies the tag. These changes connect image selection or naming to a more specific identity than an unconstrained label alone.
Declarative changes meet existing cluster state
The Kubernetes package moves to 1.11, and the NixOS options change along with the integration. The API server address option becomes bindAddress, with its default changing from loopback to 0.0.0.0. That is both an option rename and a change in listening behaviour. Reading only the new option name would miss the exposure consequence of leaving its value unspecified.
Dashboard access changes to HTTPS, with public port 443 and container port 8443. The dashboard receives minimal RBAC permissions by default, while a separate option enables cluster-admin rights when desired. These defaults describe the intended new configuration, but the notes identify an additional requirement for existing clusters.
Revoking the prior privileges requires manually removing the existing dashboard ClusterRoleBinding. This is an example where producing new declarative configuration does not automatically erase every object previously created in an external system. The persistent cluster object has its own transition step, which the release documents explicitly.
That boundary matters to the claim made by an upgrade. A new default can govern newly created resources without proving that every existing resource has already acquired the same permissions. The documented removal requirement identifies the extra action needed for the revocation to take effect on an existing cluster.
User channels also enter the default NIX_PATH in this release. The notes demonstrate using a personally named channel in nix-build, nix-shell, and angle-bracket imports. This makes another source-selection boundary explicit, since a user channel can supply the package set used by an expression. It is a lookup convenience, without a claim that two separately updated channels necessarily identify the same package revisions.
Generated paths remain part of a module contract
The Diffie-Hellman parameter module gains a stateless mode that puts generated parameters in the Nix store instead of managing them under /var/lib/dhparams. The notes tell consumers to obtain the actual path through config.security.dhparams.params for the named entry. Hard-coding the old state directory would ignore the newly supported storage choice.
This follows the same requirement for precision as the other changes. A consumer should use the path the module declares, just as a cross-build expression should name the intended platform and an application caller should select the intended wrapper. NixOS 18.09 exposes those distinctions through its configuration interfaces, while documenting persistent resources whose migration remains separate from rebuilding the system.