← Docket

Security & privacy, verifiably

You can check everything on this page yourself, in about five minutes, with an outbound firewall. Docket runs on your Mac: no server of ours holds your work, and there is no account and no telemetry. Below is every network connection it can make, enumerated from the code, plus what the macOS Keychain does and does not buy you, and the one host we run. Put your clients' work in it and the work stays on the machine you already trust with it.

Every connection, enumerated

This list cannot quietly drift from the app you downloaded. The hosts live in hosts.json, a file that ships with this site so you can read it yourself, and a lint runs on every deploy that fails if this page names a host the file does not, or omits one it does. That is what makes the table below evidence rather than a promise.

ConnectionWhenWhat is sent
Your JiraOn sync, when you write back, and when you open an epic and press Show everyone'sYour queries; the comments, status changes, estimates, priorities, assignees, work logs and new tickets you send or approve. Show everyone's reads one epic's tickets, once, and writes nothing. Authenticated with your own token, sent only to the host you configured.
Your ConfluenceOn syncA mentions query, your token.
Linear (api.linear.app)On sync, and when you write backYour personal API key; a query for the issues assigned to you, and the comments, status changes, estimates, priorities, assignees and new tickets you send or approve. One GraphQL endpoint does all of it, so your firewall sees a single host rather than a spread.
Figma (api.figma.com, plus the storage host it names)On sync; thumbnails on demand; a reply when you send oneYour token or your signed-in grant; the keys of the files you added and, with a token, of the files in the team you named. What comes back is your comments, the names of the files they’re on, and a rendered picture of the spot each comment is pinned to. Docket asks a file for nothing else. The one thing it writes is a comment: a reply you send from Docket, posted in that file’s comment thread. It never changes a design.
Dovetail (dovetail.com) / Miro (api.miro.com)On sync, only if connectedYour token.
Google Calendar (direct)Never in a stock install. Docket ships no Google OAuth client, and your calendar comes from your Mac's own calendars through Apple's EventKit — which is not a network connection at all. This route opens only if you create an OAuth client in your own Google Cloud project and write its client ID and secret into your config file by hand. If you do, then on sync and on token refresh: www.googleapis.com and oauth2.googleapis.com.Your own OAuth tokens; the focus blocks you approve. Until you do that, nothing — neither host can be reached.
Your mail server (IMAP)On sync, only if you added a mailboxYour IMAP login. Read-only by protocol — the app uses EXAMINE and PEEK, so it cannot mark mail read, move or send anything. Headers only — with one deliberate exception: when a message contains a calendar invitation (a text/calendar part), that part alone is fetched so the invitation can be shown. Prose bodies are never fetched or stored.
Your own feedsOn sync, only if you added anyThe URL and header you configured. Nothing else.
AI engineOnly when you ask for a draftBy default the AI runs on this Mac only. Generation runs on Apple's on-device model, and on Ollama at localhost:11434 if you run it, which is also your Mac. An engine is on this Mac only at a loopback address: localhost, ::1 or one starting with 127. Any other address, a .local name included, is an external engine. We check where localhost points at every call, and we never follow an engine's redirect. External engines are your choice and send nothing until you pick one: an installed and signed-in Claude CLI, whose prompts go to Anthropic through that tool, a Claude key → api.anthropic.com, a Gemini key → generativelanguage.googleapis.com, or a custom endpoint → the URL you typed. The select on the AI engine card in Sources, Where generation runs, has three positions: On this Mac only is the default and sends nothing, ever; This Mac first tries the two local engines and then the external ones you set up; Any engine drops the preference and lets the best-configured engine answer. If your install already used an external engine before this default, we kept the position it had. Anything you mark sensitive stays on this Mac whatever that setting says, and the Sensitive box starts ticked for every recording. The same card names the engine that answered your last request, and names any engine that was handed the prompt even if it did not answer, so you never have to take this paragraph's word for it.
Gumroad (licence)On activation, then at most once a dayYour licence key, the product id, and a yes or no on whether to count this Mac. That is the whole request. We send yes only on the first check for a key on this Mac. Gumroad then adds one to that key's use count. That count is how a team licence sees how many Macs use it. Every later check sends no, so a daily check never uses up a seat. Not your device id, not your name, never your data. Offline keeps working for 14 days between checks, and everything already synced stays readable forever.
Update check (docketmac.com)Once, shortly after launchOne GET for a small static file naming the current version and where to download it. Nothing is sent — no licence key, no device identifier, not even the version you are running: the comparison happens on your Mac after the file arrives. If there is an update, the download comes from github.com/timreerink-del/docket-releases and lands on objects.githubusercontent.com, where GitHub serves release files.
Speech model (huggingface.co, then *.cdn.hf.co)Once, the first time you record or dictate~574 MB, downloaded once. This is the model that transcribes your meetings, and it runs on your Mac from then on — the audio itself never leaves. Hugging Face redirects the download to a regional CDN, so your firewall may show a different subdomain than ours does.

