Security and data flow

Ditto AI keeps recordings, agents and tool credentials on your Mac. The one thing that leaves is the frames, clicks and transcript of a recording, sent to the AI provider you choose so it can read the task. Permissions come from a fixed table rather than the model, checking a tool never changes anything, and every write can be held as a draft for you to approve.

Where everything is kept

WhatWhere it livesWho else sees it
Recordings: frames, clicks, transcriptYour Mac, in ~/Library/Application Support/Ditto AI/, readable only by your userThe AI provider you chose, when it reads that recording
Your voiceTranscribed on the Mac; the audio is deleted afterwardsNobody. There is no server fallback
AgentsThe same folder, and the Claude Code or Kiro folders you install them intoYou, and whoever you send the file to
Your AI provider keyThe macOS KeychainOnly the built-in server process on your Mac
A Ditto AI tokenThe macOS KeychainDitto AI's server, which checks it
Sign-ins to hosted tools (for example Linear, Atlassian)The macOS login Keychain, one item per serverThat tool's own vendor
Keys for local tool serversThe app's folder in Application SupportThe one server that needs it, when it runs
Sign-ins to websites with no tool serverDitto's own browser profile on your MacThat website

What leaves your Mac, and when

To turn a recording into steps, a model has to look at it. The frames, clicks and transcript of that one recording go to the provider you picked when you set Ditto up: your own Anthropic, OpenAI or Amazon Bedrock account, or Ditto AI's. With your own account, that provider's terms and your own bill apply.

To find tools, Ditto looks up each app or site the recording used, by name and address, in the official MCP registry and on npm. That lookup runs on the same server that reads your recording: Ditto AI's, or the one built into the app on your Mac when you use your own key. Nothing else about your Mac is sent. When an agent runs, it talks to the tools it was given, the way you would.

Record only what you're fine sending to that provider. A recording captures whatever is on screen, including other people's messages if they're open.

The model doesn't set permissions

The split is deliberate. A model reads the recording and decides what the process is, its steps, which values are inputs, and how to rank the tool servers that were found. It does not decide what the agent may touch.

  • The agent gets only the tools your recording used. Everything else is denied.
  • Read or write comes from a fixed table, per tool. Public web pages are always read-only.
  • Anything Ditto can't classify counts as a write. That errs toward asking you, never toward doing.
  • Each host gets the policy in its own terms: an allowlist for Claude Code, allow and deny rules for Kiro.

The exported policy says how it was made, policy_derived_by: deterministic-table-lookup, so you can check that no one chose the scope by hand. See a real one on the Wikipedia template.

Checking a tool never changes anything

Before a tool counts as working, Ditto starts its server, completes the MCP handshake and makes one real, read-only call. It prefers a call that needs no arguments, and it never fills in a placeholder to make one work.

  • A tool counts as a write if the server's own MCP annotations say so (readOnlyHint, destructiveHint), otherwise by its name. Unknown counts as a write, and writes are never called during a check.
  • If a server needs Node or uv, you see the exact command with Allow and Deny before anything is installed, and only toolchains from a fixed list are offered.
  • A key that's rejected stays on that server and says so. Ditto doesn't quietly move your task to another server.

Nothing is invented

  • Servers come from the MCP registry and npm. The model only ranks what was found; anything it suggests that wasn't in the results is thrown out.
  • Every step points at the frames and clicks it came from. A step with nothing to point at is dropped. Narration can explain a goal but can't add a step on its own.

During a run

  • Ask before it creates, sends or changes anything: every write is prepared as a draft and shown to you first.
  • With that off, the agent does the writes it was recorded doing, in the same place, and still stops to ask before deleting anything, sending somewhere new, or doing anything you didn't record.
  • Stop ends the run and every tool server it started.

Sharing an agent

An agent is a file. When someone opens it on another Mac, it goes through the same review there, and its permissions are worked out again on that Mac rather than trusted from the file.

Limits worth knowing

  • Permissions are coarse for tools Ditto doesn't know. An unrecognised MCP tool gets write access: safe, but wider than necessary. Access is set per tool, not per action.
  • The app isn't notarized by Apple yet, so macOS asks you to confirm the first open. How to open it.
  • In Kiro, the headless browser runs without Chrome's own sandbox, because that sandbox can't start inside Kiro's. Kiro's sandbox still contains it. Other hosts keep Chrome's sandbox.
  • An agent acts with your accounts. Within the tools it's allowed, it can do what those accounts can. Review the policy before the first run.

Reporting a security problem

Email [email protected] with "Security" in the subject. Please include the version (Ditto AI menu, then About) and the steps to reproduce. You'll get a reply from a person. The same contact is published in security.txt.

For what the app records and how long it keeps it, see the privacy page.

Do it once. Then hand it off.

Record a task on your Mac and Ditto AI builds the agent. You read it before it runs.

macOS 15 or later · Apple silicon · Opening it the first time