DorkOS
Advanced: Running DorkOS Yourself

Threat Model

What DorkOS trusts, what changes when you expose it, and how to reason about the risks of running agents on your own machine

Threat Model

DorkOS is a workspace where autonomous agents work on your own machine. That is a lot of reach, and reach is worth reasoning about. This page lays out what DorkOS trusts, what each choice changes, and where the sharp edges are, so you can decide what is safe for your setup. It is written to be read, not to reassure. No "bank-grade" claims here.

DorkOS is a fast-moving alpha. This page describes how it works today. When the model changes, this page changes with it.

The one idea to hold on to

Your machine is the trust boundary. By default DorkOS has no login and listens on localhost only. Anything already running as your user can reach it, the same way it could reach any other developer tool you run. DorkOS does not try to defend you from software you already chose to run as yourself. It defends the line between your machine and everyone else.

Everything below is a variation on that one idea.

The local, single-user default

Out of the box:

  • No accounts, no sign-in screen. Instant start.
  • The server binds to localhost, so only your own machine can reach it.
  • Your chats with agents and your code stay in files on your disk. There is no cloud copy.

This is the right default for a tool on your own laptop, and it is also the reason the next section matters so much: the moment you want to reach DorkOS from another device, the rules change.

What enabling the tunnel (or a public bind) changes

Reaching DorkOS from your phone or another machine means exposing it, either by starting a tunnel or by binding to a public network interface. That flips DorkOS from "single-user local tool" to "networked service," so DorkOS requires a real login before it will do it.

DorkOS decides each request by where it came from. A request from this computer is you, already signed in. A request from any other device always needs a sign-in, whatever "Ask for a password on this computer too" says: through your tunnel, over Wi-Fi, through a reverse proxy, or to a public address. A proxy's forwarding headers, or a page on another site named in Origin or Referer, make a request count as another device.

Exposing DorkOS requires an owner account: someone for those other devices to sign in as. Starting a tunnel without one routes you into creating it first. Binding to a non-loopback host without one refuses to start. This is enforced in code, not a suggestion.

Once exposed:

  • Remote visitors get the sign-in screen. Static assets load so the page renders, but every API call needs a valid sign-in.
  • Registration is owner-only. The first account is the owner and further sign-ups are closed, because anyone who can drive agents effectively has your machine's file access and spends your AI quota. A viewer/operator role that safely admits more people is planned, not shipped.
  • You can add a second factor at the tunnel edge (ngrok basic auth) on top of login.

One deliberate escape hatch: a container that owns its own network boundary can set DORKOS_ALLOW_INSECURE_BIND=true to bind publicly without login. Until an owner account exists, that container stays open to anyone who reaches its port, for one more release; once the owner exists, every browser visit needs a password. It is off by default and logs a loud warning. Do not set it on a real machine. Copying a container's environment onto bare metal is the mistake to avoid, because it turns off the exposure guard.

See Securing your instance for the how-to.

What the MCP and agent endpoints expose

