gcx stores its OAuth access and refresh tokens in the system keychain unconditionally -- its config file keeps only opaque `keychain:gcx:v2:...` handles -- and exposes no plaintext fallback. With nothing owning org.freedesktop.secrets on this headless WSL box, `gcx login` authenticates against Grafana and then dies writing its config: "The name is not activatable". Add services.headlessSecretService: gnome-keyring as a systemd --user service, unlocking the login keyring at start. home-manager's own services.gnome-keyring does not fit here on two counts -- it is WantedBy graphical-session-pre.target, which never activates without a desktop session, and it passes no --unlock, so writes would block on a GUI prompter that does not exist. Only the secrets component is started. The ssh component is deliberately off: it would claim SSH_AUTH_SOCK and displace services.ssh-agent, breaking SSH auth and signed commits. The unlock password defaults to a random one generated on first activation under $XDG_DATA_HOME. The passwordFile option is the seam for supplying it from an agenix secret instead, once that lands. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
3.8 KiB
Work WSL box — emmathorpe-edaas
Flake host: emmathorpe-edaas (x86_64-linux). NixOS running under
NixOS-WSL on the corporate Windows machine. Headless: no Sway desktop
(features.swayDesktop.enable = false), plain WSL shell login. Files:
configuration.nix.
What this host is
The day-to-day work environment. It layers the corporate Kubernetes / Helm /
Terraform / cloud toolchain and a couple of work-only editor language servers on
top of the shared home profile. The system config here is thin — it is mostly
WSL plumbing; the user-facing tooling lives in
../../users/emmathorpe/work.nix.
WSL specifics
wsl.enable, default useremmathorpe, Windows PATH interop and start-menu launchers on./etc/hostsgeneration is off (generateHosts = false).- Docker Desktop integration, not the native daemon as the primary path:
wsl.extraBinshims the coreutils/groupadd/usermodbinaries Docker Desktop'swsl-distro-proxyexpects, anddocker-desktop-proxy.scriptis patched to the real proxy path. The nativevirtualisation.dockeris also enabled (withenableOnBoot+autoPrune). programs.ssh.systemd-ssh-proxy.enable = false— the NixOS-WSL store is a read-only VHD owned bynobody, and OpenSSH rejects the generatedssh-proxyInclude as "Bad owner or permissions", which would break ssh/git for every command. The vsock proxy it provides is unused under WSL.networking.hostName = "emmathorpe-edaas"matches the flake attribute sonh os switchresolves without-H.
Renovate review timer
The host-table entry sets users.emmathorpe.linger = true so the user's
systemd --user instance stays alive without an open login session. That keeps
the daily headless Renovate PR review timer firing — defined in
../../users/emmathorpe/renovate-review.nix
(imported only from work.nix, so it exists on this machine alone). See that
file's header for the auth (Vertex AI ADC), triage policy, and caveats.
Secret Service (keychain)
work.nix sets services.headlessSecretService.enable = true, which runs
gnome-keyring as a systemd --user service owning org.freedesktop.secrets
on the session bus, with the login keyring unlocked at start.
This exists for gcx, the Grafana Cloud CLI. gcx stores its OAuth access and
refresh tokens in the keychain unconditionally (its config keeps only opaque
keychain:gcx:v2:... handles) and has no plaintext fallback, so without a
Secret Service gcx login authenticates and then fails to persist with "The
name is not activatable".
Home-manager's own services.gnome-keyring does not work here: it is
WantedBy=graphical-session-pre.target, which never activates on this headless
box, and it cannot unlock the keyring. See
../../home/secret-service.nix for the full
rationale and the security trade-off of an auto-unlocked keyring.
Only the secrets component is started. The ssh component is deliberately off
— it would claim SSH_AUTH_SOCK and displace services.ssh-agent, breaking SSH
auth and signed commits.
Checking it:
systemctl --user status headless-secret-service
busctl --user list | grep secrets # expect org.freedesktop.secrets
secret-tool search --all service gcx # inspect what gcx stored
gcx config check # end-to-end
If the keyring password is ever lost or changed, the login keyring cannot be
unlocked: delete ~/.local/share/keyrings and re-run gcx login.
stateVersion
system.stateVersion = "24.11" — the release this box was first installed on.
Leave it; it freezes stateful defaults and is not meant to track the current
nixpkgs.
Apply
sudo nixos-rebuild switch --flake .#emmathorpe-edaas
# or, since the hostname matches the attribute:
nh os switch