Locara

13 — Security & Privacy

This is the synthesis doc for how the Locara design adds up to “secure and private by default.” It cross-references the implementation details that live in other docs and shows how each layer composes.

The wedge of Locara is defensible privacy — apps that demonstrably can’t betray the user. This is not just a registry policy; it’s a property of the architecture. This document explains why.

The “secure and private by default” thesis

A user installing a Locara app should be able to assume:

  1. The app cannot see anything outside its declared scope. Not other apps’ data, not arbitrary filesystem, not the network unless explicitly allowed.
  2. Nothing the app does leaves the device unless the manifest says so. No telemetry, no analytics, no remote logging, no model-fetch leaking content, no error reporting.
  3. The Locara framework itself does not phone home. Zero ambient telemetry from the runtime, the CLI, the dev panel, or the client.
  4. Data the app stores stays on disk in a per-app container, encrypted at rest by macOS FileVault (and optionally by the app via SQLCipher).
  5. What the app can do is verifiable — at install time, before clicking, the user sees exactly the capability surface and can compare it to what the app has declared.

These five properties are not promises. Each is enforced by an architectural choice. Below is each property mapped to its mechanism.

Privacy by architecture (the local-first dividend)

The “fully local” thesis isn’t just a marketing line — it’s a privacy property that emerges from where reads and writes go:

OperationWhere it goesPrivacy implication
LLM inferenceLocal weights, local memoryPrompts and outputs never leave the device
EmbeddingsLocal modelTexts being embedded never leave the device
TranscriptionLocal WhisperAudio never uploads anywhere
OCRLocal OCR modelDocument content stays on disk
Database reads/writesPer-app SQLite fileAll structured data is local
Vector searchLocal sqlite-vec / zvecQueries + matched content stay local
File readsmacOS Powerbox-mediatedOnly files the user explicitly picks
Tool executionWasmtime sandboxTools can only do what their imports allow
Logging~/Library/Logs/Locara/On disk, on device
Error reportingNone (no auto-reporting)User must explicitly export logs
Update checkManifest check via HTTPS to registryOnly “do you have a newer version?” — no app-internal data

Compare to a typical SaaS AI app:

OperationWhere it goes
LLM inferenceVendor’s GPU cluster
EmbeddingsVendor’s model server
TranscriptionVendor’s transcription API
OCRVendor’s OCR service
Database reads/writesVendor’s PostgreSQL
Vector searchVendor’s vector DB
File uploadsVendor’s S3
Tool executionVendor’s compute
LoggingVendor’s observability stack
Error reportingSentry / Datadog / etc.
TelemetryMixpanel / Amplitude / etc.

Every line in the SaaS column is a place data could leak, be subpoenaed, be breached, be analyzed for advertising, or be retained beyond what the user expects. In the Locara column, every line stays local by default.

This is the structural privacy advantage of local-first. It’s not “we promise not to look at your data” — it’s “your data is never on a system we operate in the first place.”

The “fully local” badge formalizes this: an app earns it when net: false, all models locally cached, and no tools requiring network. Auto-computed from manifest. See 03-capabilities.md.

Defense in depth — the layered security model

┌──────────────────────────────────────────────────────────┐
│ Layer 6: User consent (informed install + capability UI) │
├──────────────────────────────────────────────────────────┤
│ Layer 5: Capability cool-down on update                  │
├──────────────────────────────────────────────────────────┤
│ Layer 4: Locara registry review + signing + provenance   │
├──────────────────────────────────────────────────────────┤
│ Layer 3: Locara runtime capability enforcement           │
├──────────────────────────────────────────────────────────┤
│ Layer 2: Tauri IPC trust boundary (capability-gated)     │
├──────────────────────────────────────────────────────────┤
│ Layer 1: macOS App Sandbox (kernel enforcement)          │
└──────────────────────────────────────────────────────────┘

Each layer denies independently. Bypassing all six requires:

  • A bug in macOS kernel (Apple’s responsibility, frequently patched).
  • A bug in Tauri’s IPC layer.
  • A bug in Locara’s plugin enforcement.
  • A bug in Locara’s review pipeline.
  • A bypass of the cool-down clock.
  • A user explicitly clicking through clear consent UI.

This is what “defense in depth” actually means: not “we have lots of checks” but “an attacker has to compromise multiple independent systems.”

Secure-by-default checklist

Every default in Locara is the safe option. Here is what that looks like, surface by surface:

Manifest defaults

FieldDefaultRationale
capabilities.netfalseMost apps don’t need network. Earns “fully local” badge.
capabilities.fs.user-selectedread (when omitted, derived as needed)Powerbox-mediated; user explicitly picks files.
capabilities.device.*all falseTCC prompts only triggered if declared and used.
capabilities.tools[]No code-exec without explicit declaration.
capabilities.ipc[]No inter-app communication by default.
storage.backups.enabledfalseNo backups created without opt-in.
Custom toolsrejected unless reviewedOnly registry-curated tools by default.

