14 — Trust & Safety
The wedge is safety as a property, not a promise. This document covers the trust machinery that makes “fully local” verifiable.
Threat model
What we defend against:
- Malicious app at submission. A bad actor publishes an app that does something harmful — exfiltrates data, runs ransomware, mines crypto.
- Compromised account. A legitimate publisher’s account is taken over (phishing, leaked credentials); attacker pushes a malicious update.
- Compromised dev machine. Publisher’s laptop is compromised; build artifacts are tampered.
- Supply chain via dependencies. A model, tool, or component the app depends on is compromised.
- Compromised registry. The Locara registry itself is breached.
- Malicious “alternative” registry. A user adds a hostile third-party registry.
- Capability-creep updates. An app gradually expands capabilities in updates, without user noticing.
What we don’t defend against (out of scope):
- A user explicitly granting all permissions and installing a clearly-marked-malicious app.
- A user bypassing macOS Gatekeeper to install unsigned apps.
- Physical access attacks.
- Side-channel / timing / hardware attacks on inference.
Defense layers
1. Verified publisher identity
Threat: anonymous publishing → typosquatting, drive-by malware.
Defense:
- Locara accounts require GitHub OAuth (cheap identity).
- “Verified” badge requires DNS TXT verification of a domain.
- 2FA mandatory for all publishing actions.
- Account takeover triggers cool-down (see below).
2. Source-only submissions; CI builds the binary
Threat: compromised dev machine ships malicious binary.
Defense:
- Developer never uploads a binary. They submit a
(repo_url, commit_sha, manifest)triple. - Locara CI clones the source in a clean environment, builds, signs.
- Build is reproducible given the lockfile; reviewers can re-run independently.
- This eliminates “compromised dev machine” attacks from npm/PyPI.
3. Sigstore-style provenance attestations
Threat: tampered artifact in transit / at rest.
Defense:
- Every published artifact has a signed attestation:
(commit_sha, build_env, build_steps, artifact_sha, publisher_id). - Attestations stored in a public transparency log (Sigstore public good or self-hosted Rekor).
- The user’s macOS Gatekeeper verifies the Apple Developer ID signature before allowing first launch. The app’s own first-run code verifies the Sigstore provenance attestation against the registry’s public log.
- Tampering with the artifact requires forging the signature and the log entry — practically impossible.
4. Static analysis vs declared capabilities
Threat: app declares net: false but uses fetch() somewhere; declares limited fs scope but escapes it.
Defense:
- AST analyzer scans
src/**/*.ts(x)for capability-touching APIs. - Mismatches between declared capabilities and used capabilities are flagged.
- Some are hard errors (unconditional violations); some are warnings (dead-code branches that could be a problem).
- Hard errors block submission; warnings prompt human review.
5. Runtime enforcement (defense in depth)
Threat: static analysis missed something; or app uses dynamic technique to evade.
Defense:
- macOS App Sandbox: kernel denies syscalls outside declared entitlements.
- Tauri IPC: capability-gated commands; requests for undeclared commands fail.
- Locara plugin layer: re-checks scope on every call.
- Wasmtime sandbox: tools can only do what their WASI imports allow.
Three independent enforcement layers. Bypassing all three requires a cooperating bug in macOS + Tauri + Locara — vanishingly unlikely.
6. Capability cool-down on update
Threat: account takeover or insider threat; attacker pushes update that adds net: true and exfiltrates data on first run.
Defense:
| Change | Behavior |
|---|---|
| Patch update, no capability change | Auto-update if user enabled |
| Minor update, no capability change | User notification, optional auto-update |
| Capability expansion (new cap or broadened scope) | 7-day cool-down + explicit user re-consent before activation |
| Capability narrowing | Immediate, no consent required |
The cool-down means:
- New version is downloaded.
- Old version remains active for 7 days.
- During cool-down: user is notified (“Transcribe v0.2.0 wants to add: device.camera. Activate now or wait 7 days.”).
- After 7 days: user prompted again; can dismiss to defer indefinitely.
This catches account-takeover attacks: the legitimate publisher (or the community) has 7 days to notice, raise alarm, force-revoke the version. By the time the malicious capability would activate on user devices, the bad version is gone.
7. Kill-switch (revocation)
Threat: a malicious app slips through review.
Defense:
- Each Locara app, on launch, checks the registry’s revocation list (cached locally + refreshed periodically).
- A revoked version is uninstalled automatically; user is shown what happened.
- Revocation can target a specific version, all versions, or a specific publisher.
- Revocations are public, signed, logged — not silent.
This is better than npm’s left-pad-style memory-hole: the artifact stays available for forensics, but is marked malicious + blocked from running.
8. Anomaly detection
Threat: app behaves within declared capabilities but does so unusually (e.g., suddenly indexing 100k files when it normally indexes 100).
Defense (v2+):
- Locara runtime keeps a per-app baseline of capability use.
- Significant deviations surface in user-facing alerts (“Transcribe is reading 1000x more files than usual. Continue?”).
- Optional reporting back to Locara registry (anonymous, opt-in).
v1 ships without this; phase 4 onwards.
9. Public incident log
Threat: trust degrades when failures are hidden.
Defense:
- All takedowns, revocations, and security incidents are publicly disclosed.
- Postmortems published for any non-trivial incident.
- Transparency is the trust currency. A registry that hides incidents loses faster than one that admits them.
Code signing (macOS specifics)
Every Locara app artifact is signed by two keys:
- Apple Developer ID Application certificate owned by the Locara project. One certificate signs every app published through the registry. macOS Gatekeeper recognizes it as a trusted developer.
- Locara’s CI signing key (a separate key, Sigstore-style or Ed25519, attesting “this exact binary was built by Locara CI from this exact source commit”). Verified by the runtime + by user clients.
The user verifies both: a known-trusted developer ID and a reproducible-build attestation.
Publishers do NOT need their own Apple Developer Program enrollment. Apps are co-credited to publishers in the metadata + signed Info.plist (publisher name shown in macOS “Get Info” panel), but the legal signer of the binary is Locara. Publisher identity is verified separately via GitHub OAuth + optional DNS-TXT verification (see “Verified publisher identity” above).
This is similar to how:
- Many SaaS-built-app platforms sign apps on behalf of customers (Tauri Cloud, Capacitor builds, etc.).
- Mac App Store apps are co-credited to “Apple, Inc. (signing)” + the developer (named in metadata).
The Locara CI’s Apple Developer ID is treated as a trust-root credential and protected accordingly:
- Stored in CI Secret with hardware-backed access controls.
- Never present on a developer machine.
- Rotated annually or in response to incidents.
- Backed up via documented escrow process.
For Mac App Store distribution (optional, separate from the Locara registry), an individual publisher could submit their app independently — that’s their own Apple Dev relationship, separate from Locara’s. Most publishers won’t bother.
Notarization
All Locara-published apps are submitted to Apple for notarization. Notarization:
- Apple scans the binary for malware / known-bad patterns.
- Apple re-signs the binary with its notarization ticket.
- Gatekeeper allows installation without warnings.
Notarization is a requirement for Locara-distributed apps. Apps that fail notarization cannot publish.
Notarization is automated and per-app — Locara CI submits each new version to Apple as part of the build pipeline. Typical turnaround: 1–10 minutes. Apple’s notarization is not editorial review; it’s automated malware scanning.
Permission UI
When a user installs an app, the consent UI shows:
Install Transcribe?
This app can:
✓ Use your microphone (for live transcription)
✓ Read files you select (you choose what to transcribe)
✓ Use Whisper (1.4 GB local model)
This app cannot:
✗ Access the network
✗ Read other files on your Mac
✗ Access your camera, contacts, calendar
✗ Run code outside its sandbox
Verified publisher: kingtongchoo (Domain-verified)
Built by: Locara CI (provenance: github.com/...)
[Install] [Cancel]
Capability claims are verifiable, not marketing copy. Users can click any claim to see the underlying enforcement (manifest field, macOS entitlement).
Distribution outside the registry
Because each Locara app is a standalone signed .app bundle, distribution outside the registry is just normal Mac app distribution:
- A developer’s own website serves their
.dmg— works exactly the same as a registry download. - Homebrew Cask formula referencing the artifact — supported via the standard Cask process.
- Email attachment, USB drive, internal company mirror — all work, because the app is a normal Mac app.
The same trust mechanics travel with the artifact regardless of source:
- macOS Gatekeeper checks Apple’s notarization + Locara’s developer ID.
- The Locara framework code linked into the app enforces capabilities at runtime.
- The Sigstore provenance attestation is verifiable from anywhere.
What’s lost when distributing outside the registry:
- Kill-switch reach. The runtime checks the Locara registry’s revocation list on launch. If an app is revoked, the runtime refuses to run it — but only if the app can reach the registry’s revocation API. Apps in fully-disconnected environments simply cache the last-known revocation list. Off-registry distribution doesn’t escape the kill-switch; it just can’t get fresh data without network.
- Catalog discovery. Off-registry apps don’t appear on locara.app. Users have to know about them.
- Automated review. Off-registry apps haven’t been through Locara’s review pipeline. The runtime still enforces capabilities; users are warned that the app is “not from the Locara registry” on first launch.
See 15-distribution.md.
Account takeover response
If a publisher reports their account compromised:
- Locara immediately freezes that publisher’s apps from receiving updates.
- Recent versions enter “manual review” status.
- Cool-down on already-pushed unactivated updates is extended.
- Affected users are notified.
- If malicious code confirmed: revocation + kill-switch.
- Account access restored only after publisher proves identity (multi-channel verification).
Plan, document, run drills.
Open questions
- (open) Should we mandate that high-capability apps be open-source? Pro: independent auditability. Con: filters out legitimate proprietary apps.
- (open) Bug bounty program? Probably yes once user base justifies it (phase 4+). Joint with Sigstore / Apple bounty programs where applicable.
- (open) Should the kill-switch require multi-party authorization (project lead + community trustees)? Probably yes once community matures.
- (open) Hardware attestation (Apple Secure Enclave for app integrity)? Powerful but locks Locara harder to Apple. Defer.
Cross-references
- Capability model: 03-capabilities.md
- Capability cool-down rules: 03-capabilities.md
- Build pipeline / signing: 16-build.md
- Distribution / sideloading: 15-distribution.md
- npm supply chain lessons:
../notes/npm.md - macOS sandbox notes:
../notes/mac-app-store-sandbox.md