Machine settings: config.yaml
Machine settings live in $XDG_CONFIG_HOME/sparkwing/config.yaml, or
~/.config/sparkwing/config.yaml when XDG_CONFIG_HOME is absent.
SPARKWING_CONFIG selects another file. A present empty value is invalid.
SPARKWING_HOME selects runtime state and does not move machine settings.
Project declarations live in .sparkwing/sparkwing.yaml instead.
See Config reference.
Sections
| Section | Holds |
|---|---|
profiles | Named controller connections containing controller.url, an optional controller.token, and default: true to select an optional-profile CLI connection. |
repos | Registered checkout paths, fallback_paths, auto_register and include_worktrees. |
admission | Machine admission mode, budget and custom policy. |
runner | Controller URL, credentials_dir, permitted repos, labels and local capacity preferences. |
cache | Local binary-cache max_bytes and max_entries. Explicit zero disables a bound. |
machine | An optional box_id for standalone machine admission. |
debug | pause_timeout. |
run | submit_env_allow and the opt-in cache_from controller profile. |
The shared decoder validates the complete file before a section is used. Unknown keys, duplicate keys, explicit null and additional YAML documents fail with file, key and line information. A reader never accepts another section's invalid settings. Omission remains distinct from an explicit empty, false or zero value where the setting permits it.
profiles:
prod:
controller:
url: https://api.sparkwing.example
token: swk_...
repos:
repos:
- path: /srv/code/app
fallback_paths:
- ~/code
include_worktrees: true
admission:
mode: auto
budget: 50%,ignore-external
runner:
controller: https://api.sparkwing.example
credentials_dir: /srv/sparkwing/credentials
repos: [github.com/acme/app]
max_concurrent: 2
holder_prefix: desk
labels: [host=desk, gpu]
local_admission: true
cache:
max_bytes: 4GiB
machine:
box_id: rack-3-host-7
run:
submit_env_allow: [BUILD_REGION, BUILD_*]
pipeline trigger and Cloud-routed run capture only present variables matching
run.submit_env_allow. Empty values remain present. Literal names and terminal
_* prefixes are supported; a prefix needs at least two characters and must
start with a letter, so _* and A_* are refused as too broad. Credential-shaped and engine-owned names are
excluded. The controller encrypts the captured values separately from the run
spec and delivers them only to live execution awards. Retries keep the same
values. Planning, installation and execution use them, and values of at least
12 characters are masked before processes start. Public run views show only
names and an environment digest.
On a machine that runs other people's work, the same run.submit_env_allow
is the operator's list of submitted names it accepts. A submitted value under
any other name is dropped before a process starts; an empty list accepts none.
Cloud Jobs, here-hosted runs and the requester's own personal machines accept every submittable name. Go toolchain and
network base names cannot be submitted at all.
Connections come only from this machine file. A project can name a profile but
cannot define one. A controller command uses an explicit --profile first, then a saved default
when its profile flag is optional, then the local controller. Use --profile=
to select local for one invocation. See Controller connections.
Enrollment saves the machine's display name in runner.holder_prefix.
sparkwing-runner start --config PATH accepts this saved metadata. The Cloud
controller supplies the runner identity and claim holder for each award.
Controller-backed concurrency uses this persisted machine identity for box
scope, independently of machine.box_id and runner.local_admission. A local
controller uses its persisted local peer identity in its private store.
Runner labels
runner.labels lists custom labels this machine reports for job placement,
such as host=desk or gpu. They apply to everything the machine runs: work
an enrolled runner claims from a controller, and the machine's own local
sparkwing run work. A job with Requires("host=desk") runs locally on a
machine whose configuration lists host=desk, and waits on any other machine
with a status detail naming the missing label.
Labels are matching preferences the machine reports about itself. They never
grant pools, reserved secrets, trust or repository scope; those come from the
machine's credentials and the team's access rules. A label that names a granted
fact (name=, class=, location=, team=, pool= or local) has no
effect: matching uses the granted value instead. The daemon logs a warning for
each one when it starts, and sparkwing doctor reports it with its file and
line. Validation refuses a blank label and the sparkwing- prefix reserved for
Sparkwing Cloud. os= and arch= labels are accepted but never override the
platform the machine observes.
The local controller reads runner.labels when it starts. After changing them,
run sparkwing daemon restart --force so local runs report the new labels. An
enrolled runner reads them when its service starts.
Permissions and writes
The file carries credentials, so reads require an owner-only regular file.
Unix uses mode 0600. Windows checks the owning SID and DACL. Symlinks and
reparse points are refused.
Settings writers lock config.yaml.lock, reread the file, change their section
and atomically replace the file with an owner-only copy. Other sections and
their comments survive. A write that would leave a dangling YAML alias fails.
Profile mutations also preserve changes to other profiles made during a
controller probe or credential revocation.
A command running under a separate SPARKWING_HOME refuses to write the
machine's settings. Set SPARKWING_CONFIG to a file inside that home when
testing an isolated runtime.
Local secrets
Secret values are separate from the machine settings file. Use Secrets for credential storage and rotation.
Moving from the per-file settings
There is no automatic import or compatibility reader. Move settings into the
final sections above. Remove old agent, logs, fleet, allow_repos,
dispatch_wait and profile backend keys. Runner enrollment uses
sparkwing runners add and stores its credential in a private file under
runner.credentials_dir.
Enrollment leaves an omitted --max-concurrent unset in the file. The shared
runner settings resolver defaults it to one. An explicit positive value is
saved as supplied. Enrollment and removal validate the complete machine file.
Removal reads agent-token as an owner-only regular file and checks its
controller and runner selectors before stopping the service or revoking authority.
See the migration guide for controller-profile changes.