The world does revolve around you.

Security architecture.

Ostler holds your entire digital life in one place. That is powerful and dangerous in equal measure. This page explains exactly how we protect it. No hand-waving, no “industry-standard encryption.” Specifics, and honest status labels on every claim.

The threat model is different here. A breach of your LinkedIn exposes one slice of your life. A breach of Ostler would expose everything – every relationship, every conversation, every pattern. We built the security around that reality.

The realistic threat is software, not magic AI. What threatens a local-first product is malicious code running on the same Mac, with your permissions, doing things you did not ask it to. The AI inside Ostler is an instructed insider: bounded tool calls, bounded data access, audited outputs. The unexpected attacker is everything else with a foothold on the host.

Figure 1.0  /  Security boundary One device. One owner.
SECURITY BOUNDARY YOUR MAC Secure Enclave Passkey · non-export Touch ID / Face ID SQLCipher DB AES-256 · in review FileVault today OSTLER CORE Local · localhost-only · no telemetry Auto-lock In-memory key wiped · ctypes.memset E2EE iOS APP Passkey via iCloud Keychain Realm · AES-256 Pinned TLS Self-signed Ed25519 Pubkey-pinned Home Wi-Fi only LAN No arrow leaves the boundary. No server. No telemetry.

No cloud. A severely reduced attack surface.

Ostler does not connect to any external server. No cloud backend. No API endpoint. No telemetry. The databases, the AI models, and the processing pipeline all run on your Mac.

This eliminates the largest, most boring class of attack vector for personal data: server breaches, man-in-the-middle attacks, credential stuffing, insider access at the vendor, and government data requests against the vendor. There is no server to breach. There is no data to request.

Verify it yourself. Disconnect from the internet. Everything continues to work.

What this is not: a claim that nothing can go wrong. Removing the cloud closes the door an attacker most often walks through. It does not seal every window. The honest limits – what stays your responsibility – are spelled out in What this doesn’t protect against, below.

Further reading · Why “no data to request” keeps an AI note-taker out of a privilege dispute →

How authentication works

There is no password. We took passwords off the table entirely.

On first run, Ostler registers a passkey against your Mac’s Secure Enclave. From that moment on, unlocking Ostler is a Touch ID tap, a Face ID glance, or a double-click on your Apple Watch. The cryptographic proof of identity lives inside your Mac’s hardware security chip. It cannot be exported, phished, or copied to an attacker’s machine.

Creative Machines never sees a password because there is no password to see. We never receive a login token, a session cookie, or a hashed credential. There is nothing for us to lose in a breach because we hold nothing.

Your passkey syncs to your other Apple devices through iCloud Keychain, end-to-end encrypted by Apple. That is how the Ostler iOS app will unlock data from the same Hub without a second setup step.

What the passkey protects

Ostler’s at-rest design gives every database its own encryption layer under a 32-byte data-encryption key (DEK). Whole-disk FileVault protects everything on the Mac today; the finer-grained per-store layer is in review, and the table below shows the honest per-component status. The DEK is generated on your Mac at install time, never leaves your Mac in plaintext, and is wrapped (encrypted) under a key derived from your passkey. Unlocking Ostler means: your biometric unlocks the passkey, the passkey unwraps the DEK, the DEK decrypts the databases. When the app locks, the DEK is wiped from memory.

When Ostler is locked – auto-lock and stolen-Mac design

Ostler auto-locks after a configurable period of inactivity. On lock, the in-memory encryption key is overwritten. A stolen or lost Mac sitting on the attacker’s desk cannot yield plaintext without a live Touch ID / Face ID from you.

Most consumer software does not seriously model device theft – the cloud holds the real copy, so a stolen device is treated as a lost endpoint. We model it because here the device is the data, and the data is intimate. There is no cloud copy to fall back on. The auto-lock, the in-memory key wipe, and the requirement for a live biometric to re-unlock are designed around that reality, not bolted on after the fact.

Email is not the chokepoint here

There is no password-reset email, no magic link, no email-bound recovery. A compromised inbox compromises nothing.

Why that matters, and how the chain of custody actually runs

A common pattern in “passwordless” products is to bind authentication or recovery to email – a magic link, a one-time code, a password-reset flow. It looks strong on the surface; there is no password to phish. The catch is that the security of the whole system inherits the security of the user’s email account. A compromised inbox is a compromised identity.