DorkOS ships a tool endpoint at /mcp so external agents and scripts can drive it. It is closed by default, on localhost too. What you send to open it depends on whether you have turned on login:

  • On this computer, with login off (the default). Anything that changes something on your machine — installing a package, creating an agent, running extension code — needs your local MCP token, a file only someone signed in to your computer can read. Without it, those calls come back 401. What still answers with no token is the handshake and read-only checks: listing the tools, ping, get_server_info. A tool DorkOS does not recognise is refused rather than allowed, so a tool added later starts out closed.
  • Login on, or from another device. The login gate covers /mcp like the rest of the API, so every call needs a sign-in or a per-user API key, and the local token steps aside. A call from another device never gets the local token or the no-token checks, whatever "Ask for a password on this computer too" says.
  • Exposing the server does not loosen either rule; it adds the exposure guard on top. The server refuses to bind to a public address without an owner account. Two things get past that guard, and both are worth knowing: the official Docker image opts out of it on purpose (the callout above), and a reverse proxy in front of a loopback bind is a path it never sees, because it only inspects the address DorkOS itself binds to. The request gate still catches that proxy: its forwarding headers make every request through it another device, which needs a sign-in. The one gap left is named here on purpose. A proxy on this computer that sends no forwarding headers and points Host at localhost or 127.0.0.1 (nginx's default for proxy_pass http://127.0.0.1:4242) makes its traffic look like this computer. A browser still gives itself away when it changes something, because it names the page it is on. A script or command-line client names no page, so through such a proxy it gets everything this computer gets. For the same reason, a sign-in made on this computer also works through that proxy, because DorkOS cannot tell the two apart. Make your proxy send X-Forwarded-For (the configs in Reverse proxy do), or turn on "Ask for a password on this computer too".

The honest limit of the local token. While login is off, any program running on your computer can read the token file the same way the app does. The token stops callers that have no token at all, and it guards the endpoint anywhere the port is reachable from outside — a tunnel or a proxy. It does not stand between you and other software running as you, which can still drive tools that install packages and run extension code. Turning on login is the boundary that closes that. MCP_API_KEY is not: it is the fixed key for a server nobody signs into, not the thing standing between you and an open endpoint.

The A2A agent endpoints work the same way, with one difference: while login is off, reading an Agent Card needs no token, because a card is public metadata — but every JSON-RPC call, which runs a prompt against one of your agents, is gated. Turn login on and card reads need a credential too.

Agent-to-agent messaging and budgets

Agents message each other in chats you can open, and reach you and outside systems through the relay. These controls apply:

  • Relay budgets are enforced before delivery. Every relay message passes an authoritative budget and hop check before it is delivered, so a runaway loop is stopped at the source, not just in a mailbox. Cascade depth, cycles, and per-agent call budgets are all bounded.
  • An hourly ceiling caps the relay's cost, whatever the route in. A relay message, a scheduled task, and an outside system speaking A2A all end at the same counted checkpoint before a turn starts, so no route around the relay buys a bigger allowance. You set the cap per agent and for everything combined; see Relay Messaging.
  • Messages between your agents' chats have no loop limit. Two agents can keep messaging each other's chats for as long as they keep going, and each round uses your plan. Every message is in a chat you can open, and you can stop either chat. DorkOS still limits how many chats agents can start running at once, to protect the machine.
  • An agent cannot choose its own identity through the supported messaging path. The server takes the sender from the calling chat, or from the chat for relay messages, instead of trusting the tool call. This stops one normal agent call from naming another agent. It is not operating-system isolation: software running as your user can read the same files and credentials that you can.
  • A message never raises an agent's power. A turn another agent's message starts runs no looser than the agent that sent it. A message a bridged Telegram or Slack chat posts into a room, or one from another company's agent over A2A, runs at the level a brand-new chat starts at, even in a chat set to Full autonomy. A chat that turn starts can be no stronger than it.
  • Reaching a human is a consent choice. Whether an agent may start a chat with you on a chat app like Telegram is set for each agent on each chat app.

What stops an agent operating DorkOS itself

Agents do not only write code here. They can create agents, schedule work, change settings, and add or remove packages. Every one of those actions carries one of three labels:

LabelWhat happens
Read onlyRuns. Nothing to undo.
Changes thingsRuns, and lands in your activity feed, named to the agent when DorkOS knows which asked.
Cannot be undoneOn a Trusted install (the default) most of these run too, recorded the same way. Three never do: they return a pending approval and wait for somebody to answer, on Trusted and on Careful alike.

Six actions carry the "Cannot be undone" label: removing an installed package, deleting a scheduled task, removing an agent, changing an agent's safety boundaries, changing what an agent runs on (its runtime, model or effort), and running a package from a folder. The last three always wait, whatever preset you are on, because each brings in code nobody has reviewed or moves an agent the way every one of its scheduled runs would also move. The first three no longer stop to ask on Trusted: they run and land in your activity feed, named to the agent that did them. Creating a new package in your personal marketplace waits too, and so does installing or updating one, because a package is code from outside your team. A package's own hooks and any global plugins it carries ask separately as well. On a Careful install, every action above waits for your yes, the way DorkOS always used to work.

The gate is not advice. It sits at the composition root of the two tool servers that carry these actions, and inside the capability registry, below every caller, so a chat's permission mode cannot reach it: an agent in bypass-permissions mode still stops at the ones that always ask. A new tool with no declared label fails the server build rather than running unlabelled.

There is a third, much smaller tool server, for Codex chats, and it is outside that gate. It carries exactly one tool, for changing what the app is showing you, which is in the middle group above and would not stop to ask in any case. Nothing that changes your files or your setup is reachable through it.

How much that gate is worth depends on whether login is on, and the two answers are genuinely different.

With login off, the default, DorkOS refuses the requester: a caller presenting an agent identity or the retry token it was handed cannot decide its own request, which stops an honest agent and a prompt-injected one. Every decision is recorded with the posture it was made under. What it cannot do is tell you apart from a bare, credential-free request from other software running as you. That is the same boundary as everything else on this page.

With login on, deciding requires a verified account. A network caller with no credential cannot decide, whatever it sends or omits. Note the honest limit even here: a valid per-user API key satisfies the check, so "a signed-in account decided this" is what the record says, not "a person did." Login does not isolate software running as your operating-system user. That software can reach files and credentials your account can reach.

Connections and account access

Connections lets an agent use only the account and actions you grant. Notifications are a separate choice with their own event, filter, receiving agent, and destination. DorkOS keeps service login tokens and private account references out of the agent-facing response. Removing a grant or connection stops the next checked call, but it cannot recall a request already sent to a service.

Where your service login lives depends on the route you chose: Composio's vault for the DorkOS-managed and bring-your-own-key routes, your own Nango server's database for the Nango route, or the remote server itself for raw MCP, which never asks DorkOS to sign you in at all. Some services ask for an API key or other account details instead. You enter those on the signed-in dorkos.ai page. DorkOS passes them to Composio to create the account connection. It does not save or log those values, and they never pass through your local app, agents or CLI. Your service’s own permissions still apply alongside the grants you choose in DorkOS.

With login off (the default), DorkOS cannot tell a write that changes who can use an app apart from one the app itself made — so anything with a shell on this machine can make that change, the same as the app could: sharing an app, narrowing it, disconnecting it. Sharing an app with Every agent is just the widest version of that change, worth naming because it needs no per-agent review: a caller with a shell on this machine could turn it on for itself and every other agent. Turning login on closes the gap for all of these writes, because only the signed-in owner can make them from then on.

During a turn, DorkOS gives the runtime a private Connections token. The server checks its runtime, chat, registered agent, working folder, and server start. The token has a four-hour expiry window. Finishing the turn or restarting the server invalidates it. Each account action still needs the right grant.

The current source includes both protections below. Check your installed build before relying on them:

  • Renewal for long turns. The server supervisor renews the same token about once an hour, keeping its expiry four hours ahead while the exact turn remains active. Using the token cannot renew it. This supports long turns, but a stolen token could remain useful while that turn continues. Four hours is not a fixed lifetime from the moment the token was issued.
  • Fewer inherited secrets. The launch policy passes a deliberate list of settings to Claude Code, Codex and OpenCode. It keeps supported sign-in, system and privacy settings, including DO_NOT_TRACK. Other settings require the owner's explicit choice by name. Reserved server secrets cannot be added that way. Existing processes keep their old settings until a safe restart.

Connections grants are not a sandbox. Software running as your operating-system user can read files and credentials that you can. Older builds and processes started before the new policy can still inherit the server environment. Filtering that environment reduces accidental exposure; it does not isolate files, processes or software you run as the same user. Login and grants protect their own DorkOS and network paths.

Managed account access is enabled in alpha. Automated tests cover its access rules. A real Gmail sign-in, profile read, usage record, and removal of agent access have also been verified. This does not certify every service. Managed account notifications remain unavailable until their separate live delivery check passes.

Marketplace package trust

This is the sharpest edge, so it gets its own rule:

Installing a marketplace package runs its code. A plugin's bundled extensions are compiled and loaded into the DorkOS server process. Install packages the way you would run any script from the internet: only from authors you trust.

What DorkOS does on your behalf:

  • Package sources are fetched over safe git transports only. A booby-trapped source link cannot run a command on your machine at browse or preview time.
  • Installs are transactional. A failed install rolls back and leaves your existing setup untouched.
  • Browsing and previewing the marketplace does not execute package code. Installing does.

What DorkOS does not do yet: it does not verify a package signature or pin it to a content hash by default. Treat the marketplace as trust-on-first-use, and prefer packages from sources you know.

What is out of scope

Being honest about the edges:

  • DorkOS does not defend against other software running as your own user. That is your machine's job.
  • It is not a multi-tenant server. One instance belongs to one operator.
  • The local edition sends no email and has no "forgot password" flow. Password recovery is a command you run on the machine, because machine access already implies owner trust.

Found something?

If you believe you have found a vulnerability, please report it privately. See SECURITY.md for how.

Next steps