Files
claude-plugin-nixbuild/skills/nixbuild-settings/SKILL.md
T
Oleks cbcf122422 Initial commit: nixbuild.net operator plugin
Haiku ops agent + 3 tools (nbshell expect+PTY admin-shell driver, nbapi
read-only HTTP client, nb-substituters guarded cache manager) + 2 skills
(nixbuild-settings, nixbuild-usage). Encodes the two-control-surface model
and the path-style-substituter-URL gotcha.
2026-06-01 11:17:40 +03:00

4.8 KiB

name, description, disable-model-invocation, allowed-tools
name description disable-model-invocation allowed-tools
nixbuild-settings Manage nixbuild.net account settings over the interactive admin shell — binary-cache substituters, trusted public keys, SSH keys, and other account/SSH-key settings. Carries the guard rails for nixbuild's quirks: path-style substituter URLs are rejected (reach sub-path caches like Attic path-less instead), and the admin shell needs a real PTY (driven by the nbshell tool). Use when registering/removing a cache on nixbuild, adding a trusted public key, managing SSH keys, or reading/changing any `settings <SETTING>`. Trigger on "add a substituter to nixbuild", "register a cache on nixbuild", "nixbuild trusted key", "nixbuild ssh key", "change nixbuild settings", "nixbuild substituters". false Bash, Read, AskUserQuestion

nixbuild-settings — account settings via the admin shell

Owning agent: nixbuild:ops. Account administration lives ONLY behind nixbuild's interactive admin shell; the HTTP API cannot touch it. Drive the shell through the nbshell tool (real PTY via expect) — never hand-roll ssh (see the plugin's ops agent for why the obvious invocations all fail).

Tools live under ${CLAUDE_PLUGIN_ROOT}/bin.

Read current settings

nb-substituters list                          # substituters + trusted keys
nbshell 'settings substituters --show'
nbshell 'settings trusted-public-keys --show'
nbshell 'ssh-keys'                            # registered SSH keys + permissions
nbshell 'settings --help'                     # list every available SETTING

The full SETTING list includes: substituters, trusted-public-keys, caches, access-tokens, always-substitute, max-cpu, max-mem, default-permissions, signing-key-for-builds, timeout, and more. Read any with settings <SETTING> --show.

Register a binary cache (the common task)

nb-substituters add-cache <url> <public-key>

add-cache adds the substituter AND its trusted key, then re-shows both. It refuses path-style URLs before they reach the shell.

The path-style gotcha (apply, do not re-derive)

nixbuild's settings substituters --add accepts ONLY:

  • host-root HTTPS: https://host (NO path, no trailing slash)
  • s3://bucket/prefix
  • cachix://name

A path-style URL like https://host/cache-name (Attic, nix-serve) is rejected as "invalid substituter". To use such a cache you must expose it path-less: front it at a host root with a reverse proxy that rewrites /<hash>.narinfo and /nar/* into the cache namespace, then register that bare host.

Worked example (oleks fleet): Attic's native URL is https://nix-cache-custom.oleks.space/attic-infra-cache-k3s-1 (rejected). But oci-caddy.nix already serves it path-less at the root of nix-cache-custom.oleks.space, so register:

nb-substituters add-cache https://nix-cache-custom.oleks.space \
  attic-infra-cache-k3s-1:qYSNK3DmttQXCFqn1t50qoWGtQNPRFWq9mgQjD05DeU=

NCPS is plain host-root and just works: nb-substituters add-cache https://nix-cache-mirror.oleks.space nix-cache-mirror.oleks.space:v8rbmAnk5MrEunNCC0BxYUh21UALvCuR2lnuZrr0hHY=.

Why register account-side at all

builders-use-substitutes = true on the client does NOT forward the client's substituters to nixbuild — the remote uses ITS OWN substituters. So a cache only speeds up / cheapens remote builds when registered here, account-side.

Add only a key, or remove things

nb-substituters add-key <public-key>
nb-substituters remove <url>
nb-substituters remove-key <public-key>
nbshell 'settings substituters --reset'        # back to default (cache.nixos.org)

SSH keys and other raw settings

nbshell 'ssh-keys'                              # list keys + permission sets
nbshell 'settings <SETTING> --add <value>'      # generic add
nbshell 'settings <SETTING> --reset'            # generic reset

Per-key overrides: most settings take --ssh-key <SSH_KEY_ID> to scope to one key instead of the whole account.

Procedure (mutations)

  1. Read the current value first (--show) so you can show a before/after.
  2. State the exact command(s) you will run and confirm via AskUserQuestion — settings changes affect every build on the account.
  3. Apply through nb-substituters (preferred, guarded) or nbshell.
  4. Verify: re-show the setting and report the after-state. A successful add is silent; the proof is the --show afterwards.

Failure signals

  • invalid substituter → path-style URL; expose path-less (above).
  • Authorization failed … run:write → the SSH key in use lacks admin permission for the shell (or the command was sent as ssh args, not via nbshell). Use a full-access key.
  • nbshell prints nothing but errors → expect missing and no nix to fetch it; install expect or run where nix is available.