Ostler does not work that way. There is no password-reset email, no magic link, no email-bound recovery for the local product. The data-encryption key is issued by the Hub on your Mac at install time and wrapped under a key derived from your passkey, which lives in your Mac’s Secure Enclave. The only out-of-band fallback is the 12-word phrase you wrote down. The chain of custody never runs through your inbox.

Recovery phrase

There is exactly one fallback: a 12-word recovery phrase generated during setup. You write it on paper. You keep it somewhere safe. You never type it into iCloud, Dropbox, a password manager, or a photo.

How the phrase works – and what happens if you lose it

The phrase is shown to you once, on a screen that blocks copy-paste, and never stored on disk afterwards. To be specific about what we use from BIP39 and what we don’t: we use its 2048-word English wordlist and its entropy-to-words encoding (128 bits of entropy plus a 4-bit checksum ⇒ 12 words). We do not implement BIP39’s PBKDF2 mnemonic-to-seed step – we treat the entropy as our recovery-key material directly, which is the right choice for a non-wallet system. Ostler is not a cryptocurrency wallet and we do not claim BIP39 wallet compatibility. We use the wordlist because it is publicly audited and ergonomically proven, not because we are interoperating with anything.

If you lose your Mac and your iPhone, and iCloud Keychain has not restored your passkey to a new device, the recovery phrase is how you get back in. It unwraps a second, independent copy of the same DEK.

If you lose the phrase and all your Apple devices and your Time Machine backup simultaneously, your data is gone. By us, by anyone. That is the price of real privacy – the same architecture that prevents us from reading your data prevents us from helping you recover it.

Encryption at rest

Your data is protected by multiple layers. Each row below shows the current, honest status – not what we intend, what is actually in the build:

ComponentEncryptionStatus
Full diskmacOS FileVault (AES-256-XTS)Live
Installer checks this is enabled
SQLite databasesSQLCipher (AES-256)Live in code
Whole-disk FileVault protects everything today; the finer-grained per-store layer is built and in review
iOS app secure storeRealm (AES-256), device-bound keyLive
Voice-profile store encrypted on iOS today
iOS app main storePasskey-derived Realm key (shared with Hub)In development
Cross-platform spec signed off; iOS pairing flow next
Vector + graph databasesEncrypted APFS volumeSpecified
Design signed off; build queued as a defence-in-depth pass behind the per-store SQLite work. FileVault (AES-256-XTS) already provides full-disk protection today; per-store encryption adds an application-level layer.
Local audit logSQLCipher-encrypted, append-onlyLive in code
Per-entry HMAC integrity chain is a planned upgrade
Time Machine backupsInherits FileVaultLive
Via macOS Time Machine encryption

Code and model integrity

Two pieces of Ostler arrive on your Mac from the internet at install time: the assistant binary itself, and the local LLM model weights. We handle the integrity of each differently because the trust shape is different.

The checksum gate, and the model-registry trust assertion

The assistant binary ships as a signed tarball with a SHA-256 checksum published in a sidecar file. The installer downloads both, computes the hash of the tarball, and refuses to continue if the values do not match. Tampering between our release pipeline and your Mac – by an intermediary, by a compromised CDN, by any agent in between – is a hard install failure, not a silent compromise.

The model weights come from curated upstream registries (the Ollama registry, Hugging Face) over TLS at install time. We pin model names; we rely on the upstream maintainer’s tag-immutability discipline for what bytes those names resolve to. We are honest about the trust assertion: if a maintainer of an upstream we depend on shipped a malicious update under a tag we had pinned, fresh installs would pull it until the upstream caught the issue. We pin versions where we can, read changelogs, keep the model surface small. Tightening this further by pinning content digests is a hardening item on the post-launch list.

Hub and iPhone: hardened local channel

When the Ostler iOS app talks to your Mac Hub, the connection is designed to run over TLS with a self-signed certificate generated during install, with the iPhone pinning the certificate’s public key at pairing time so only your Mac can answer.

The pairing contract – what is locked in the specification

The cryptographic contract – pairing QR code format, WebAuthn handshake, HMAC-based proof of shared passkey, ten-minute pairing-token expiry – is locked in a normative cross-platform specification that was signed off on 2026-04-23 by both the Hub-side and iOS-side implementers. Every HKDF constant, wire-format byte, and test vector is fixed. Hub-side code-signing is the remaining blocker before iPhone-to-Hub pairing runs end-to-end (see below).

Network hardening

Everything binds to localhost. Nothing is reachable from outside your Mac, and no port is ever exposed to the internet.

