Skip to content

Blog

Why we built deputyOS: a personal AI you actually own

deputyOS is an appliance image for self-hosted personal AI assistants — origin story, design philosophy, and what we'd never compromise on.

7 min read deputyOS team

There’s a particular pattern when a semi-technical friend asks for help getting an open-source AI assistant running on their own hardware. It goes like this:

You point them at OpenClaw or Hermes Agent. They have a spare Raspberry Pi 5. They’re capable people. Maybe two hours in, they’re staring at a node-gyp build failure for @discordjs/opus on arm64. Maybe they didn’t run loginctl enable-linger, so the service dies when they log out. Maybe their CMake is too old. Maybe they didn’t realize they needed to add a ufw rule before exposing the wizard.

Each one of these is solvable. None of them should exist.

That’s why we built deputyOS.

What deputyOS is

deputyOS is a batteries-included Linux appliance image. You flash it to an SD card or NVMe (or boot it on a cloud VPS, or in WSL2, or in UTM), the device comes up, a wizard publishes itself at deputyos.local, and within roughly ten minutes you have a working personal AI assistant talking to you over Telegram.

There is no npm install. No pip install. No apt install of agent dependencies. No CMake invocation. The image already contains:

  • Node.js LTS + every native module the agent needs, prebuilt for the target arch.
  • Python 3.11 + uv + every package on the agent’s pinned manifest.
  • llama.cpp prebuilt for the target arch.
  • ClamAV signatures dated within hours of the image.
  • AppArmor profiles for the agent, loaded in enforce mode.
  • ufw default-deny, fail2ban, hardened sysctls, key-only SSH.
  • A first-boot wizard that does only configuration — no installs.

That’s the entire point: the network at first boot is for talking to your model provider, not for downloading the agent.

The four invariants we don’t compromise on

These are the rules we hold ourselves to. They’re load-bearing — they shape every product decision we make.

Zero first-boot network installs

The image at rest contains everything needed to run the chosen agent end-to-end. Build hosts pull dependencies once, at bake time, from sources whose SHAs are pinned. Devices in the field don’t see public package mirrors at all. This rule exists because flaky mirrors, lapsed certs, and stale registries kill the first-boot experience and they kill it disproportionately for non-technical users. Read the rationale.

Security baseline on by default

A user who never types a sudo command should still be running a hardened machine. deputyOS ships AppArmor enforce, ufw default-deny, fail2ban, hardened sysctls, key-only SSH, ClamAV signatures embedded, and Magika hooked into the agent’s file-upload path. The security default-on list is enumerated, audited, and stable. See default-on controls.

Local-first, cloud-optional

The agent runs on hardware you own. Channels, memory, hooks, and skills live entirely on your device. Cloud is opt-in for two things: the model provider you choose (if you choose one — the air-gapped tier bakes a local LFM2 instead), and your own backup bucket (B2 / R2) if you want one. No telemetry is on by default. No callbacks home.

Profile-class rule

Not every agent fits in deputyOS. We accept only multi-channel personal AI assistants — OpenClaw, Hermes, Khoj. We refuse IDE plugins, agent frameworks, integration shims, and home-automation hubs (those have their own first-class projects). This is in the spirit of “do one thing well.” See the profile-class rule.

What’s hard about this and why nobody else does it

Building a real appliance image — one that boots, runs unattended, updates safely, and works across a hardware matrix — is the kind of work that pays off late. There’s no commit that makes for a great demo. The first month is spent on Packer templates, Ansible variants, signing chains, and reproducible builds. The second month is spent on the wizard, the QR-on-TTY for HDMI users, the ClamAV signature bundling, the systemd unit hardening.

But once you have it, everything compounds. Adding a new profile is a manifest + an Ansible bake recipe + an AppArmor profile + a systemd unit. Zero Rust code changes. We proved that with Khoj as the third profile.

What you actually do with it

The wizard asks for:

  1. Hostname + timezone + Wi-Fi (if not on Ethernet).
  2. Which profile to run — OpenClaw, Hermes, or Khoj.
  3. Which model provider — OpenAI, Anthropic, OpenRouter, Bedrock, or a local LFM2 if you picked the air-gapped tier.
  4. Which channels to wire up — Telegram, Slack, Discord, Signal, Matrix, IRC, Email, and others.
  5. Whether you want a Cloudflare Tunnel or a Tailscale connection for inbound webhooks behind NAT/CGNAT.
  6. A backup destination (B2, R2, or S3).
  7. Optional cost guardrails — per-day and per-month spend caps with auto-pause.

That’s it. Then it builds the systemd unit, drops the secrets file with mode 0600, brings the agent up, and points your phone at http://deputyos.local/chat for the first conversation.

The air-gapped tier we’re proudest of

Recent work added an AIRGAP=1 flag. With it, the image bakes a tier-appropriate LFM2 GGUF (350M / 1.2B / 2.6B) served by llama.cpp. The apt mirror is baked into the image. The nftables ruleset denies all egress except RFC1918 + mDNS + local DNS. You can plug the device into a switch with no internet uplink and have a working assistant. See the air-gapped concept doc.

We added this because some users genuinely don’t want their conversations to ever touch a cloud LLM. Some live with intermittent connectivity. Some work in regulated environments. deputyOS shouldn’t ship “local-first” as a marketing line and then quietly require an OpenAI key for everything useful. The air-gapped tier means the full assistant function — chat, memory, channels, skills — works with zero outbound network.

Who this is for

  • Engineers tired of cloud lock-in who want their assistant on their own NUC or Pi 5.
  • Privacy-aware professionals — lawyers, journalists, doctors — who can’t send conversations to a third party.
  • Tinkerers who like the idea of one Pi handling Telegram, Slack, Signal, and their personal notes.
  • Educators and labs who want classroom AI without per-seat licensing.
  • Builders who want a reproducible appliance to extend — add their own profile, hook, or skill.

It is not (yet) for:

  • People who want a polished mobile app. deputyOS runs on a server you own; the PWA is the mobile UX.
  • People who want SaaS billing and dashboards. By design we don’t have telemetry.
  • People who want every model under the sun on day one. The provider list is curated — see model providers — and grows with demand.

What we won’t do

A surprising amount of deputyOS’s design is about restraint. We don’t:

  • Run our own LLM inference SaaS. The model provider is yours.
  • Phone home with telemetry. Optional OpenTelemetry is on the roadmap, opt-in.
  • Auto-update without your consent. Updates require explicit user action or a cron-scheduled deputyctl update --apply.
  • Bundle a desktop browser. The PWA is the UX. If you want a browser, run one yourself.
  • Add features for features’ sake. Every checkbox we add is a maintenance liability for years.

Where this is going

The roadmap has the full picture. Short-term: cross-builder reproducibility (SLSA L3 verified), the desktop launcher polish, the DigitalOcean Marketplace listing, the egress-whitelist mode, and eventually an opt-in cloud-backup business layer. Long-term: more profiles (we want a coding-specific one and a personal-knowledge one), and better voice — wake-word + TTS that just works on a Pi 5.

If any of this resonates, the picker has the right image for your hardware, the GitHub repo takes pull requests, and we read every Discussion thread. Welcome aboard.

Related posts

Search

Search index isn't built yet. Run npm run build to generate it (Pagefind writes to dist/pagefind/).