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

120 lines
4.8 KiB
Markdown

---
name: nixbuild-settings
description: |
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".
disable-model-invocation: false
allowed-tools: 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
```bash
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)
```bash
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:
```bash
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
```bash
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
```bash
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.