The five hardening measures
  • All services bind to localhost. Qdrant, Oxigraph, Valkey, the API gateway, the local LLM endpoint, the MCP service – none are reachable from outside your Mac. All Hub services bind to 127.0.0.1 (loopback only); none accept LAN connections. This protects against every attacker who is not already on your Mac. It does not isolate Ostler from other software running on the same Mac as you – see below.
  • JWT secrets validated at boot. Every service that participates in the gateway authentication chain refuses to start if its signing secret is missing, set to a placeholder, on a known-weak banlist, or shorter than 32 characters. A misconfigured deployment fails loudly at boot, not silently at request time.
  • No ports exposed to WAN. No UPnP. No port forwarding. Your router’s firewall is the perimeter.
  • Remote access via Tailscale only. If you want to access Ostler from your phone away from home, we recommend Tailscale (zero-trust, encrypted, no exposed ports).
  • iOS app connects over your home Wi-Fi. Once paired, your iPhone finds your Mac using the same local discovery that AirDrop uses. It never reaches out to the internet to find your Mac.

How the assistant is bounded

The AI inside Ostler is an instructed insider, in the phrasing of the callout at the top of this page. This section is what that means in concrete terms: what the assistant is allowed to do, what it is not allowed to do, and how its actions are recorded.

The six boundaries, in concrete terms

Workspace confinement. The assistant reads and writes inside a default-deny workspace. The directories that hold your credentials and your private keys – ~/.ssh, ~/.gnupg, ~/.aws, ~/.config, the system directories under /etc, /usr, /var – are on a static denylist that path-guards every file-touching tool. The assistant can read your messages, your email, and the documents you have asked it to read; it cannot, even by misadventure, read your SSH key.

Hardened binary. The assistant binary is built with macOS Hardened Runtime enabled, with the JIT, library-injection, and dyld-environment-variable capabilities denied at code-sign time. The standard process-level injection paths that work against ordinary Mac software – DYLD_INSERT_LIBRARIES hooks, JIT-mapped code injection, loader-environment-variable rewrites – do not work against the assistant. Code-signing trust is the gate; only the original binary runs.

Per-tool approval gate. Every tool call goes through an approval gate. In Supervised mode (the default), a tool that has not been pre-approved this session blocks until you say yes. Session-scoped allowlists do what the name says: they expire when the session ends, not when the assistant decides it has earned your trust forever.

Channel-driven default-deny. When the assistant is being driven by an incoming message – iMessage, WhatsApp, email – there is no human at the keyboard to approve a tool call. In that posture, the assistant cannot ask, so it does not run any tool outside a small read-only allowlist (search, lookup, fetch a public web page). A prompt-injection arriving by message cannot escalate to file writes, arbitrary network calls, or destructive shell commands; the shell-tool surface in this posture is bounded by a separate pre-approved command allowlist.

Tamper-evident audit log. Every tool call writes a record to a local audit log that uses a SHA-256 hash chain: each entry includes the hash of the previous entry, so a deleted or edited entry breaks the chain in a way that replay-validation detects. HMAC signing of each entry is supported as an additional hardening step. The audit log is local; it is not shipped anywhere.

Private-by-default conversations. Conversations between you and the assistant are stored on your Hub and marked private by default. Content tagged at the most sensitive privacy level (full transcript bodies you have shared in confidence) is withheld from query responses unless the calling client explicitly opts in. The default API path returns metadata, not bodies.

Privilege boundaries

Ostler runs as your user account on your Mac – not as root, not as a system service. The orchestrator, the API gateway, the local databases, and the inference processes all run inside your user’s permission scope. There is no LaunchDaemon shipping with the installer, and no background process that survives logout.

The one admin prompt, and the blast radius

The installer asks for an administrator password once, at install time, for the system-level operations that macOS requires admin for: changing power-management settings so the Hub stays reachable to your iPhone when the Mac is idle (disable sleep on AC, enable wake-on-magic-packet), and installing the supporting packages (Homebrew, Ollama) that ship as standard macOS CLIs. After install, no part of Ostler asks for elevated privileges to run, and the application has no path that escalates on its own.

This bounds the blast radius of a bug or a successful attack on Ostler itself: it inherits your user’s reach, not the system’s. It does not protect against malware that has already obtained your user’s permissions through some other vector – that is the surface the next section is about.

What this doesn’t protect against

