Each of these overrode a value nothing else set at a higher priority:
- qemu-guest: btrbk, hardwareTools and cloud-init have no competing
definition on the guests.
- mdns: nixpkgs' sunshine module sets avahi.publish.* with mkDefault.
- computer-use: i18n now sets the time zone with mkDefault.
- darwin terminal: the shared ghostty/kitty font sizes are now mkDefault.
- shoukei: sunshine is mkDefault false in remote-desktop.nix, zram's
memoryPercent is mkDefault 50; supportedFilesystems now merges instead
of discarding the fsType entries other modules add.
- youko: nothing enables docker.
- nixpak: pasta.enable and sockets.pipewire are mkDefault in the shared
modules, sockets.pulse already was.
Every NixOS host's toplevel drvPath is unchanged; on fern and frieren the
terminal font sizes and time zone evaluate to the same values.
Assisted-by: Claude Code (claude-opus-5-5)
* feat(nixpak): sandbox six desktop apps
* chore(nixpak): trim OBS plugin set
* fix(nixpak): enable OBS on aarch64
* fix(nixpak): let imv read the full home directory
* fix(home): drop redundant freerdp package
* fix(nixpak): grant OBS access to V4L2 camera devices
* fix(nixpak): expose V4L2 sysfs to OBS
* fix(nixpak): expose NVIDIA encode library to OBS
* docs(nixpak): record OBS interactive validation
* docs(nixpak): record OBS RTMP validation
* fix(nixpak): run MuseScore via XWayland and PulseAudio
* docs(nixpak): explain app sandboxing rationale
* fix(nixpak): route MuseScore ALSA through PipeWire
* refactor(nixpak): split policy checks into per-app suites
Make hardening/tests/policy.nix a small loader that auto-discovers one suite per app under hardening/tests/policy. Shared checks live in policy-lib.nix and common expectations are generated by mkAppPolicy; app files only declare differences and special cases. The loader also discovers wrappers from hardening/nixpaks and fails when wrapper/suite inventory or check names diverge.
Assisted-by: DeepSeek Harness (deepseek-flash)
* fix(nixpak): reject duplicate per-app policy checks
mkAppPolicy merges generated and custom checks, so an extraChecks key could silently override a standard assertion. Fail explicitly when a per-app check name is defined twice.
Assisted-by: DeepSeek Harness (deepseek-flash)
Merge the three runtime-validation files into one concise record, update the interactive browser and Zoom results, and document the intentional Chromium host-loopback and Brave/Edge no-media exceptions. Tighten the remaining cookie-crypto workaround and the smoke-test prerequisites.
Assisted-by: DeepSeek Harness (deepseek-flash)
Switch to the native deb package from nixpkgs-patched (#560225), remove the AppImage/FHS bwrap layer, and enable native Wayland while keeping the X11 fallback.
Keep only WeChat state under one app-scoped HOME and bind the host Documents and Downloads directories like the other desktop apps. User-selected files also go through the XDG FileChooser portal. Remove the launcher, activation script, and compatibility symlinks.
Assisted-by: DeepSeek Harness (deepseek-flash)
* refactor(nixpak): unify desktop app sandboxes
Move common GUI, portal, and network policy into reusable modules and migrate browsers plus Zoom/WeChat/QQ/Telegram to the same boundary.
Assisted-by: DeepSeek Harness (deepseek-flash)
* fix(nixpak): stop exposing the system D-Bus to apps
* fix(nixpak): bind only the PulseAudio socket
* feat(nixpak): run apps in a new session tied to the launcher
* feat(nixpak): start apps from an allowlisted environment
* feat(nixpak): isolate app networking with pasta
* fix(nixpak): keep Firefox on the host network
Assisted-by: Claude Code (claude-opus-5-5)
The abort needs havePrivateMountNs == false AND /nix/store still ro:
remountReadOnlyWritable() returns early while the store is writable. Nix
<= 2.34 left it rw until reboot; 2.35 remounts in a private namespace, so
only a freshly booted host hits it. The repro command also uses an open-only
exec 7<..., since cat fails on the read even when the open succeeds.
While here, trim the comments and drop the disabled default_deny/nix
policies plus the explicit killUnconfinedConfinables=false (nixpkgs
default). 82 -> 34 lines.
Nix 2.35's root nix-env -- used by nixos-rebuild to set the system profile --
calls saveMountNamespace(), which opens /proc/self/ns/mnt before remounting
the read-only /nix/store writable. Those magic links have no connected path,
so AppArmor cannot match them against any rule and denies the open with
EACCES even in complain mode. The private mount namespace is then never
created and nixos-rebuild aborts with:
cannot remount "/nix/store" writable: not in a private mount namespace
Adding flags=(attach_disconnected) lets AppArmor re-root those paths on / so
the existing `file /**` rule matches. This also fixes any other sudo'd tool
that needs namespaces (unshare, nsenter, bwrap, ...).
Rolling this out to a host that already has the old profile loaded needs one
deploy with --no-reexec, so the current system's Nix performs nix-env --set
instead of the new system's; after that generation is active, plain
`just niri` works and the Nix version is never rolled back.
Reuse the already-extracted, libtiff-patched AppImage from the nixpkgs wechat package (`wechat.src`) instead of keeping our own CDN URLs and hashes, which had to be refreshed whenever Tencent replaced the versionless files. Take the package from nixpkgs-master, which carries the newest builds.
- wechat.nix: repacking is needed because nixpkgs' wechat package does not expose its AppImage wrapper args for `.override`, not because wrapAppImage lacks overriding (it forwards args to buildFHSEnv).
- peripherals.nix: drop a link to an already-closed issue and fix a typo.
The sandbox remaps XDG_DATA_HOME/XDG_CONFIG_HOME, so paths Firefox exposes to
or shares with the host ended up isolated. Bind the MPRIS artwork dir and the
real trash rw, and mimeapps.list, user-dirs.dirs and the shared NSS cert store
ro.
recently-used.xbel stays isolated: GTK writes it atomically, which a
single-file rw bind would break.
Tencent replaced the file behind the versionless CDN URLs, so the pinned hashes stopped matching. Refresh the x86_64 and aarch64 hashes with nix store prefetch-file.
The broad 'file /** rwlkUx' rule conflicts with rix exec rules pulled in
via nested abstractions (xdg-open): AppArmor 5.0 rejects merged rules
with differing exec modifiers, failing apparmor.service on first load.
* security: make firewall secure-by-default, disable explicitly on servers
Flip the base firewall default to ON so new hosts are protected by default. Servers keep the firewall off (trusted internal LAN, WAN protected at the router) via explicit overrides in modules/nixos/server/{server,server-aarch64}.nix. Behavior-preserving for all 18 current hosts; adds a security-firewall eval test guarding the per-host state.
* test: fix security-firewall eval test to scalar per-host values
* security: enable AppArmor (complain) on all Linux hosts
* security: bind aquamarine metrics exporters to loopback
* security: restrict k3s kubeconfig file mode to 600
* security: disable SSH X11 forwarding on servers, keep on desktops
* security: add conservative systemd hardening to aquamarine services
* docs(apparmor): correct FHS-alias comment (nixpkgs has no broad FHS layer)
nixpkgs only creates /run/current-system, /usr/bin/env and /bin/sh; it does not
provide a broad FHS->store alias tree, so FHS-oriented abstractions are incomplete
on NixOS. They are safe only because the profiles run in complain mode.
* fix(aquamarine): scrape same-host exporters over loopback
The v2ray/postgres/sftpgo exporters were bound to 127.0.0.1 but VictoriaMetrics
scraped them via the host's routable IP, so those scrapes refused connections.
Point the three same-host scrape targets at 127.0.0.1 (VM runs on the same host).
node-exporter keeps the host IP since it binds 0.0.0.0.
* Revert "security: add conservative systemd hardening to aquamarine services"
This reverts commit f9cf99dadb.
* feat: comment out nixpkgs-unstable, we use unstable by default
Signed-off-by: Ryan Yin <xiaoyin_c@qq.com>
* fix: typo...
---------
Signed-off-by: Ryan Yin <xiaoyin_c@qq.com>