Two rows mention googleapis.com, for unrelated reasons. That is why this list names subdomains: generativelanguage.googleapis.com is Gemini answering a draft you asked for, and it is the only one of the two a normal install can ever reach. www.googleapis.com or oauth2.googleapis.com would be calendar traffic — impossible unless you built your own OAuth client, so if you see either without having done that, treat it as a bug and report it.

Not in this list, because it does not exist: analytics, crash reporting, a telemetry endpoint of any kind. Nothing above reports on you, and nothing above is something we can read.

This list used to say "a Docket server of any kind", and that stopped being true. The update check reads a static file from docketmac.com — the same host serving this page. It holds no account, no database and none of your data, and the request carries nothing about you. But it is a host we control, and its logs see an IP the way any web server does. A list that denied it would be worth less than one that names it.

Connectors you add from the library

Docket ships a library of connectors for the tools your work lives in besides the ones above. Each one is a template inside the app: you pick it in Sources and paste a token you made at that tool, and the work assigned to you there counts in Needs you and My work like a Jira issue. Docket reaches none of these hosts on its own. Each is contacted on sync, and only after you added its connector. What is sent is your token and the query for your own items. They read, and write nothing back.

ConnectorWhat it does
Asana
app.asana.com
Reads the incomplete tasks assigned to you in one workspace, if you added the Asana template in Sources.
ClickUp
api.clickup.com
Reads the open tasks assigned to you in one Workspace, if you added the ClickUp template in Sources.
GitHub
api.github.com
Reads the issues or pull requests assigned to you, if you added a GitHub template in Sources.
GitLab
gitlab.com
Reads the issues or merge requests assigned to you, if you added a GitLab template in Sources.
GitLab, self-hosted
the address you entered
Reads the issues or merge requests assigned to you on your own GitLab, if you added a self-hosted GitLab template in Sources.
Linear
api.linear.app
Reads the issues assigned to you, and writes back the comments, status changes, estimates, priorities, assignees and new tickets you send or approve. The Linear catalogue template reads the same issues and writes nothing.
monday.com
api.monday.com
Reads the items assigned to you on one board, if you added the monday.com template in Sources.
Notion
api.notion.com
Reads the pages assigned to you in one database, if you added the Notion template in Sources.
Sentry
sentry.io
Reads the unresolved issues assigned to you in one organization, if you added the Sentry template in Sources.
Todoist
api.todoist.com
Reads your open tasks, leaving out ones assigned to others, if you added the Todoist template in Sources.
Trello
api.trello.com
Reads the open cards you are a member of, if you added the Trello template in Sources.

This table is not typed. It is rendered from the rows hosts.json marks "catalogue": true, which sit with the connections you enable and never with the ones Docket makes by itself, and the same lint fails the deploy if the two disagree. The library travels inside the app and changes with releases, so adding a connector fetches no list from us.

Verify it yourself

Run Docket behind Little Snitch (or any outbound firewall) for a day. You should see the hosts you connected in Settings, and these four that Docket reaches on its own:

Anything else is a bug and a broken promise, and the moment you report it, it becomes the most urgent thing on the board. This paragraph was wrong once, and it is worth knowing how. It named only one of those four self-initiated hosts, so the sentence inviting you to run this test would itself have failed it. That is why the list is checked against hosts.json on every deploy now rather than kept in someone's head.

Where your data lives

Everything Docket stores is plain, readable files on your Mac: JSON you can open, back up, and take with you. No proprietary database, no lock-in. The export button gives you all of it at once. If you switch on At the Mac, its times are one more plain file there, presence.json. Your meeting recipes are recipes.json. What each one wrote sits beside its meeting's transcript.

Your tokens are in the macOS Keychain — Jira, Confluence, Figma, Dovetail, Miro, your mail password, the token of every connector or feed you add, every AI key and your licence key. You can see them yourself in Keychain Access, under the name Docket, and delete any of them there. They are marked this device only, so they never sync to iCloud and never restore onto a different Mac from a backup.

What that does and does not buy, measured rather than assumed. It means the tokens are encrypted at rest while your keychain is locked, and that a copy of Docket's data folder — or a backup of it — carries no credential to any service you connected. One token does stay in that folder, and we would rather name it than let you find it: a random string Docket generates for itself, so its own window, the docket command and your own scripts can reach the backend running on your Mac. It authorises nothing anywhere else. It does not mean another program running as you cannot read them: we tested it, and the security command-line tool reads a Keychain item in plaintext with no prompt, with or without an access-control list naming only our own binary. Nothing on macOS prevents that short of sandboxing, and Docket cannot be sandboxed because system-wide dictation needs Accessibility. A tool that told you the Keychain made your tokens unreadable to other software would be telling you something untrue.

One file on that local backend needs no token: the copy of your synced items that Docket's window loads at start, which any program running on your Mac can read.

