External macOS worker for Tangled Spindle. nnabeyang.tngl.sh/spindle-agent

Files
README.md

spindle-agent #

spindle-agent is an experimental external worker for Tangled Spindle. The spa command connects outbound to a compatible Spindle Gateway and runs explicitly allowed jobs on macOS. The binary release supports native execution. Its VM executor can run jobs in a separately prepared disposable Apple silicon macOS virtual machine. The 0.1.1 archive also carries the private host helper and matched guest kit required by spa vm provisioning commands.

Warning

Version 0.1.x is an experimental dogfood release, not a production-ready sandbox. Native jobs execute arbitrary repository commands as the worker user. Use a dedicated non-administrator account with no personal data and allow only repositories and manual dispatchers you trust.

Compatibility #

The external-worker protocol is not currently supported by the public spindle.tangled.sh service. A compatible custom Spindle build is required. The canonical external-worker schema lives in Protocol/ExternalWorker. The exact Buf generator and SwiftProtobuf runtime are recorded in protocol.lock; the worker and server must use a wire-compatible schema revision.

The current transport, lifecycle, compatibility proposal, and known limits are documented in the External Worker Protocol Draft. This draft describes the compatible fork and is not an official Tangled protocol specification.

Capability Supported environment
Source package macOS 14 or later, Swift 6.3 or later
Homebrew binary Apple silicon, macOS 15 or later
Native executor macOS builds, XCTest, and configured Simulator runtimes
Virtual-machine executor Apple silicon and a separately provisioned macOS base bundle

The Homebrew package exposes only spa on PATH; its release archive also contains private host and guest components under libexec. Installing it does not create or modify a VM base. Operators use spa vm to prepare a separately owned base and complete macOS setup and Xcode installation. The binary-only VM provisioning contract defines the component, command, compatibility, validation, and upgrade boundaries. Do not treat this workflow as supported until its candidate has passed the documented end-to-end Pipeline validation.

Install from source #

Until a release artifact is published, install from a reviewed source checkout:

./install.sh
export PATH="$HOME/.swiftpm/bin:$PATH"
spa --version

The prepared Homebrew release will use:

brew tap nnabeyang/tap \
  https://tangled.org/nnabeyang.tngl.sh/homebrew-tap
brew install nnabeyang/tap/spa

Do not use the Homebrew command until the corresponding release artifact and Formula have been published.

Configure and run #

Create an absolute mode 0600 JSON configuration and a separate private token file, then validate it before connecting:

spa check --config /absolute/path/to/spa.json
spa run --config /absolute/path/to/spa.json

See Configuration.md for the JSON contract and allowlist rules. See LaunchAgent.md for a dedicated-user LaunchAgent. Operators hosting the compatible Spindle and Cloudflare Tunnel on the same Mac should use MacOSSpindleStack.md.

Security model #

  • The worker makes an outbound authenticated WebSocket connection; it does not require an inbound port.
  • Repository DID, clone URL, event, full ref, and commit are checked before a workspace is created.
  • Tokens are read from private files and excluded from configuration reports and logs.
  • Native execution is not a sandbox and can reach services available to the worker account, including Keychain and GUI authorization services.
  • Pipeline logs are public on a public Spindle. Workflows must not print credentials or private host data.

Read SECURITY.md before operating a public worker. Known limitations are tracked in CHANGELOG.md.

Development #

./format.sh
./scripts/generate-worker-protocol.sh --check
./scripts/generate-protocol.sh --check
./scripts/generate-ci-protocol.sh --check
DEVELOPER_DIR=/Applications/Xcode-26.6.0-Release.Candidate.app/Contents/Developer \
  ./scripts/generate-documentation.sh --check
swift build
swift test
bash Tests/install-script-tests.sh

Generated protobuf and CI Lexicon sources must be regenerated from their repository-owned locked schemas; do not edit generated Swift files by hand. Contributions follow CONTRIBUTING.md.

License #

spindle-agent is available under the MIT License. Third-party notices are listed in THIRD_PARTY_NOTICES.md.