All writing

JetBrains Toolbox proxy settings and certificates that survive updates

JetBrains Toolbox proxy settings and certificates live in .settings.json: a proxy block, plus a network.keystore that adds trust without patching cacerts.

JetBrains Toolbox keeps its proxy in a file called .settings.json, as a proxy block with a type, a host and a port. If the proxy terminates TLS, Toolbox also has to trust that proxy's certificate authority, and there are three places to put it: the operating system's root store, the cacerts file inside Toolbox's bundled Java runtime, or a separate trust store named by the network.keystore setting. The first trusts the certificate machine-wide, the second is undone by Toolbox's own self-updates, and the third adds one certificate for Toolbox alone and stays put.

JetBrains documents the first and does not document the third. Everything below about network.keystore rests on the source and tests of jtaccel, the studio's MIT-licensed local proxy that speeds up Toolbox downloads and writes exactly these two settings, so each claim links the line it comes from.

Where the settings file lives

JetBrains' Toolbox FAQ gives the path on each platform:

  • Windows: %LOCALAPPDATA%\JetBrains\Toolbox\.settings.json
  • macOS: ~/Library/Application Support/JetBrains/Toolbox/.settings.json
  • Linux: ~/.local/share/JetBrains/Toolbox/.settings.json

On Linux, jtaccel checks $XDG_DATA_HOME/JetBrains/Toolbox first and falls back to the path above, and it accepts a JTACCEL_TOOLBOX_DIR override for installs elsewhere.

The file is small, because Toolbox omits any setting left at its default. On the Mac this was written on, running Toolbox 3.8.1, it holds four top-level keys (shell_scripts, statistics, plugins, disk_usage) and no proxy at all.

Quit Toolbox before you edit it. jtaccel's source records why: "Toolbox keeps settings in memory and flushes them, so an external edit made while it is running gets overwritten." Its installer stops Toolbox, writes, and starts it again.

The proxy block

Toolbox's UI offers system settings, automatic configuration, HTTP and SOCKS under its Proxy section. Choose HTTP with address 127.0.0.1 and port 8899, and Toolbox writes this:

"proxy": {
    "type": "http",
    "host": "127.0.0.1",
    "port": 8899
}

That shape is quoted in internal/toolbox/settings.go as "a value Toolbox itself wrote after entering a proxy in its UI". Two details from the same file matter if you write it by hand:

  • The type is lowercase. The values are disabled, system, automatic, http and socks. The comment is blunt about the alternative: "Writing "HTTP" corrupts the file." The test TestSetProxyEmitsLowercaseHTTP locks it in.
  • Defaulted fields stay out. With no authentication and no PAC address, there is no auth or config_url key, and the same test asserts both are absent.

Because the schema belongs to Toolbox and grows between versions, jtaccel reads the file into a plain map rather than a fixed structure, changes only its own keys, and writes the rest back untouched, at Toolbox's four-space indentation, through a temporary file and a rename so an interrupted write cannot truncate it. TestMergePreservesUnknownKeys checks that keys like advanced, shell_scripts and plugins survive. A text editor and some care do the same job.

The proxy entry alone is enough for a proxy that only tunnels. For one that decrypts, the trust question comes next.

Three places to put the proxy's certificate

The operating system's root store

This is the route JetBrains documents. Its page on adding a self-signed certificate says: "The Toolbox App trusts the certificates that you store in the OS system storage", and gives the steps per platform: certutil -addstore root on Windows, security add-trusted-cert into the System keychain on macOS, and the distribution's anchors folder plus update-ca-certificates or update-ca-trust on Linux.

It works, and it is the right answer for a company's own inspection proxy that every application must trust anyway. For a proxy meant only for Toolbox it is far too wide: the macOS and Linux commands need sudo, and every browser and tool on the machine now trusts certificates minted by that authority.

The bundled cacerts

Toolbox ships its own Java runtime, and that runtime has the usual lib/security/cacerts. On this Mac it sits at:

/Applications/JetBrains Toolbox.app/Contents/jre/Contents/Home/lib/security/cacerts

Adding the proxy's certificate there works until Toolbox updates itself. The jtaccel README calls this a trap: "Toolbox replaces that file on every self-update, silently reverting the patch and leaving you wondering why downloads got slow again." The CA package's comment gives the reason: the self-updates "replace the bundled JRE".

On macOS there is a second problem. The app is code-signed, and jre/Contents/Home/lib/security/cacerts is listed in its resource seal, Contents/_CodeSignature/CodeResources. An edit to that file is an edit to a sealed resource, which is exactly what signature verification exists to notice.

network.keystore

The third route is a setting under network, beside the two timeouts JetBrains does document (network.connect_timeout and network.download_timeout, in the same FAQ):

"network": {
    "keystore": {
        "location": "/Users/you/Library/Application Support/jtaccel/truststore.p12",
        "password": "…"
    }
}

location is a PKCS#12 file and password opens it. The behaviour that makes this route work is that Toolbox adds these certificates to its defaults rather than replacing them. jtaccel's SetKeystore names the Toolbox method responsible, CertificateManagerImpl.addCertificatesFromKeystore, and concludes that "a single-entry store is enough and the platform roots keep working". Nothing in the Toolbox install is modified, so a self-update has nothing to revert.