One credential in Docket is not yours, and it is not secret either. Docket ships its own Figma client identifier and client secret inside the app bundle, the way desktop apps do. That pair identifies Docket to Figma — it is what lets Figma show you a reviewed consent screen naming the app that is asking. Anyone can unzip a .app and read it, so we treat it as public and so should you; on its own it grants access to nothing. A token that can read or write anything of yours is issued only when you sign in and approve that screen; that token is yours, it goes in your Keychain with the rest, and you can revoke it at Figma at any time.

What that Figma sign-in actually grants is your comments and the names of the files they're on, in the files you add. The consent screen names five permissions and this is what they add up to: which account signed in, the comment threads on the files you add to Docket, those files' names, a rendered picture of the spot each comment is pinned to, and posting the replies you write in Docket. The picture is why a file's contents are in there: Docket asks Figma to draw the spot a comment points at, and asks a file for nothing else. The sign-in cannot list the files in a team, because Figma does not let a public app do that, so it reaches the files you add and any Figma file linked from your issues, and nothing else. If you want Docket to find the files in your team for you, that takes a pasted personal access token, which carries your whole account's access. You can withdraw the sign-in at Figma, under Settings then Connected apps.

If your keychain is locked or refuses, Docket says so and keeps working from the config file rather than failing silently — and it never removes the file copy until it has read the value back out of the Keychain successfully.

Docket takes no token from another tool's config file. The copy you download uses only the tokens you enter and the sign-ins you complete. If you also use Anthropic's Claude CLI, Docket looks in that tool's ~/.claude.json for the names of the servers set up there, to tell you whether a connector can work through it. It reads no credential from that file and never changes it.

Two ways in from outside the window

Docket answers docket:// links, and it ships a docket command for Terminal and launchers. Neither one opens a network connection, so neither adds a host to the list above. They are new ways in on your own Mac, and this is exactly what each one can do.

A link can leave a card in Needs you after you confirm it. It cannot post, change or read anything. Any web page, mail or app on your Mac can open a docket:// link, so a link can do four things and no more: bring Docket forward on a view, put a question in Ask without sending it, and, after you click Keep in a dialog Docket shows every time, leave a card in Needs you or change the current frame. A card writes nothing until you choose what to do with it in Docket. A link gets nothing back, opens no other link and runs nothing. Docket takes five links a minute, keeps at most five cards from outside, and never lets one push your own cards out of Needs you.

The docket command can do what Docket's own window can, because it uses the same token. It reads that token from the config file in Docket's data folder and refuses if any other user can read the file. It never takes the token from a command line, and before it sends it, it asks the server to prove it already holds the same token, so another program listening where Docket usually does is sent nothing. A capture from the command is a card in Needs you, like one from a link, without the dialog.

What Docket notices on your Mac

Docket can note when you are at your Mac, so the Day closure says what happened rather than what you planned. We built it off. It stays off until you switch on At the Mac in Settings, under Your data.

When it is on, Docket notes two kinds of time: at the Mac, and away. Away means the Mac is locked or asleep, or no key or pointer has moved for 5 minutes. Each stretch is a start time and an end time, and that is all. Docket never notes which app is in front, a window title, a web address, a keystroke, the microphone or the screen.

The times stay in presence.json in Docket's data folder for 30 days, and older days are removed. Delete all, beside the switch, removes every one at once. Switching it off stops the noting. What is there stays for its 30 days, or until you delete it.

This is not telemetry, because nothing is sent. Telemetry reports to someone else. These times open no connection and add no host to the list above. They are read by one thing: your own Day closure, which adds a line such as "You were at the Mac 08:40 to 17:04, 6h 42m in all." On the default AI setting, On this Mac only, the closure's draft may use those times. On any other setting they are kept out of every prompt and shown as their own line.

Docket can sit in your Mac's menu bar. We built it off. It appears only after you switch on Show Docket in the menu bar in Settings, under This Mac. While that is off, there is no menu-bar item at all.

It shows the name of your current frame, or the Docket mark when none is set. It never shows a count, a badge or a clock. Its menu holds your frames, Clear frame, Open Docket and Open Needs you.

A meeting title appears only if you ask for it. A second switch, Show the next meeting in the menu, adds your next meeting today to that menu. It is off by default, because anyone watching your screen share can read the menu bar.

The item reads two files in Docket's data folder: frames.json and current-frame.json. With the second switch on, it also reads harness.json for today's meetings. The item writes no file. It sends nothing off this Mac, so it adds no host to the list above. Choosing a frame changes Docket's current frame, the one a docket:// link or the command sets. It never writes to Jira, Linear, your calendar or any other tool.

The discontinuation pledge

Two commitments, so that buying from one person is not a risk you carry on your own. Your data is never hostage: plain files, export always, and everything already synced stays readable even if your subscription lapses. And if we ever stop maintaining Docket, we will open the source, the pledge Obsidian made. The code is not open today because a paid app is what keeps one person building it.

Want it?

Buy Docket → €18 a month, or €180 a year — two months free.