Closing the cloud closes the biggest, most boring class of attack – the kind that exposes a million people at once. It does not mean nothing can ever go wrong. We would rather tell you the limits than let you discover them.

Other software running on your Mac

This is the realistic threat surface for a local-first product, and we are explicit about it. If a piece of malware reaches your Mac through a malicious browser extension, a poisoned download, or a compromised app from outside the App Store, it inherits your user’s ability to talk to localhost. The encryption-at-rest layer protects against physical theft and against your data leaving the device, but it does not isolate Ostler from other software you have given permission to run. Treat your Hub Mac the way you would treat a password manager or a banking app: don’t install random utilities, don’t approve installer prompts you didn’t initiate, and ideally use a Mac that mostly runs Ostler and not much else.

Supply-chain compromise of our dependencies

Ostler runs on Ollama, an LLM model file, a Python runtime, and a small set of Python packages. We don’t write those, we use them. If any of those upstream projects shipped a malicious update tomorrow, fresh installs – ours, yours, every other user’s – would be exposed until the issue was caught. We pin versions, we read changelogs, we keep the dependency surface as small as we can. We are not going to pretend the risk is zero. The same supply-chain caveat applies to any software you ever install, anywhere.

You

The recovery phrase is the worst-case backdoor. If you write it on a sticky note, take a photo of it, paste it into a cloud notes app, or read it out on a video call, the phrase becomes the attacker’s shortest path. We make it easy to do the right thing – the screen blocks copy-paste, the recovery doc explains the threat – but the final link in the chain is you.

This is the price of a system that holds the keys on your hardware, not ours. We can architect the inside; we can’t architect around bad operational hygiene. The mitigation is honest documentation, not a promise we can keep on your behalf.

Independent audit

We are engaging senior security advisors and scoping an independent security audit from a recognised cybersecurity firm. The scope covers authentication, data handling, storage encryption, network posture, and dependency analysis. The report will be published here when complete.

Why a professional audit – and why this architecture is easy to audit

We chose a professional audit over relying on community code review because an expert review is more rigorous than hoping someone reads the code. Trust should be verifiable, not assumed. “We promise not to look at your data” is what every cloud company says. “We architecturally cannot look at your data, and here is the auditor’s report proving it” is what we are aiming for.

The architecture is intentionally simple. Passkey-primary auth via Apple’s own frameworks. Standard cryptographic primitives (HKDF-SHA256, AES-KW RFC 3394). Local services on 127.0.0.1. Local Ollama inference. There is very little novel cryptography to get wrong because the primary security mechanism is not having a network connection to begin with.

For the technically curious

The full technical specification – WebAuthn/PRF authentication, HKDF key derivation, AES-KW wrapping, recovery-phrase construction, memory handling, and transport – lives on the docs site: Security technical specification. The complete cross-platform cryptographic contract, including every constant and test vector, will be available for independent review.

Current build status – honest line-by-line

Transparency means admitting exactly where each piece stands today. The encryption table above shows the per-component status; the full line-by-line ledger – every subsystem, its state, and the specific blocker named for anything not yet live – is maintained on the docs site: Current build status.

Responsible disclosure

If you think you have found a security vulnerability in any part of Ostler – the Mac Hub installer, the iOS app, the passkey helper, the Sparkle update pipeline, or any related infrastructure – please report it to [email protected]. A human reads every report and replies within 72 hours.

What we promise, and what we ask

What we promise in return:

  • Acknowledgement within 72 hours. A human reads every report.
  • A real conversation. No auto-responders, no triage forms, no bug-bounty paperwork. You talk to an engineer.
  • Public credit, if you want it. We will name you in the release notes for the version that fixes the issue. Pseudonyms and anonymous credit are fine too. If you prefer no credit, we will respect that.
  • A fair window to fix. We ask that you give us a reasonable time to ship a patch before public disclosure. In return we commit to not using legal threats against good-faith researchers.

What we ask in return: do not access other users’ data, do not disrupt our services, and do not demand payment as a condition of disclosure. We do not run a paid bug-bounty at launch – if that changes, this page will say so.

For encrypted reports, our PGP public key is published at /security.asc. The full disclosure policy is also machine-readable at /security.txt per RFC 9116.

The security story is the privacy story. Every competitor sends your data to the cloud and promises to protect it. We keep your data on your hardware and prove it cannot leave. That is not a feature. It is the architecture.

Privacy overview What Ostler knows

Architecturally cannot look. Audit pending.

Specifics  ·  Not hand-waving