Server Schema
Server configuration defines SSH server connections stored in servers/<id>.json.
Schema
{
"id": "string",
"name": "string",
"host": "string",
"port": number,
"user": "string",
"identity_file": "string",
"kind": "string",
"auth": {
"mode": "key_controlmaster | key_plus_password_controlmaster",
"control_path": "string",
"persist": "string",
"persist_source": "configured | migrated | legacy_default (engine-owned output)"
},
"runner": {
"workspace_root": "string",
"homeboy_path": "string",
"daemon": boolean,
"concurrency_limit": number,
"artifact_policy": "string",
"require_exact_homeboy_version": boolean,
"require_fresh_runtime_overlay": boolean,
"policy": {
"snapshot_excludes": ["string"]
},
"env": {},
"secret_env": {},
"resources": {}
},
"forward_agent": boolean
}Fields
Required Fields
id(string): Unique server identifiername(string): Human-readable server namehost(string): Server hostname or IP addressuser(string): SSH username for authentication
Optional Fields
port(number): SSH port (default: 22)identity_file(string): Path to SSH private key file for authenticationkind(string): Optional server classification for extensions and project-specific behaviorauth(object): Optional SSH authentication/session policyrunner(object): Optional runner capability for Homeboy execution on this serverforward_agent(boolean): Enable SSH agent forwarding (default: false)
Example
{
"id": "production",
"name": "Production Server",
"host": "example.com",
"port": 22,
"user": "deploy",
"identity_file": "/Users/dev/.ssh/id_rsa",
"kind": "password-gated",
"auth": {
"mode": "key_plus_password_controlmaster",
"control_path": "~/.ssh/controlmasters/%h-%p-%r",
"persist": "4h"
},
"runner": {
"workspace_root": "/home/deploy/Developer",
"homeboy_path": "/usr/local/bin/homeboy",
"daemon": false,
"concurrency_limit": 4,
"artifact_policy": "copy",
"policy": {
"snapshot_excludes": ["generated-state", "generated-state/**"]
},
"env": {},
"secret_env": {},
"resources": {}
},
"forward_agent": true
}Runner Capability
Use homeboy runner enable <server_id> to make an SSH server runner-capable. The server ID is also the runner ID, matching the common runner-machine model: one machine, one server, one runner-capable server.
Runner Environment
Use runner.env for non-secret values that are safe to show in diagnostics, such as public artifact URLs:
{
"runner": {
"env": {
"HOMEBOY_PUBLIC_ARTIFACT_BASE_URL": "https://artifacts.example.test"
}
}
}Use runner.secret_env for values that must be read at execution time instead of stored in plaintext config. Each key is the environment variable exposed to the runner process. The value references either an environment variable visible to the Homeboy process on the runner or a file on the runner machine:
{
"runner": {
"secret_env": {
"OPENAI_API_KEY": { "env": "OPENAI_API_KEY" },
"SERVICE_TOKEN": { "file": "~/.config/homeboy/secrets/service-token" }
}
}
}Homeboy rejects likely credential names in newly persisted runner.env entries. Use secret_env for those values; it is also the explicit sensitivity declaration for non-obvious names. Existing legacy entries can be inspected without values using homeboy runner doctor <id> --scope secret-env and migrated into OS keychain-backed references with --repair. Homeboy command output redacts sensitive names in env and keeps secret_env as references only. Secret file contents and referenced environment variable values are not printed by runner config/status diagnostics.
Lab Offload Safety Gates
Two runner settings decide whether detected drift warns or refuses a Lab offload. Both default to unset, which means warn-and-proceed, and both have a per-run environment override:
| Setting | Env override | Default (unset) | When true |
|---|---|---|---|
require_exact_homeboy_version | HOMEBOY_REQUIRE_EXACT_RUNNER_VERSION | Patch drift within the same MAJOR.MINOR proceeds with a warning; MAJOR/MINOR drift refuses | The controller↔runner version gate requires a byte-identical Homeboy version on the runner |
require_fresh_runtime_overlay | HOMEBOY_REQUIRE_FRESH_RUNTIME_OVERLAY | A stale runtime-overlay build warns on stderr and the offload runs the old build | A runtime overlay whose built artifact is provably behind its source checkout refuses the offload |
{
"runner": {
"require_exact_homeboy_version": true,
"require_fresh_runtime_overlay": true
}
}Precedence for both is the same: a truthy environment value (1, true, yes, on) escalates that single run regardless of configuration; anything else — including a falsy value, which is indistinguishable from "not set for this run" — falls through to the runner setting, whose unset default is false. The environment variables are escalation overrides only, so neither can relax a runner configured strict.
require_fresh_runtime_overlay escalates only builds proven stale. An overlay whose freshness cannot be established — no containing checkout, no artifacts, or an unreadable source history — is reported as unknown and never refused. Freshness itself is derived from the artifact’s newest file mtime against the containing checkout’s history, which is an indication rather than a proof: a freshly created checkout rewrites mtimes and makes every artifact in it look newly built. Set this on runners where silently executing a stale build is worse than a failed dispatch.
Managed SSH Sessions
Key-authenticated servers can keep an explicitly bounded authenticated session available for unattended work:
{
"auth": {
"mode": "key_controlmaster",
"control_path": "~/.ssh/controlmasters/%h-%p-%r",
"persist": "8h"
}
}Run homeboy server connect <server_id> while the key is available. Later
commands attach to that control socket instead of requesting another key
signature. This is useful for hardware-backed or interactive key agents that
cannot sign while the controller session is locked.
Servers that accept a key and then require an operator-entered password can opt into managed control-master reuse:
{
"auth": {
"mode": "key_plus_password_controlmaster",
"control_path": "~/.ssh/controlmasters/%h-%p-%r",
"persist": "4h"
}
}Homeboy never stores the password. Run homeboy server connect <server_id> to establish the interactive session, then later homeboy ssh, file transfer, deploy, logs, and other server-backed commands reuse the active SSH control master.
auth.persist is required when adding a managed-session policy. It is an OpenSSH ControlPersist value such as 4h, 1h30m, yes, or no; colon-form values are not accepted. This is the local control-socket idle lifetime, not a policy imposed by the remote server. A shorter lifetime reduces the time an authenticated socket remains usable; a longer lifetime avoids repeated interactive authentication.
persist_source is engine-owned output, not a configuration input. configured identifies an explicit persisted operator choice. legacy_default identifies an older omitted value still using its historic 4h behavior. Updating that legacy record with an explicit persist safely records migrated. homeboy server show and managed-session output report the effective value and source.
SSH Key Management
Homeboy manages SSH keys in two ways:
Identity Files
SSH keys referenced in identity_file should exist on the local filesystem. Common locations:
- macOS/Linux:
~/.ssh/id_rsa,~/.ssh/id_ed25519 - Windows:
%USERPROFILE%.sshid_rsa
Keychain Integration
SSH key passphrases are stored in the OS keychain:
- macOS: Keychain Access
- Linux: libsecret / gnome-keyring
- Windows: Windows Credential Manager
Homeboy automatically retrieves passphrases from the keychain when establishing SSH connections.
Storage Location
Servers are stored as individual JSON files under the OS config directory:
- macOS/Linux:
~/.config/homeboy/servers/<id>.json - Windows:
%APPDATA%homeboyservers<id>.json
SSH Key Generation
Generate a new SSH key pair:
ssh-keygen -t ed25519 -C "[email protected]"Copy the public key to the remote server:
ssh-copy-id user@hostnameOr manually:
cat ~/.ssh/id_ed25519.pub | ssh user@hostname "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"SSH Agent Forwarding
When forward_agent is enabled, SSH keys from your local agent are forwarded to the server. This allows:
- Git operations on the remote server using your local credentials
- Access to other servers that trust your SSH keys
- Reduced need for keys on remote servers
Enable agent forwarding cautiously – it grants the remote server access to your forwarded SSH identities.
Related
- Server command – Manage server configuration
- SSH key management – Detailed SSH key handling
- SSH command – Remote shell access