No Xcode project. Just swiftc, a few plists, and codesign — one script turns source into a signed app with an embedded System Extension.
./build.sh, produce a real signed NetFilterDemo.app, verify its signature — and then run it and hit the security wall on purpose. That wall is the whole point of Lesson 5.Everything here was run on this Mac while writing the course (macOS 15.7.4, Apple Silicon, your Apple Development identity). The output below is real.
security find-identity -p codesigning -v → grabs your first Apple Development cert automatically. Signing is mandatory: macOS will not load an unsigned System Extension.swiftc -module-name FilterExt Sources/Filter/*.swift -o …/filter — the -module-name is why the provider class is FilterExt.FilterDataProvider in the Info.plist.swiftc -framework SystemExtensions -framework NetworkExtension Sources/App/*.swift.Info.plist and place the binaries: the app at Contents/MacOS/, the extension at Contents/Library/SystemExtensions/…systemextension/ (the layout from Lesson 2).codesign the extension first (with ext.entitlements), then the app (with app.entitlements). Order matters: a containing bundle's signature covers its contents, so nested code must be signed first.The app needs com.apple.developer.system-extension.install (permission to ask for activation) plus the networkextension capability. The extension needs the networkextension capability plus app-sandbox. Same codesign --entitlements flag, two different plists.
Confirm the entitlements actually made it into the binary:
You've produced a properly structured, properly signed System Extension from the command line — the thing most people assume requires the full Xcode GUI. The bundle is real and valid.
Launch the container app. It should submit the activation request… but watch what actually happens:
The kernel's AMFI (Apple Mobile File Integrity) killed the process at launch. com.apple.developer.networking.networkextension is a restricted entitlement: AMFI refuses to run a binary that claims it unless a provisioning profile authorizes that claim. Your Apple Development cert signed it, but nothing provisioned it — so: instant SIGKILL.
Re-sign the same app with empty entitlements and it launches fine — then fails gracefully at a later, expected point:
| Build | Result | Meaning |
|---|---|---|
| Restricted NE entitlement, no profile | Killed: 9 (137) | AMFI: unauthorized restricted entitlement |
| Empty entitlements | runs, then code=2 | can't even ask to install without system-extension.install |
| Correct entitlements + provisioning profile | activates ✅ | Lesson 5 |
There is no SIP-on, provisioning-free way to run your own System Extension — that's by design, and it's why the App Store is full of trustworthy ones. To cross the wall you need either a provisioning profile (keeps SIP on — our path next lesson) or developer mode (which needs SIP off). Building and signing, though? Fully done, fully CLI, fully verified.
A bundle's signature seals its nested contents. If you signed the app first and then re-signed the extension, the app's seal would be invalid. Always sign inside-out: deepest code first.
128 + 9 = killed by SIGKILL. At launch with no output, it's AMFI rejecting a restricted entitlement that no provisioning profile authorizes.
com.apple.developer.system-extension.install (to request activation) and com.apple.developer.networking.networkextension (the capability). Without the first: OSSystemExtensionErrorDomain code=2.
No. swiftc + bundle assembly + codesign is enough to build and sign. Xcode mainly automates the provisioning step you'll do by hand next.
--options runtime (hardened runtime) does, or want to see the full build.sh walked line by line? Ask. Otherwise say "Lesson 5" — we cross the wall and watch your filter see live traffic.