Skip to content
Great Blue Heron

Trans: Latin prefix implying “across” or “Beyond”, often used in gender nonconforming situations Scend: Archaic word describing a strong “surge” or “wave”, originating with 15th century english sailors Survival: 15th century english compound word describing an existence only worth transcending

Jess Sullivan

Little Zig Libraries for Fruit-Shaped Escape Hatches

· 2 min read · software

Zig C ABI bridge from Apple application code to Linux native capabilities

I’ve bumped into this quandry a few times, most recently in an ongoing side quest to fully port cmux emulator and multiplexer to a wide array of popular Linux distrobutions- I’d love help QAing these for a proper release, much to do.

The pattern is pretty boring, it is more exciting in my head I guess: build a small native library in Zig, expose a stable C ABI, keep the SwiftUI/AppKit/UIKit/Cocoa bits as the application shell on macOS, and make the native capability boundary portable enough that a Linux build can call the same conceptual surface without pretending to be an Apple app.

Docs for each of these live here:

macOS app shell
SwiftUI / AppKit / ObjC

small C ABI
owned by Zig

zig-crypto
std.crypto primitives

zig-notify
osascript / libnotify

zig-keychain
SecItem / Secret Service

zig-ctap2
IOKit HID / hidraw

Linux-native builds

I have been calling this “de-attestation” work as these 4 libraries represent structures require signed apple attestations to build, package and distribute; by snipping these stuctures out, I can retain the SwitftUI core toolchain and compilation structures for application itself, disabiguating only for target specific operations, such as CTAP2, DE notifications, Crypto etc. This does not mean weakening platform policy, the structures are still signable and attestable using normal GPG signatories. ^w^

LibraryWhat it ownsApple-ish analogLinux / portable path
zig-cryptoHashing, HMAC, AES-CBC, PBKDF2, P-256 ECDH, Ed25519, CSPRNGCryptoKit, CommonCrypto, SecRandomCopyBytesZig std.crypto, no system crypto dependency
zig-notifyLocal desktop notificationsUNUserNotificationCenter, AppleScript notification callslibnotify over D-Bus
zig-keychainGeneric secret storageKeychain Services SecItemAdd, SecItemCopyMatching, SecItemDeleteSecret Service / libsecret
zig-ctap2External authenticator CTAP2 over USB HIDAuthenticationServices-adjacent passkey/authenticator flows, IOKit HID accesshidraw and a direct CTAP2 stack

Zig not any more suited to this than Rust, C3, Odin or Hare perse, this is just the screwdriver I’ve adopted for tiny, native boundary code that can be audited, cross-compiled, documented, and called from nearly anything that understands C, which is most things.

Linux backendmacOS backendZig C ABIApp UILinux backendmacOS backendZig C ABIApp UIalt[macOS build][Linux build]store token / notify user / enumerate security keySecurity.framework, osascript, IOKit, std.cryptonarrow resultlibsecret, libnotify, hidraw, std.cryptonarrow resultstable app-facing response

These are not library / SwitUI ecosystem complete; stuff I have to aide in continued expansion:

  • SwiftPM/modulemap smoke tests so Swift can import the headers cleanly.
  • Objective-C sample code that shows the bridge without hand-waving.
  • Header nullability annotations so Swift sees nicer optional boundaries.
  • Migration examples from CryptoKit/CommonCrypto, UserNotifications, SecItem, and WebAuthn-ish request things.
  • Packaging examples for distro-ish Linux environments.

Huzzah, -Jess

Related Posts

Comments

Loading comments...