Endpoint behaviour disclosure
Every process we spawn, every port we open.
Bolt works on your machine, so the work is visible on your machine: it reads your screen, your clipboard and the files you point it at, and drives other applications for you. Everything it does to get that done is listed here, with the reason attached and the command to check it yourself. Behavioural tooling flags this class of application - Zoom, Loom, Raycast, Alfred and iTerm are flagged the same way - so the useful thing we can give you is not reassurance, it is the full list.
First, what never happens
Bolt does all of this on your machine so none of it has to leave. That's the trade this page documents - the list below is long because it's showing you local behaviour you can watch, instead of network traffic you can't.
with administrator privileges is on the explicit list of markers Bolt flags in caller-supplied AppleScript.1. Code signing identity
Verify the identity yourself before you trust anything else on this page. On macOS,
codesign -dv --verbose=2 /Applications/Bolt.app should report an authority of
Developer ID Application: Sparcle Inc. (4VSW7NBZ2S), a team identifier of 4VSW7NBZ2S, an
identifier of app.sparcle.bolt.enterprise, and a stapled notarization ticket. For the
Gatekeeper assessment use spctl -a -vvv -t exec /Applications/Bolt.app. An
earlier version of this page printed -t install, which is the type for
installer packages rather than application bundles, so anyone who copied it was running the
wrong check. Verifying the
download itself, including the signed release manifest and the software bill of materials,
is covered at verify your download
and supply chain.
If something in this inventory does not match what you observe on your own machine, that is the most useful message you can send us. Write to security@sparcle.app, or use the coordinated disclosure process. A gap between this page and reality is a defect in the page, and we will correct it.
2. Why we publish this
3. Processes Bolt spawns
Grouped by what they're for. Some depend on your platform or your own setup, so not every row runs on every machine.
Screen, clipboard and on-screen content
| Binary | Why it runs | When | What your tooling shows |
|---|---|---|---|
screencapture | Captures the screen, a region, or one window id to a temporary PNG for the screenshot tool, the OCR bridge and the pixel-colour sampler. The screenshot tool checks the Screen Recording permission first and returns a permission error rather than capturing without it. | On a screenshot, OCR or pixel-sample request. | A console sees the system screenshot tool run. |
powershell.exe | The Windows equivalent of the above: a GDI CopyFromScreen script, because Windows has no screencapture binary. | On a screenshot request. | A console sees PowerShell run a screen-copy script. |
gnome-screenshot, spectacle, scrot, import, flameshot | The Linux equivalent. Bolt probes with which to find whichever one you have, and runs that. | On a screenshot request. | A console sees your desktop's own screenshot tool run. |
bolt-ocr | A signed helper we ship inside the bundle. Runs Apple Vision text recognition against an image file already on disk. No network call and no model download; the pixels do not leave the device. | On an OCR request, and by the workers that read text out of an image when one is copied or saved. | A console sees a signed sibling binary launch inside the app bundle. |
wl-paste, xclip, xprop | Linux only. Reads the clipboard's advertised MIME types to detect the KDE password-manager concealed hint, so that Bolt does not record a password manager's clipboard entry into history. It fails open: if nothing can answer, the content is treated as not concealed. | Automatically, as part of clipboard capture. | A console sees the clipboard's type list read. |
bolt-ax | A signed helper we ship inside the bundle. Reads the macOS Accessibility tree: window titles, window geometry, the current selection and menu structure, and performs window and menu actions. Secure text fields are replaced with a redaction marker inside the helper before anything crosses back into Bolt. It exists so that Bolt does not have to drive System Events, which would raise an Automation prompt for every application. | On selection and screen-context requests and on launcher window actions, and automatically on every application switch when Accessibility has been granted. It is skipped silently when it has not. | A console sees a signed sibling binary in the app bundle read window information. |
Desktop automation and script interpreters
| Binary | Why it runs | When | What your tooling shows |
|---|---|---|---|
osascript, reading | AppleScript and JXA against Mail to read messages, and against System Events to read the frontmost application. Calendar, Reminders and Contacts are not read this way: those go through EventKit and Contacts.framework, which send no Apple Events and are gated by their own narrower permissions - Calendars, Reminders and Contacts, each with its own system prompt - rather than by one Automation grant that would cover anything Bolt could ever ask that application to do. Contacts requires a search term and will not enumerate the whole address book. | On a request that needs that data. A background or speculative read refuses to spawn osascript at all unless the target application is already running, and defers rather than raising a first-time Automation prompt. | A console sees AppleScript run against Mail or System Events. |
osascript, writing | The same interpreter, used to compose a mail message, send a reply, send an iMessage, respond to an invitation, and add attendees to an event. The last two stay on AppleScript because EventKit exposes attendees and participation status as read-only, with no public write API: it is the only interface macOS offers for them. Creating and updating events and reminders goes through EventKit. These are writes to your data and to other people. | Only on an explicit request. The macOS Automation permission and, for several of them, Accessibility, gate them first. | A console sees AppleScript send a message or answer an invitation, after the macOS Automation prompt. |
osascript, arbitrary | Bolt exposes tools that run caller-supplied AppleScript and JXA. We are explicit internally that AppleScript can call do shell script, so this is arbitrary shell execution wearing a desktop-automation label, and it is excluded from every sandbox tier for that reason. | Off by default. AppleScript, JXA and PowerShell script execution must each be switched on by an administrator; no opt-in ships enabled. | A console sees AppleScript run text supplied by the caller. Nothing to see unless an administrator turned it on. |
powershell.exe | Window management (raise, move between displays, snap, fullscreen, restore), enumerating windowed processes for the running-apps list, reading the foreground window, launching an application, extracting an application icon from an executable, and reading one entry from Windows Credential Manager. | On the corresponding action, and whenever the running-apps list refreshes. | A console sees PowerShell move windows and read one credential entry. |
cmd | Hands a mailto or ms-settings URI to the default handler, and runs a caller-supplied command line for the terminal-execution tool on Windows. | On the corresponding action. | A console sees the Windows command shell run. |
sh, /bin/sh | Runs a caller-supplied command line for the terminal-execution tool on Unix; runs the raw Exec line out of a Linux desktop entry, which can carry placeholders and arguments and therefore needs a shell; probes whether a search backend is on PATH; and runs a small detached relaunch script after a bundle rename. | On the corresponding action. The relaunch script runs at startup only when a rename actually happened. | A console sees a shell run. |
gdbus | A generic D-Bus call tool on Linux, with a caller-supplied destination, object path, method and arguments. | Only on an explicit request. | A console sees a desktop-bus call you asked for. |
Shell execution that Bolt injects, as opposed to what you type yourself, crosses a native gate before its bytes reach a terminal. The gate classifies the command line as safe, destructive or catastrophic; the default posture runs safe commands, requires explicit confirmation for destructive ones, and refuses catastrophic ones outright. An administrator can tighten it to confirm everything, or to refuse injected execution entirely. A surface with no way to ask you for confirmation is treated as unconfirmed and therefore refuses rather than proceeding. A command line carrying what looks like a live credential is escalated to require confirmation, so that a secret cannot be put on a command line silently. Every refusal and every confirmation is written to an append-only audit log as a fingerprint rather than as the command text. A command you type into the terminal yourself is never gated, by design.
Process, window and connection discovery
| Binary | Why it runs | When | What your tooling shows |
|---|---|---|---|
kill, taskkill | Terminates an orphaned bolt-api that still holds the port, after the name check above; and force-quits an application when you ask Bolt to quit it. On Windows the whole tree is killed, because a surviving grandchild can keep the inherited listening socket. | Automatically at startup for the sidecar; on demand for an application. | A console sees process termination initiated by Bolt. |
wmctrl, xdotool, xprop | The Linux equivalents of the window work: list windows with their process ids and classes, resolve a window from a process id, position, resize, activate and gracefully close, and read the active window's name and process id. | On the corresponding action, and whenever the running-apps list refreshes. | A console sees window information read. |
mdls | Reads an application bundle's size, last-used date and install date for the launcher's application info panel. | On demand. | A console sees an application bundle's metadata read. |
sample, eu-stack | When the freeze watchdog detects a stall or a resource-ceiling breach, it samples process stacks to enrich the report. The target is always Bolt's own process id; it never samples another process. | Automatically, and only on a detected freeze. | A console sees Bolt sample its own process, and only its own. |
Search, file discovery and opening files
| Binary | Why it runs | When | What your tooling shows |
|---|---|---|---|
mdfind | Spotlight. A filename-only lookup for launcher results, and a separate content search that is opt-in and scoped to the folders you configure as scan roots. | Query-driven. There is no background indexing sweep behind these. | A console sees a Spotlight query. |
plocate, rg, where, recollq, tracker3 | The filename and content search backends on Linux and Windows, used according to what is installed. | Query-driven. | A console sees a file search run through the index you already have. |
qlmanage | Renders a Quick Look preview of a file you selected. | On demand. | A console sees a preview helper launch. |
open, explorer, xdg-open, xdg-email, gtk-launch | Opens a file, folder, URL or mail draft in the operating system's own default handler, and reveals a file in Finder or Explorer. The hyphen-argument-injection guard - refusing a target that starts with a hyphen so it cannot be parsed as a flag by the spawned handler - exists in exactly one of these paths today: the browser-URL opener. File and application opens, revealing a file in Finder or Explorer, and the Linux mail-compose tool (which an LLM can invoke directly, with the recipient address as the unguarded value) each hand their target straight to the OS handler with no such check. See section 9. | On demand. | A console sees a process-launch chain from Bolt into the handler application. |
Credential and secret store integration
| Binary | Why it runs | When | What your tooling shows |
|---|---|---|---|
bw, bws, op, vault, aws, az, gcloud, pass, keepassxc-cli, secret-tool, kwallet-query | Bolt federates the secret managers you already run rather than making a second copy of your secrets. Each of these is that vendor's own command-line tool, installed by you, not shipped by us. Reading a secret additionally requires that tool's own authentication, and a revealed secret is written straight to the system clipboard in native code rather than being returned across the application boundary. | Reading a secret is only on an explicit query or reveal. Detecting which tools are installed is not: today Bolt runs each installed tool's version command at app launch, again on every reconnect, and on TOTP host scans and unlock checks. That is more than detection needs and we are removing it, so that presence is determined from the filesystem without executing anything. Until that ships, expect these version commands at startup on a machine that has the tools installed. | A console sees your own vault tool run, under that tool's own authentication. |
The availability probe | When the vault surface asks which providers are available, Bolt looks for each tool on your PATH by walking the directories in it and checking for an executable file. No process is started, so having a vault CLI installed does not cause Bolt to run it. A provider you never use is never invoked. | When the list of vault providers is requested. | Nothing. No process is started. |
The local database, and preparing its binaries
| Binary | Why it runs | When | What your tooling shows |
|---|---|---|---|
postgres, initdb, pg_ctl, pg_upgrade, pg_controldata | Runs, initializes, stops and version-upgrades the local PostgreSQL cluster described in section 5. The stop path only acts if the process holding the port matches what our own postmaster.pid claims; otherwise it leaves it alone. | Automatically at startup, and on a detected version change. | A console sees a database server start under a desktop application. Section 4 explains why. |
(no process - getxattr(2)/removexattr(2)) | Bolt removes the com.apple.quarantine attribute from the PostgreSQL directory inside its own data directory, recursively, so the database it just extracted can execute. It is never done to your files or to the application bundle. It is two direct system calls rather than a subprocess, so nothing is spawned, but the attribute is still removed and we count that against ourselves. | On the first launch after the payload is extracted or upgraded, then skipped on every later launch. | A console sees an extended attribute removed from files inside Bolt's own data directory. Never from your files, and never from the application bundle. |
codesign | Both macOS architectures receive a PostgreSQL payload we build ourselves, signed with our Developer ID and pinned in the binary to a digest that is checked before the bytes are used. Three read-only invocations run against the payload's own binaries: codesign --verify --strict, codesign -dv --verbose=2 to read the signing authority out of the signature, and codesign --verify --verbose=2 against the postmaster before the preparation is recorded as done. Their answer decides one thing, whether Bolt proceeds or stops. A payload that does not carry our signature is refused, and the install stops with an error naming the path. | On the first launch after the payload is extracted or upgraded, then skipped on every later launch. | A console sees a signature read against files inside Bolt's own data directory. |
ldd | On Linux, reads the shared-library dependencies of the payload's own binaries so that a missing system library is reported as a clear message naming it, rather than surfacing as a database that will not start. | On the first launch after the payload is extracted or upgraded. | A console sees a dependency read against files inside Bolt's own data directory. |
The PostgreSQL payload arrives signed with our Developer ID and pinned in the binary to a SHA-256 digest that is verified before a single byte is unpacked. A payload that does not match the pin is not used. It is already linked against its own libraries and already carries our signature, so it is extracted and run exactly as it left our build. Bolt reads its signature and acts only on the answer: a payload it did not sign is refused, and the install stops with an error naming the path. The installer served from this site does the same, and verifies the same pin before it writes anything. The quarantine attribute is handled the same way: Bolt probes for it first and strips only what actually carries it. On the payload we ship, nothing does, so on an ordinary install the strip does not run at all.
Trust, permissions and system state
| Binary | Why it runs | When | What your tooling shows |
|---|---|---|---|
security | Reads the login keychain to find out whether Bolt's local certificate authority is already trusted, and removes a superseded one. Three subcommands run: find-certificate, verify-cert and delete-certificate. Installing the authority is not a subprocess: macOS grants trust through SecTrustSettingsSetTrustSettings and Windows through CertAddCertificateContextToStore, both in-process, and both raise the operating system's own consent prompt before anything is trusted. Bolt does install a local certificate authority, and section 6 covers it in full, including how to inspect and remove it. | See section 6. | A console sees the login keychain read for Bolt's own local authority. Section 6 covers this in full, including removal. |
systemextensionsctl | Read-only. The only call site that runs today is the bundle-rename guard: before renaming its own app bundle, Bolt asks whether its network-filter extension is staged, and declines the rename if so, to avoid orphaning it. Current releases ship no system extension, so the probe finds none. A failed probe is treated as absent (no extension), not unknown - refusing every rename on a machine where the tool is merely slow or missing would be worse than proceeding. A continuous status-refresh path also exists in the source, but nothing calls it: the module's own doc says the settings surface that would wire it in has not shipped yet. | Only when a bundle rename is about to happen, which is rare - not on every ordinary startup. | A console sees a read of the system extension database, on the rare occasion a rename triggers it. |
fdesetup | Reads FileVault status by absolute path, so that a binary planted earlier on PATH cannot answer for it. Needs no administrator rights. | Automatically, on window focus. A successful answer is cached for the life of the process, because changing FileVault requires a reboot. | A console sees FileVault status read. |
defaults, networksetup, loginctl, gsettings, brightness | The Finder hidden-files toggle; the Wi-Fi power toggle; log out; the GNOME dark-mode setting; and display brightness. | Only as launcher actions you invoke. | A console sees a launcher action you took. |
update-desktop-database | Refreshes the Linux desktop-entry cache after Bolt writes its own .desktop file to register the OAuth deep-link URL scheme, so the OS picks up the new handler. | Automatically, on every Linux startup - unconditionally, as part of app setup, not only when you invoke a launcher action. | A console sees a desktop-cache refresh run at every launch, not tied to anything you clicked. |
codesign | The exact invocation is codesign --verify --strict against the app bundle. It answers one question - does this build's own signature verify - used only to explain a sidecar launch-failure crash on the splash screen when one occurs. It is not used to detect a stale Accessibility grant: that heuristic looks only at the running executable's own path - a dev-swap staging path, or an install outside the canonical bundle - and never calls codesign. | Only when the sidecar fails to start and Bolt is diagnosing why. | A console sees a signature read, on the rare occasion a launch failure triggers it. |
Programs you configure
| What | Why it runs | When | What your tooling shows |
|---|---|---|---|
| MCP servers | Whatever command you configure. Bolt spawns a Model Context Protocol server over standard input and output when you add it and mark it as running on this device. Typically a Node or Python entry point. | Only after you add it. | A console sees the server you configured run. |
| Coding-agent CLIs | Third-party agent binaries hosted over a stdio protocol. The built-in roster names devin, claude-agent-acp, codex-acp and gemini, none of which we ship; the roster is extensible from a file in your home directory, so an administrator can add others. A readiness probe runs the agent's own authentication-check command so the interface can tell you to sign in. | On selecting an agent, and when the interface evaluates which agents are ready. | A console sees the agent binary you installed run. |
| User Apps, the ones we ship | Twenty-eight command definitions written by us, shipped inside the signed bundle and copied into Bolt's data directory on launch, enabled by default. They are ours, not yours, and they are listed by name in the panel below this table. The feature is named for the fact that you can add your own, which is a different statement from the one an earlier version of this page made. | The command itself runs only when you invoke that App from the launcher and press Enter. Separately and automatically, a detection probe runs the tool's own version and authentication-status commands, so the launcher can hide an App whose tool you do not have. | A console sees the command behind the launcher entry you invoked. |
| User Apps, the ones you add | The same loader, pointed at any manifest you or your administrator drops in the same directory. The safety properties are the same for both halves: the loader rejects a command template containing a shell metacharacter, arguments are substituted into argv slots rather than into a command line, and the command line is never handed to a shell for interpretation. Some Apps, ours included, run a bundled shell or Python script as their program, which is an argv-only spawn of the interpreter and not the same thing as shell interpretation of the template. | As above. | A console sees the command you or your administrator defined. |
| git, docker | Read-only enumeration with a fixed argument list, to populate launcher autocomplete: branch and tag names, container and image names. You cannot influence the arguments, only the working directory. | While typing in the launcher. | A console sees a fixed read-only query against a tool you installed. |
| tmux | Lists panes across your tmux server and Bolt's own private one, with a captured tail of each, and can focus, kill or send keys to a pane. Sending keys crosses the command governor described above; focus and kill carry no command line. | When the tmux launcher scope is open. | A console sees tmux listed or driven. |
| bolt-cli | A signed helper we ship inside the bundle. Launches an application or opens a document while holding the launch assertion open, which is what makes strictly-managed applications start reliably without blocking the launcher. | Only when you open an application or document from the launcher. | A console sees a signed sibling binary launch inside the app bundle. |
MCP servers and coding-agent binaries genuinely are yours: the executable is whatever you or your administrator named, so the table above describes the mechanism rather than the programs. They are spawned from your configuration and are not routed through the command gate, because that gate classifies command lines and these are program invocations. User Apps are the opposite case, and an earlier version of this page got it badly wrong.
The User Apps we ship, enumerated
Bolt ships twenty-eight User Apps inside the signed bundle and copies them into your data directory on launch, with the feature enabled by default. They are ours rather than yours, so they are enumerated here in full rather than described as user content.
Check the list rather than trusting it. The shipped copies are at
Bolt.app/Contents/Resources/sample-user-utils/, and the seeded copies are in
the user-utils folder of Bolt's data directory. Both are plain YAML, so
ls gives you the count and any text editor gives you the exact command line
each one runs. Read the seeded folder rather than the bundle if you want the truth about a
particular machine: it holds whatever a previous version seeded and anything you or your
administrator added, so its count is legitimately higher than twenty-eight on a long-lived
install. Your own build is the authority here, not this list.
What they reach for. Most wrap a vendor command-line tool you already
installed and signed into, so the network call is that vendor's own, made by their binary
under your credentials: GitHub, GitLab, AWS, Kubernetes, Okta, PagerDuty, Salesforce,
Slack, Stripe, Twilio and Vercel. Three reach the network without a vendor tool:
=whois queries a registrar through the system whois binary,
=ollama talks to a model server on your own loopback, and =sys
can reach the network in one specific mode, disclosed separately. Nothing here routes
through a Sparcle host.
They do not run on their own, and here is what that is worth. An App's command runs when you type its chip in the launcher and press Enter. The launcher shows a confirmation row first, worded by the manifest itself, so you can read what a given App will say in its YAML before you ever open Bolt. Setup guidance is display-only by design: where an App tells you to run a sign-in command, Bolt renders it for you to copy and never executes it, and the source says so at the type that carries it. Three qualifications, because the sentence above is worth less if we let it sound bigger than it is. The manifest format does allow an App to declare that it dispatches without that confirmation row, on a pattern match against what you typed. None of the twenty-eight we ship declares it, which you can confirm by searching the YAML for auto_when, but one you or your administrator add could. Then two things that are simply automatic. First, the detection probe: when the launcher first loads, when the Detected CLIs or User Apps settings section opens, and on an explicit rescan, Bolt runs each App's version command and its declared authentication-status command, eight at a time. That is a real spawn of a real vendor binary without you asking for that App. Second, seeding: the shipped manifests are copied into your data directory on launch and refreshed when we ship a better version, though a copy you have edited is preserved rather than overwritten. An administrator can switch the whole feature off, which stops both the probes and the invocations.
4. Ports and sockets
Whether a listener is bound to loopback or to every interface is the single most important fact on this page, so it is stated per port rather than in a summary sentence.
| Port | Process | Bind address | Off-box | Authentication |
|---|---|---|---|---|
13017 | bolt | 127.0.0.1 | No | A per-install bearer token, generated on first launch into local-api.key at mode 0600. A request from one of Bolt's own pinned origins is admitted to ordinary app routes without it, but that is a WEAKER tier and it deliberately cannot reach saved logins, TOTP codes, the vault or the secrets provider: an Origin header is asserted by the caller and any local process can set one, so it is treated as a hint, never as proof. Those credential routes require the token itself. Only the health endpoint is reachable without either. |
13018 | bolt-api | 127.0.0.1 or ::1 | No | Session cookie, HttpOnly and Secure. The desktop build refuses to start at all on a non-loopback address; see the note below. |
13020 | bolt | 127.0.0.1 | No | The relay that lets a coding-agent command-line tool route through Bolt's masking. The listener is created only when the feature is enabled: with the feature off there is no socket at all, so a port scan finds nothing rather than finding a listener that refuses. Disclosed with a caveat below about what still authenticates a caller. |
15432 to 15441 (Windows only) | postgres | Unix socket on macOS and Linux; 127.0.0.1 and ::1 on Windows | No | On macOS and Linux there is NO TCP socket. PostgreSQL is started with an empty listen address, so nothing binds a port at all, and it is reached only through a Unix socket inside a directory only your account can open (mode 0700). The single access rule is peer authentication: the kernel tells PostgreSQL which account connected, and that is the credential. There is no database password to steal, and no port to scan. On Windows PostgreSQL has no Unix-socket transport, so a loopback TCP port in this range and a password remain unavoidable there; that is a property of PostgreSQL, not a choice we made. Verify it yourself: on macOS or Linux nothing Bolt-related should appear in a TCP listener list for this range. |
Nothing binds 0.0.0.0. On the desktop build this is enforced rather than configured: before any listener is created, the sidecar checks that its configured host is a loopback name and that it is running in desktop deployment mode, and exits with an explanatory message if either is false. The check exists so that a copy of the sidecar extracted from the application cannot be pointed at a network interface and used to serve other people. The server build, which is a different binary you deploy behind your own ingress, deliberately does not carry this restriction.
Fallback ranges, and why a port number is not an identity. Both HTTP services auto-discover the next free port when their default is taken: 13017 through 13026 for the first, 13018 through 13027 for the second. Those two ranges overlap across most of their length, so on a machine where the defaults were already occupied you can legitimately observe either of those two services on a port that is not the one in the table above. The gateway is different and worth stating separately: its port is a fixed constant with no fallback at all, so 13020 is the only port it will ever use. If something else already holds 13020, the gateway logs the failed bind and does not listen anywhere. Do not go looking for it further up the range. PostgreSQL separately takes the first free port from 15432 through 15441 when its cluster is created, and thereafter reuses whatever port that cluster recorded in its own start-up options file, so a long-lived install is often not on 15432. The practical consequence for a reviewer: match on the process and the bind address, not on the port number. The bind address is the part we are asking you to hold us to.
The gateway. Port 13020 is a relay that lets a coding-agent
command-line tool send its traffic through Bolt, so that structured PII and secrets are
masked before the request leaves the machine. No listener exists while the feature is off:
the socket is bound when you switch it on and released when you switch it off, so a port
scan of a machine that is not using it finds nothing on 13020. When it is on it binds
loopback only, and a request must present this device's own Bolt credential.
Read what it is for precisely: it reduces what an agent sends when the agent is pointed at
it. Pointing an agent at it is a line you export. Bolt does not stop an agent from talking
to a model provider directly, and you should not deploy it as though it did.
Verify it yourself, and please do. On macOS or Linux, run
lsof -nP -iTCP -sTCP:LISTEN and filter for bolt and postgres. On Windows, run
netstat -ano and match the process ids. Every row should show a loopback
address. Anything that does not is a finding we want reported to security@sparcle.app. There is
a fuller walkthrough at prove it
yourself.
5. The database on your endpoint, and why
7. Permissions Bolt asks for
The operating system permissions Bolt requests, what each is used for, and what stops working if you deny it, are already published as section 3 of the review packet. Rather than keep a second copy that can drift out of step with the first, that table stays the one place it lives: read it on the review packet page. All of them are optional, and Bolt runs without any of them.
Three things relevant to this page are not on that table. First, macOS Automation, sometimes called Apple Events: it is what the AppleScript rows in section 3 require, it is requested per target application by macOS rather than by us, and declining it disables those readers and writers only. Second, current releases ship no system extension, so there is none to approve (section 1 says why). Third, nothing on this page requires administrator or root privileges at any point, including the certificate authority in section 6 and the database in section 5.
8. Files and directories Bolt writes
9. Hardening, and how to see it
What we will and will not put on a public page, and how to get the rest.
Where the platforms differ
Most of this page describes behaviour that is the same everywhere. Protection of the local database and its keys is not, and the differences are large enough that a Windows reviewer should not infer macOS properties. What follows is the ceiling each platform allows, not a claim about what ships today - the socket and operating-system-identity work described here is in progress, and section 9 tracks it.
FAQ
Questions a reviewer actually asks
Does anything about me, my machine, or my data reach Sparcle?
Can an attacker use Bolt to reach something they could not reach without it?
local-api.key, mode 0600. Hardening of the local listeners is ongoing work rather than finished work, and we will walk your security team through the current state of it directly.
Does Bolt need administrator or root privileges?
with administrator privileges is on the explicit list of markers Bolt flags in caller-supplied AppleScript.
Can any of these listeners be reached from the network?
127.0.0.1 or ::1, never 0.0.0.0. You should not take that on our word - the ports section names each one, and you can confirm every binding on your own machine with the commands there, or with any process monitor.
Why does my EDR flag Bolt?
Does Bolt install a root certificate, and can I prevent it?
localhost, so browsers and the Bolt extension get warning-free HTTPS. Be precise about how it is offered: on a normal first run it is a step you can decline, and a decline is permanent. Outside that sequence Bolt will attempt the install at start-up if it is not already trusted and you have not previously declined - in which case the operating system's own prompt is the consent surface. Administrators can switch it off entirely with the AllowLocalCertificateTrust policy key, which defaults to off on a managed device. The exact commands to inspect or remove it are in the certificate section.