Code identity
How Outbound names a program by its signature and path, and what changes when an app is updated or replaced.
Before Outbound can ask you about a connection or match a rule to it, it needs to know which program made the connection. It reads that from the running process, not from a name the process reports.
What Outbound reads about a program
Section titled “What Outbound reads about a program”For a connection, the network extension resolves the process and records:
- The executable path, for example
/Applications/Slack.app/Contents/MacOS/Slack. A helper nested inside a framework inside an app is attributed to the outermost.app, so “Google Chrome Helper” counts as Google Chrome. - The team identifier on a Developer ID or App Store certificate.
- The signing identifier, the code’s own name, such as
com.apple.Safari. - The code directory hash (cdhash), a fingerprint of the exact build.
- How the code is signed: by Apple, by the Mac App Store, by a Developer ID certificate with a team, ad hoc, or not at all.
The result is cached for that process instance (the same process id and start), so a long-running app is inspected once.
Signatures Outbound trusts
Section titled “Signatures Outbound trusts”A signing identifier on its own proves nothing: anyone can ad-hoc-sign a binary that claims to be com.apple.Safari. Outbound accepts a signing identifier when a team identifier on a Developer ID or App Store certificate backs it, or when the code carries Apple’s own signature and that signature checks out.
An ad-hoc signature can claim any team identifier, so Outbound drops the team and identifies that program by its path. A rule for an ad-hoc binary covers that path, not every binary that claims the same identifier. A self-signed certificate is treated the same way: nobody vouches for it.
A program with neither a signing identifier nor a path is never asked about and never allowed while Outbound is not running: those connections are blocked. When you answer an alert for a program that cannot be named, the answer applies to that connection only.
Apple-signed programs
Section titled “Apple-signed programs”Rules can match Apple-signed code by that signature rather than by path or hash. The signature travels with the bytes, so a copy made with cp is still Apple-signed. Only System Integrity Protection locations count:
- Apple apps: inside an
.appbundle under/System/Applications/,/System/Library/,/System/Cryptexes/,/System/Volumes/Preboot/Cryptexes/or/Library/Apple/. - System services: outside any
.app, under/System/,/usr/libexec/,/usr/sbin/or/Library/Apple/. The built-in group names daemons such asmDNSResponder,trustdandapsd.
Command-line tools in /usr/bin and /bin (curl, ssh, python3) are Apple-signed and are in neither group. Apple apps installed into /Applications, such as Xcode or Pages, are asked about like any other app.
When an app’s signature or path changes
Section titled “When an app’s signature or path changes”The app is updated in place. A normal update of an app in /Applications keeps the same code identity, so a code-identity rule still matches. For the layouts Outbound knows (Homebrew Cellars under /opt/homebrew/Cellar/ and /usr/local/Cellar/, and CoreSimulator runtimes), a rule you save from a versioned path is written as a pattern, so a Homebrew formula keeps matching after the version number in the path changes.
The binary at a path is replaced. A path rule that allows or asks can be pinned to the approved hash: it matches only code with that hash. Replace the binary and that rule stops matching. If some other rule would still allow or ask, and a pinned path’s hash has changed, Outbound sets that rule aside: Strict blocks the connection, and Learn and Ask ask about it, so you approve the new code yourself. If nobody answers, the connection is blocked. A block in Strict lands in Review as “Changed binary”. A block is never narrowed this way. Whatever runs at a blocked path stays blocked. In Learn and Ask, a replaced pinned binary is asked about even when no other rule matches.
The developer re-signs with a different team. A code-identity rule names a specific team and signing identifier, so code signed by a different team no longer matches it. When no other rule matches, Outbound treats that code as an unknown program: Learn allows it and files it in Review, Ask asks, and Strict blocks it.
The developer’s name
Section titled “The developer’s name”Where Outbound can, it shows who made an app: the name on the Developer ID certificate, such as “Slack Technologies, Inc.”, and only when that certificate validates for the same team the filter verified. An app Apple re-signed for the Mac App Store is shown as “the Mac App Store”. A self-made certificate that merely claims a company name is never shown.