On this page
Desktop publisher and Developer ID
Stado owns the repeatable path from a desktop repository to a signed macOS release. The publisher runner builds on a registry-selected Darwin host; Weles performs the Account Holder browser trajectory; Skarbiec holds credentials and the reusable certificate bundle; GitHub receives only repository-scoped release secrets.
Prepare a repository
stado host publisher-runner bootstrap <repository> --json
This creates or reuses the repository's Sparkle key pair and publishes RELEASE_BOOTSTRAP_TOKEN, AC_API_KEY_ID, AC_API_ISSUER_ID, AC_API_KEY_P8, and SPARKLE_PRIVATE_KEY. Repeating the command preserves the existing Sparkle identity.
Install or reconcile the publisher
stado host publisher-runner install <target> \
--repository <repository> \
--json
target must resolve through the Stado registry to darwin-arm64. Stado installs the isolated stado-publisher account and launchd unit, registers the runner in GitHub's Default group, applies the publisher network policy, and reuses an existing .runner registration instead of requesting a new organization token. Repeat --repository to bootstrap every desktop product in the same run.
Inspect it with:
stado host publisher-runner status <target> --json
A ready publisher reports a running service and a Developer ID Application: identity in its dedicated keychain.
Prepare Apple challenge capture
Prepare and inspect the registered Darwin host without beginning Apple account
authorization. The workload capability replaced host gui-automation …, so
preparation is one declared plan against one declared kind:
cat > apple-only.json <<'PLAN'
{"schema":"wisent.gui-automation-plan.v1","operation":"grant-accessibility","apple_only":true}
PLAN
stado workload run gui-automation --target <target> --plan apple-only.json --json
stado workload status gui-automation --target <target> --json
The preparation command installs or reuses the signed Apple challenge helper
version 2, reconciles only its Accessibility grant, and runs its prompt-free
--preflight in the registry-bound user's exact Aqua session. It supplies the
registered host-account password to remote sudo -S over stdin rather than
prompting; without one it uses noninteractive sudo -n and returns the refusal.
apple_only leaves CuaDriver, its grants and runtime, autologin, and remote
management untouched.
Both JSON reports preserve target, ssh_target, the ordered items pairs,
and error. A successful preparation and subsequent status report include
apple-challenge-ready: yes; a partial failure still returns completed items
and its error, and must not be read as readiness.
This is helper preparation only. It does not request an Apple authorization, capture a code, issue a certificate, or prove that issuance ran. The Developer ID trajectory below is separately authorized and may require Apple sign-in, system consent, and Account Holder 2FA.
Issue or reuse Developer ID
The Account Holder credential must be a Skarbiec item named weles-apple-<name>-account, with email and password fields.
stado host publisher-runner developer-id <target> \
--account-item weles-apple-<name>-account \
--repository <repository> \
--json
For the first run Stado:
- creates a private key and CSR on the selected Mac;
- issues three one-use, one-hour Skarbiec capabilities bound to one authorization ID: Apple email fill, password fill, and 2FA;
- asks Weles to run
apple_create_developer_idon that exact host and agent; - imports Apple's certificate, verifies the
Developer ID Application:identity, and exports a password-protected PKCS#12 bundle; - stores the bundle as
desktop-release-developer-idin Skarbiec; - publishes
MACOS_CERT_P12,MACOS_CERT_PASSWORD, andMACOS_SIGN_IDENTITYto every named repository; - removes private key material from the host work directory.
Later runs reuse the stored bundle and only reconcile repository secrets. They do not repeat Account Holder 2FA.
Trust boundaries
The GitHub runner never receives the Apple Account password. Weles receives short-lived capability references rather than credential plaintext in action parameters. The private key is generated on the Mac, enters Skarbiec only inside the encrypted PKCS#12 bundle, and is removed after storage succeeds. Repository secrets contain release signing material, not the Account Holder credential.
Failure readings
cannot issue ... release platform— the selected target is notdarwin-arm64.Skarbiec refused Apple capability— capability issuance or its authorization binding failed.Weles API refused /run— the installed Weles action contract or placement policy does not admitapple_create_developer_id.Developer ID bundle export failed— Apple did not produce the certificate, or the certificate does not match the generated private key.GitHub repository secret ... failed— the certificate exists in Skarbiec, but the named repository has not received all signing fields.
The command is successful only when it returns status: issued or status: reused and names the Developer ID identity and every reconciled repository.
Source: this website