Runtime defaults

BehaviorDefaultRationale
Model fetchingLocara runtime fetches; app cannot do its ownApps never need network for model loading; can’t sneak in extra fetches.
TelemetryNone, everPrivacy-as-pitch demands zero phone-home.
Crash reportsStored locally; user must export to shareNo automatic sentry-style upload.
Update checksManifest-only request to registry; no app-internal infoDaily by default; user can disable.
LoggingLocal file under ~/Library/Logs/Locara/Logs never leave the device.
CachePer-app + shared model cache, on diskCleared on uninstall (option to keep).

CLI defaults

BehaviorDefaultRationale
locara doctor reportingLocal output only; no uploadDiagnostics stay on dev machine.
locara init --from-promptUses dev’s own API key from envLocara doesn’t proxy LLM calls.
locara test capability testsRequired to pass before publishStatic check on what the app actually does.
locara verify --strictTreats warnings as errorsCI uses this; prevents accidental capability creep.

Build defaults

BehaviorDefaultRationale
Code signingRequiredGatekeeper compatibility.
NotarizationRequiredApple-vetted malware scan.
Provenance attestationAlways generated, always loggedPublicly verifiable supply chain.
Build environmentFresh ephemeral runnerNo environment carryover.
Source-only submissionRequired (no developer-uploaded binaries)Eliminates “compromised dev machine” attacks.

Registry defaults

BehaviorDefaultRationale
Publisher identityGitHub OAuth requiredCheap identity floor.
2FARequired for publishingAccount-takeover mitigation.
Auto-approveOnly for low-risk capability profilesRisk-based routing.
Capability cool-down7 days for capability expansionsAccount-takeover mitigation.
Review evidencePublicTrust through transparency.
Kill-switchAvailable, signed, loggedForensics + revocation.

Distribution defaults

BehaviorDefaultRationale
Auto-updateUser opt-in per appPrivacy + control.
Capability-expanding updateRequires re-consent + cool-downAccount-takeover mitigation.
Sideloaded appsSignature verification requiredSame trust mechanics for off-registry installs.
Multi-registryUser must explicitly add non-default registriesDefault registry is the trusted source.
App data on uninstallKept by defaultUser chooses to wipe.

What you’ll notice: every default is “safer / more private,” and any deviation requires explicit user action with clear consequences.

What the user must opt into for less safety

The asymmetry matters: the path to “less safe” is explicit, slow, and visible.

ActionFriction
Install an app that uses networkClear capability summary at install + ongoing badge in the app itself
Add an alternative registryManual locara registry add; warning shown in client
Install a sideloaded app”This is a sideloaded app, not from the registry” banner
Disable auto-updatesPer-app or global setting; doesn’t affect security updates
Enable subprocess tool execManifest declaration; flagged in review; prominent warning to users
Skip notarizationNot possible — Locara CI requires notarization

The user can always make the system less private (e.g., install a network-using app), but they always know they’re doing so. Locara never silently enables a less-safe behavior.

Threat model summary

A high-level summary; full details are in 14-trust-safety.md.

What we defend against

  • Malicious app at submission. Verified publisher + automated review + capability declarations + runtime enforcement.
  • Compromised publisher account. Mandatory 2FA + capability cool-down + kill-switch.
  • Compromised dev machine. Source-only submissions + Locara CI builds in clean environment.
  • Tampered artifact in transit/at rest. Sigstore provenance + dual signatures + transparency log.
  • Capability creep across updates. Mandatory cool-down + re-consent on capability expansion.
  • Tool-mediated escape. Wasmtime sandbox + composition rule (tool ≤ app capabilities).
  • Network exfiltration. macOS App Sandbox kernel-blocks network when net: false.
  • Filesystem traversal. Powerbox-mediated user-file access; container isolation.
  • Cross-app contamination. Per-app containers; explicit IPC declarations.
  • Supply-chain attacks via models/tools. Content-addressed by SHA; verified at install.

What we don’t defend against

  • User explicitly granting all permissions and installing a clearly-marked-malicious app. No system can save users from informed self-harm.
  • Physical access attacks (someone steals the laptop with FileVault disabled). Out of scope; this is OS-level concern.
  • Side-channel attacks on the Apple Silicon GPU during inference. Theoretical research; no practical exploits known.
  • Apple itself. Locara apps run on Apple’s OS; Apple has theoretical access. The privacy floor is “Apple ≤ Locara” — we don’t try to defend against Apple.
  • Hardware compromise (firmware-level malware). Out of scope.
  • Someone publishing a copycat app on a different store that lies about being Locara-built. Brand defense, not technical.

Privacy-specific design choices

Beyond the capability/sandbox machinery, several design choices contribute specifically to privacy:

Zero ambient telemetry

