Adding Electron Fuses
Information below has been partially copied from integration with @electron/fuses and electron tutorial for easier reading/access.
What are fuses?
For a subset of Electron functionality it makes sense to disable certain features for an entire application. For example, 99% of apps don't make use of ELECTRON_RUN_AS_NODE, these applications want to be able to ship a binary that is incapable of using that feature. We also don't want Electron consumers building Electron from source as that is both a massive technical challenge and a significant cost in time and money.
Fuses are the solution to this problem, at a high level they are "magic bits" in the Electron binary that can be flipped when packaging your Electron app to enable / disable certain features / restrictions. Because they are flipped at package time before you code sign your app the OS becomes responsible for ensuring those bits aren't flipped back via OS level code signing validation (Gatekeeper / App Locker).
How do I flip the fuses?
Under-the-hood, electron-builder leverages the official @electron/fuses module to make flipping these fuses easy. Previously, electron fuses could only be flipped within the afterPack hook (this is still a supported method). Now, you can instead set electron-builder configuration property electronFuses: FuseOptionsV1 to activate electron-builder's integration.
Example
The true/false below are just an example, customize your configuration to your own requirements
electronFuses: {
runAsNode: false,
enableCookieEncryption: true,
enableNodeOptionsEnvironmentVariable: false,
enableNodeCliInspectArguments: false,
enableEmbeddedAsarIntegrityValidation: true,
onlyLoadAppFromAsar: true,
loadBrowserProcessSpecificV8Snapshot: false,
grantFileProtocolExtraPrivileges: false
}
It is also still possible to continue to keep your current logic in the afterPack hook, so a convenience method has been exposed in the PlatformPackager for easy customization of the flags on your own. It directly accepts an AfterPackContext and a FuseConfig object of type.
This convenience method was added so that custom FuseConfigs could be provided, allowing usage of strictlyRequireAllFuses to monitor your fuses and stay up-to-date with fuses as they're released, and/or force override the version of @electron/fuses in electron-builder if there's an update you'd like to leverage.
const { FuseConfig, FuseVersion, FuseV1Options } = require("@electron/fuses")
exports.default = function (context: AfterPackContext) {
const fuses: FuseConfig = {
version: FuseVersion.V1,
strictlyRequireAllFuses: true,
[FuseV1Options.RunAsNode]: false,
... // all other flags must be specified since `strictlyRequireAllFuses = true`
}
await context.packager.addElectronFuses(context, fuses)
}
Validating Fuses
You can validate the fuses have been flipped or check the fuse status of an arbitrary Electron app using the fuses CLI.
npx @electron/fuses read --app /Applications/Foo.app
Typedoc
Interface: FuseOptionsV1
Feature flags ("fuses") baked into the Electron binary at build time.
All options map 1:1 to the flags documented by
@electron/fuses and the upstream
Electron fuses guide.
electron-builder flips fuses after packaging and before signing so that the final code signature covers the modified binary. On Apple Silicon, the ad-hoc signature is re-applied automatically after flipping fuses.
Properties
enableCookieEncryption?
optionalenableCookieEncryption?:boolean
Controls whether the Chromium cookie store is encrypted using OS-level cryptography keys.
When enabled, cookies are stored encrypted on disk (the same mechanism Chrome uses). This is a one-way transition: existing unencrypted cookies are re-encrypted on write, but disabling the fuse afterwards will leave the cookie database unreadable.
Most production apps can safely enable this fuse.
enableEmbeddedAsarIntegrityValidation?
optionalenableEmbeddedAsarIntegrityValidation?:boolean
Enables ASAR integrity validation — Electron verifies the embedded SHA-256 hash of
app.asar before loading it.
Platform support:
- macOS: Electron ≥ 16.0.0
- Windows: Electron ≥ 30.0.0
For this fuse to be meaningful, asar.disableIntegrity must not be
true (otherwise the hash is not embedded).
See the ASAR Integrity guide.
enableNodeCliInspectArguments?
optionalenableNodeCliInspectArguments?:boolean
Controls whether the --inspect, --inspect-brk, and related Node.js debugger flags are
honoured.
When disabled, SIGUSR1 no longer opens the V8 inspector in the main process either.
Most production apps can safely disable this fuse.
enableNodeOptionsEnvironmentVariable?
optionalenableNodeOptionsEnvironmentVariable?:boolean
Controls whether the NODE_OPTIONS
and NODE_EXTRA_CA_CERTS environment variables are respected.
NODE_OPTIONS allows injecting arbitrary Node.js runtime flags (e.g. --require) and is
rarely needed in production. Most apps can safely disable this fuse.
grantFileProtocolExtraPrivileges?
optionalgrantFileProtocolExtraPrivileges?:boolean
Controls whether pages loaded from the file:// protocol receive elevated privileges
beyond what a standard web browser would grant.
These extra privileges include fetch to other file:// URLs, service workers, and
universal frame access for child frames also on file://. This behaviour pre-dates modern
Electron security best practices.
Disable this fuse if your app does not load content directly from file:// (i.e. you use
a custom protocol).
loadBrowserProcessSpecificV8Snapshot?
optionalloadBrowserProcessSpecificV8Snapshot?:boolean
When enabled, the browser (main) process uses a separate V8 snapshot file
(browser_v8_context_snapshot.bin) instead of the shared one.
This is only useful when you ship a custom V8 snapshot for the main process that differs from the renderer snapshot. Standard apps do not need this.
onlyLoadAppFromAsar?
optionalonlyLoadAppFromAsar?:boolean
When enabled, Electron searches for the app exclusively in app.asar, skipping the app
directory and default_app.asar fallbacks.
Combined with enableEmbeddedAsarIntegrityValidation, this makes it impossible to side-load
unverified code by replacing app.asar with an unarchived app/ directory.
resetAdHocDarwinSignature?
optionalresetAdHocDarwinSignature?:boolean
Re-applies the ad-hoc codesignature on macOS after fuses are flipped.
electron-builder already re-signs the app after flipping fuses, so this flag is generally not needed and exists only as a compatibility shim for edge cases.
See @electron/fuses — Apple Silicon.
runAsNode?
optionalrunAsNode?:boolean
Controls whether the ELECTRON_RUN_AS_NODE environment variable is respected.
When true (the Electron default), setting ELECTRON_RUN_AS_NODE=1 in the environment
makes Electron behave like a plain Node.js process, bypassing the app entirely. Disable
this fuse in production apps to prevent that escape path.
Note: Disabling this fuse also breaks process.fork() in the main process because
it relies on ELECTRON_RUN_AS_NODE internally. Use
Utility Processes as a
replacement.