Writing it must not disturb the siblings. TestSetKeystorePreservesNetworkSiblings starts from a file with both timeouts set and checks they survive.

The password sits in .settings.json in plain text, because Toolbox has to read it. jtaccel generates a fresh one per install (24 random bytes, base64url-encoded), and its config package is honest about what that buys: it "guards against casual copying, not a local attacker".

Building the trust store

The store needs exactly one entry: the proxy's CA certificate, as a trusted-certificate entry. With a JDK's keytool and the CA in PEM form:

keytool -importcert -noprompt -alias local-proxy-ca \
  -file ca.crt -keystore truststore.p12 -storetype PKCS12 \
  -storepass 'choose-a-password'

Toolbox's own runtime does not include keytool (its bin folder holds java, jcmd and jstack), so use any installed JDK. Put the file somewhere only your user can read, then point location at its absolute path and password at the password.

jtaccel builds the same kind of file without a JDK. It generates an ECDSA P-256 authority valid for ten years with a path length of zero, so it can sign server certificates but not another authority, writes the private key with user-only permissions, and encodes a trust store holding that one certificate. As a check for this post, a store written by jtaccel's code at commit 2ae9cca and one made with the command above both list under Temurin 21's keytool as a single trustedCertEntry. Toolbox 3.8.1 itself reports its runtime as JetBrains Runtime 25.0.3.

From the studio: jtaccel does this whole step with one jtaccel install: it creates the authority, writes the one-entry trust store to its own per-user directory, backs up .settings.json, and sets both keys while Toolbox is stopped. It is MIT-licensed, so every line that touches the file can be read first.

jtaccel's directory is your platform's user configuration folder plus jtaccel: %AppData%\jtaccel on Windows, ~/Library/Application Support/jtaccel on macOS, and ~/.config/jtaccel on Linux (or under $XDG_CONFIG_HOME), unless JTACCEL_HOME says otherwise. It never touches the operating system's root store, so the authority is trusted by Toolbox and nothing else. JetBrains' sign-in hosts (account.jetbrains.com, oauth.account.jetbrains.com, auth.jetbrains.com) are tunnelled without decryption regardless.

When a proxy is already configured

Pointing Toolbox at a local proxy replaces whatever proxy held before, and on a company laptop that may be the only route out. Overwriting it silently would cut Toolbox off the network, so jtaccel checks first. IsForeignProxy treats a missing block, an empty type and disabled as free to take. Any other type, system and automatic included, counts as someone else's proxy unless it already points at jtaccel's own address and port. In that case jtaccel install stops with:

error: Toolbox already uses proxy 10.0.0.1:8080 (type "http").
       Re-run with --force to replace it, or clear it in Toolbox first

--force replaces it. Use it only when the old entry is stale, because jtaccel cannot yet forward through an upstream proxy: the README's corporate-proxy answer says chaining "is not supported yet". On a network that requires the company proxy, forcing it leaves Toolbox with no way out. TestIsForeignProxy covers both sides: a proxy at 10.0.0.1:8080 is foreign, a disabled one is not.

Undoing it

By hand: quit Toolbox, delete the proxy block and the keystore entry under network (and network itself if nothing else is left in it), then start Toolbox again. Delete the .p12 file if you made one.

With jtaccel, jtaccel uninstall removes its autostart entry, stops the proxy, and puts the settings back in two passes. First it restores the backup it took before the first write, saved beside the original as .settings.json.jtaccel-backup. That backup is taken once and never overwritten by a later install, so it is always the true original. Then it removes exactly its own two keys from whatever is left, in case anything was written after the backup. TestUnmanageRemovesExactlyOurKeys checks that connect_timeout and an unrelated advanced key survive that second pass.

One consequence of restoring a snapshot: any setting you changed in Toolbox while jtaccel was installed goes back to its pre-install value as well. The certificate authority and trust store stay in jtaccel's directory until you run:

jtaccel uninstall --purge

What this rests on

JetBrains has not published network.keystore, so treat it as an observed behaviour of current Toolbox, not a promise. The evidence for it is jtaccel's:

  • The settings tests above, plus TestRoundTripStable, which installs three times over the same file and expects an identical proxy block.
  • TestTrustStoreRoundTrip in internal/ca/ca_test.go, which decodes the written store and expects exactly the one CA, and a test that completes a real TLS handshake with a certificate the authority minted.
  • CI running go test ./... on Ubuntu, macOS and Windows with Go 1.24 and 1.26. The suite also passed locally at 2ae9cca while this was written.
  • End to end, the README's log of a real install on Windows 11, where Toolbox installed a 275.2 MiB tool through the proxy. That cannot happen unless Toolbox trusted the proxy's certificate through the keystore.

If a future Toolbox drops or renames the setting, the visible symptom is a TLS failure on downloads. jtaccel status reports whether settings.proxy and settings.keystore still point where install left them.

If your Toolbox downloads are slow rather than misconfigured, why JetBrains Toolbox downloads are slow explains the single-connection problem the proxy exists to fix. If you are building your own proxy, the two JSON blocks above and a one-entry PKCS#12 file are all Toolbox needs; start with a copy of .settings.json and keep it until the first download succeeds.

All writingNextKotlin Multiplatform vs Flutter vs React Native for native app teams