The Locara CLI, runtime, dev panel, and client never make outbound network calls except:

  • Each Locara app’s periodic update check (manifest fetch from registry’s manifest API), via Tauri’s standard updater plugin.
  • locara init --from-prompt (dev’s own LLM API key, dev’s own machine).
  • locara publish (push submission to registry).

No analytics, no error tracking, no usage statistics, no hello-world ping on launch. The compromise here would be fatal — an “anonymized telemetry” leak undermines every promise we make to users about apps.

If we ever need usage data (for product improvement), it must be:

  • Opt-in.
  • Aggregated with differential privacy at the source.
  • Documented in a public spec document.
  • Auditable by users (they can see what’s about to be sent).

This is a high bar; it should remain unmet for v1.

Data retention

Locara doesn’t retain user data because Locara never sees it. The registry stores:

  • Manifest entries (public).
  • App ratings + reviews (public).
  • Publisher identities (verified, semi-public).

That’s it. No user identities, no install traces, no per-user activity logs.

Each Locara app stores its own user-specific state locally in its sandboxed container. There is no central “Locara client” tracking installed apps; macOS’s own app registry (Launch Services) is the source of truth, just like for any other Mac app. Nothing is synced to any server. Loss of local state = loss of state (Time Machine + per-app export are the recovery paths).

Logs and diagnostics

Logs live at ~/Library/Logs/Locara/. They include:

  • Capability denials.
  • Model load events.
  • Runtime errors.

They do not include:

  • App content (transcripts, documents, prompts).
  • User identifiers.
  • Network destinations (since most apps don’t use network).

When a user shares a log to debug an issue, they share a file from their disk, voluntarily, with whoever they choose. Locara never auto-collects them.

Crash reports

Crashes log a stack trace + minimal context to local logs. No automatic upload. The user can run locara doctor --export-logs to bundle logs for sharing if they choose.

What the registry can and cannot see

The Locara registry knows:

  • Who published which app (publisher account → app).
  • Manifest content of every published version (it’s public).
  • Aggregate install counts (computed from update-check pings; not per-user).
  • Public ratings + reviews.

The registry does not know:

  • Which user has which app installed.
  • What an app does after install.
  • Any content the user generates.
  • Which models a particular user has cached.
  • IP-tied install patterns (CDN may have logs; we ensure they’re not retained beyond ops needs).

This is a deliberate ceiling — the registry is structured to know as little as possible about end users.

Cryptographic primitives

Stable choices for the long-term:

UseAlgorithmNotes
HashingSHA-256Industry standard; used for model + artifact addressing.
Code signingApple Developer ID (RSA / ECDSA over P-256)Required by macOS.
Provenance signingSigstore (ECDSA over P-256, short-lived certs)Industry-trending standard for OSS supply chain.
TransportTLS 1.3All registry / CDN traffic.
Cert pinningEach app’s runtime pins the Locara registry CADefends against rogue CA / MITM.
At-rest encryptionmacOS FileVault (default) + optional SQLCipher per-appApp opts into SQLCipher if it has unusually sensitive data.

These are mostly inherited from macOS / Sigstore / TLS — Locara doesn’t invent crypto.

Disclosure & response process

When a vulnerability is reported:

  1. Reporting channel: security@locara.app with PGP key + Sigstore identity for verification.
  2. Triage: Severity classification (low / medium / high / critical) within 48 hours.
  3. Response:
    • Critical: hotfix + kill-switch within 24 hours; advisory immediately.
    • High: patch within 7 days; advisory + CVE if applicable.
    • Medium: patch in next release cycle.
    • Low: tracked publicly in issues.
  4. Postmortem: Public writeup published within 30 days for any non-trivial incident.
  5. Coordinated disclosure: Embargo periods supported when multiple parties are affected.

A security advisory page on locara.app/security lists all advisories, similar to Mozilla’s MFSA page.

(open) Bug bounty program. Likely worth doing once user base justifies it (phase 4+). Joint with Sigstore / Apple bounty programs where applicable.

What would break the privacy thesis

Things we must never do:

  • Add telemetry to the framework / runtime / CLI / client. Even “anonymous.” Even “opt-out.” Even “for debugging.” It compounds and erodes trust irreversibly.
  • Allow apps to bypass capability declarations via dynamic code loading. The “self-contained” rule (no remote code execution) is non-negotiable.
  • Give the registry visibility into user activity. Manifest checks should be cacheable + anonymous, never logged per-user.
  • Centralize keys in a way that compromise of Locara’s infrastructure breaks all signed apps. Use short-lived Sigstore certs; rotate regularly.
  • Hide failures. If a malicious app slipped through, publish it. Trust is built by transparency in failure.
  • Sell anonymized usage data. Even framed as “improving the product.” Just no.
  • Add a “cloud sync” feature that requires apps to upload data anywhere. Apps that want sync can build it (declaring net); the framework doesn’t.

These are guardrails. If a future maintainer is tempted to violate them under business pressure, they should treat that pressure as a signal to step back, not a justification to compromise.

Cross-references