Repository navigation
native2: approve a background agent by its signed program (#194) - #218
Merged
Merged
Conversation
When no app is among the client's ancestors and they reach launchd, as for a claude --bg job, the caller is the nearest team-signed program that isn't a launcher, such as Claude Code, keyed by team and identifier as before. The prompt says it is a program, not an app. With no such program the refusal says why and what to do. A team counts only from an Apple-issued certificate. Why: native2/Sources/DesktopHost/Admission.swift#func resolution | with no app above the client and the walk reaching launchd, only a team-signed program may be the caller, since an unsigned one or a bare path can't be told apart from anything else the user runs in the background; owner decision on #194 Why: native2/Sources/DesktopHost/Admission.swift#func identify | a caller's team counts only when it satisfies anchor apple generic with that leaf OU: any signer can write a team ID into a self-signed certificate, and approvals are keyed team:identifier
iamnbutler
force-pushed
the
fix-bg-callers
branch
from
October 25, 2026 00:36
f89d537 to
983682f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #194
Implements the owner's decision on #194.
claude --bgjob: node →claude bg-spare→claude bg-pty-host→claude daemon, ppid 1), the caller is the nearest program that isn't a launcher and is signed by a developer team, e.g. Claude Code. Its approval is keyedteam:<team>:<identifier>as before, so it's the same entry as the foregroundclaude-codeapproval. Chains with an app (a terminal) are unchanged..appgets "Allow the program name to control this Mac?" and a line saying it's a command-line program, not an app, and that every agent it runs, in a terminal or in the background, could use Desktop Tools. (app.swiftis copied tonative/sources/app/too, since scripts.test.mjs keeps the two identical.)CALLER_NOT_APPROVEDwith no prompt, but now names the processes it found and why nothing can be approved:…its client's parent processes (bash > perl) reach launchd with no app and no program signed by a developer team among them…, and says to run from a terminal app or a signed program.anchor apple generic and certificate leaf[subject.OU] = <team>. Before this, any valid signature counted, so a self-signed certificate with a forged OU could take an approvedteam:…key. Legitimate Developer ID and Apple Development callers keep the same keys.npx/nodeby absolute path (or use the app'sdesktop-tools-mcp).Couldn't reproduce the reported "couldn't identify". On this Mac, a real
claude --bgjob running the dev app's client was served on main's code as well as this branch's: the chain resolved toclaude-code, which was already approved. So the original failure must have had another cause, perhaps a parent whose executable couldn't be read. Any remaining "couldn't identify" case now falls through to the generic refusal.Checked:
swift build -c release,swift test(refusal text tests),npm test. On the dev app (npm run dev-app -- --native2): a realclaude --bgjob is served asclaude-code; a foreground call still works; a client whose parent is launchd and a client under a detached perl get the new refusal text. The new "program" prompt wasn't shown live, since that would put a prompt on the user's screen for an unapproved signed binary.