Skip to content

Security and privacy

Status: partly implemented. The Electron hardening baseline exists; the rest of this page is design. See implementation status.

Security and privacy are two of Astela’s core principles: the Chromium sandbox, process isolation, validated IPC, signed updates and fixed response times for security fixes, with no telemetry and local data. This document covers the hardening of the Electron embedding, network security, the supply chain, response times, documented limits and privacy. To report a vulnerability, follow SECURITY.md.

Every item in this section is designed to be covered by an automated test.

  • The sandbox is on for every renderer (an Electron default since Electron 20).
  • contextIsolation is on.
  • nodeIntegration is false.
  • webSecurity stays on; allowRunningInsecureContent and experimental features stay off.
  • There is no <webview>: will-attach-webview is always denied.
  • Web tabs have no preload script; the only planned exception is the content blocker’s minimal frame preload in M2 (see IPC). Feature scripts, such as the reader view, will run only on demand in an isolated world.
  • Internal pages get a capability-scoped preload that exposes only the IPC channels they need (see IPC).
  • setWindowOpenHandler lets pages open only tabs and popup windows of the browser, never free-floating windows.
  • The shell, the overlay and internal pages must never navigate away from app://; will-navigate and will-redirect guards enforce this.
  • Web tabs can neither navigate to, embed nor load app:// pages.
  • shell.openExternal is limited to allowlisted schemes and requires confirmation.

All app:// pages use a strict Content Security Policy and Trusted Types, and every file is sent with X-Content-Type-Options: nosniff and Cross-Origin-Resource-Policy: same-origin. Validation code stays CSP-safe because the schema library does not use eval or new Function.

The pages are sent without a Cross-Origin-Opener-Policy. That policy keeps a page apart from the windows that open it and that it opens, and the browser’s own pages have none: they cannot open windows, and web pages can neither open nor navigate to them. With the policy, a page cannot load in the renderer that its view started with its empty first document, so every view of the browser started a second renderer before its page could run (see performance).

Electron grants every permission by default (as of October 2026). Astela therefore installs request, check and device permission handlers on every session, including sessions created later (session-created):

  • The camera, the microphone, the location, notifications and reading the clipboard are asked for per origin in the overlay, and the answer is stored (ADR 0038). Without an answer, the request is refused.
  • Full screen, pointer lock and writing to the clipboard are granted; sharing the screen asks with a picker for every request.
  • Everything else, such as local-network, loopback-network, local-fonts, window-management, idle-detection and sensors, is refused, and the browser’s own pages get no permissions.

The permission handlers, the navigation and window guards and the app:// registration belong to the kernel, not to an optional module. They cannot be disabled and will stay in effect with every optional module turned off and in safe mode. Tests will check that a permission stays denied with the permissions module disabled and that a web tab cannot open app://settings. See modules for the kernel and module boundaries.

  • Client certificates are never selected automatically. The select-client-certificate handler will call preventDefault() and show a selection UI.
  • Certificate errors will show a dedicated interstitial page.
  • setCertificateVerifyProc never accepts certificates wholesale.

Electron fuses will be set through electron-builder’s electronFuses option and checked in the package smoke test:

Fuse Value Effect
runAsNode false The binary cannot be started as a plain Node.js runtime.
enableCookieEncryption true The cookie store is encrypted at rest with an OS-managed key.
enableNodeOptionsEnvironmentVariable false NODE_OPTIONS is ignored.
enableNodeCliInspectArguments false --inspect and related debugging flags are ignored.
enableEmbeddedAsarIntegrityValidation true The app archive is validated against its embedded hash.
onlyLoadAppFromAsar true The app code is loaded only from the archive.
grantFileProtocolExtraPrivileges false file:// pages get no extra privileges.
  • Cookie encryption is enabled from the first release, because turning it on is a one-way change.
  • End-to-end tests need the enableNodeCliInspectArguments fuse, so they will run on a test build that differs from the shipped package in that one fuse only. The shipped package will be verified by its built-in self-test (--smoke-test) and by reading back its fuses (see testing).
  • Site isolation stays on.
  • Web content runs in sandboxed tab views; the browser UI runs in separate shell and overlay views (see overview).
  • Isolated workspaces get their own partition (persist:ws-<id>); private windows use an in-memory partition (see data).
  • Data access and hashing run in a utilityProcess, not in the browser process.
  • Every IPC message will be checked for its sender, the sender’s capability, its schema and a rate limit (see IPC).

Chromium’s HTTPS upgrades are not available in Electron (as of October 2026), so Astela implements HTTPS-First itself in M1:

  • The RequestPipeline will upgrade navigations to HTTPS.
  • If the upgrade fails, an interstitial will offer “Continue over HTTP”, which creates a temporary exception for that host.
  • localhost, private IP addresses, .local hosts and hosts on a policy allowlist are exempt.
  • HTTPS-First is on by default.

A strict HTTPS-only mode follows in M2, selectable in the settings and through the HttpsOnlyMode policy.

Contrary to its documentation, Electron starts with DNS over HTTPS turned off (as of October 2026). Astela will therefore call configureHostResolver explicitly:

  • Default: automatic mode with a list of providers.
  • The DnsOverHttpsMode policy can switch to off or secure; DnsOverHttpsTemplates sets custom resolver templates (see enterprise).

Safe Browsing is not available in Electron (as of October 2026). In M2, Astela will block main-frame navigations to known malicious sites with signed lists and show an interstitial instead. The planned sources are the uBlock Origin badware list, URLhaus (CC0) and phishing-filter (CC BY-SA 4.0).

  • Astela will remove the app and Electron tokens from the user agent string through app.userAgentFallback. The User-Agent Client Hints brand stays “Chromium”.
  • Google account sign-in (accounts.google.com) can reject Electron-based browsers (as of October 2026), so the design includes a user agent override for that host behind a feature flag.
  • The override and Google account sign-in will be checked manually after every Electron major upgrade, as part of the maintainer workflow.

An early M1 spike produced an inventory of web platform APIs exposed by the embedded Chromium, measured in the packaged build. Capabilities that depend on Google services are unavailable, because Electron includes neither those services nor Chromium’s component updater; the validation results list the details. If a later Electron version exposes an unexpected working capability, the repository owner will decide whether and how to disable it.

  • Releases: immutable releases, artifact attestations (actions/attest) and a CycloneDX SBOM for every release.
  • Signatures: SHA256SUMS with an Ed25519 signature; GPG for the Linux repositories; operating system code signing once certificates are available (see updates).
  • Actions: pinned by commit SHA, enforced with sha_pinning_required.
  • Scanners: CodeQL, osv-scanner, dependency-review, zizmor (blocking), OpenSSF Scorecard and secret scanning with push protection.
  • Dependencies: pnpm allowBuilds limits install scripts to an allowlist; a license check enforces an allowlist of dependency licenses; every new dependency needs a stated reason.
  • Tests: dedicated security tests will check the webPreferences of every created WebContents, the fuse state of the packaged binary, the CSP of app:// pages and the navigation locks of the shell.
  • Signing keys (Ed25519, GPG and code signing) and the publishing token are stored only as secrets of the release environment, which only main may use.
  • Branch and pull request workflows never see these secrets, not even through modified workflow code. Pull requests from owner branches are opened in two stages through workflow_run, and the token used for that lives in the automation environment, also restricted to main.
  • No private key is ever stored in the repository. The repository owner keeps an encrypted offline backup.

The maintainer workflow describes the environments and the release process.

Event Target
Security fix in Electron or Chromium Patch release within 72 hours; target 24 hours for critical issues
New Electron major version Upgrade within two to four weeks
  • Astela follows the latest stable Electron major. Electron publishes a new major every 8 weeks, supports the latest three majors and ships patch releases two to three times a week per supported line (as of October 2026).
  • The daily freshness.yml workflow turns red when a newer Electron patch release exists than the one the app uses (tools/ci/electron-freshness.ts), and reports a newer major version. It raises an alarm without opening automated pull requests; maintainers then update. Known vulnerabilities in dependencies are reported by Dependabot alerts.
  • A weekly CI job will build against the next Electron beta to surface breaking changes early.
  • pnpm’s minimumReleaseAge setting (default 1 day, as of October 2026) would delay urgent Electron patches; an Electron security patch is exempted by its exact version, as the maintainer workflow describes.
  • Fully automatic Windows signing within the 24-hour target requires Azure Artifact Signing or an OV certificate (see updates).
  • The root certificate store, CRLSet and Certificate Transparency data are updated only through Electron updates. This is why the response times above matter.
  • There is no ASAR integrity validation on Linux (as of October 2026); package signatures protect the installation there.
  • WebAuthn has no PIN entry UI and no hybrid (QR code) passkeys. Device-bound authenticators, such as USB security keys, Windows Hello and Touch ID, remain usable.
  • Safe Browsing is unavailable; list-based protection follows in M2.
  • AppImage sandbox restrictions on Ubuntu 24.04 and later, and the limits of rollback, are described in updates.
  • Astela collects no telemetry and uploads no crash reports.
  • crashReporter is used locally only. Crash dumps will be visible on app://diagnostics, and users can share them manually.
  • An automated test will capture network traffic during 60 seconds of idle time after start and expect no connections other than the allowlisted ones (the update feed check after 30–60 seconds).

Every outbound connection will be documented on a “Network connections” documentation page and on app://diagnostics, and each one can be redirected or disabled by policy:

Connection Notes
Update feed (GitHub Pages) and downloads (GitHub Releases) Controlled with UpdatePolicy and UpdateURL (see updates).
Filter list feed From M2, for the content blocker.
Spellchecker dictionaries In M1, the spellchecker is off on Windows and Linux; macOS uses the system spellchecker. From M2, dictionaries are self-hosted on GitHub Pages through setSpellCheckerDictionaryDownloadURL instead of a Google CDN.
Search suggestions Opt-in.

GitHub and GitHub Pages see the IP address during update checks. The privacy statement on the website will say exactly that, and that Astela itself collects nothing.

  • Astela ships no GOOGLE_API_KEY.
  • Windows and macOS will use the operating system’s location provider.
  • On Linux, the XDG desktop portal will be evaluated; if it is not usable, the permission will be denied with an explanation.
  • Cookies will be encrypted at rest through the enableCookieEncryption fuse.
  • The WebRTC IP handling policy is default_public_interface_only.
  • Referrers will be trimmed.
  • Secrets are kept in the operating system’s key store (see data).
Feature Milestone
Strict HTTPS-only mode M2
Blocking of third-party cookies through a Chromium switch M2
Global Privacy Control (GPC) header M2
Removal of tracking parameters M2
Ad and tracker blocking with signed filter lists M2
Malware and phishing lists with an interstitial M2
Encrypted password vault M3

The roadmap lists the milestones.

The security baseline is implemented in app/src/platform/electron/ and app/electron-builder.config.mjs and checked by end-to-end and package smoke tests:

  • Every view runs sandboxed with context isolation and without Node integration; tabs have no preload.
  • Web sessions ask before a site uses the camera, the microphone, the location, notifications or the clipboard, and share a screen or a window only after the user picked it; the sessions of the browser’s own pages refuse every permission, and every session denies device access.
  • <webview> is never attached; pages cannot open free windows: what a script opens becomes a tab or a popup window of the browser and keeps its opener (ADR 0040). A script can open only an http or https URL, or about:blank, which it fills itself, and a tab opened from the context menu only an http or https URL; the browser’s own pages open nothing.
  • Private windows load web pages in a session in memory of their own, with the same guards, pipeline and content blocker; its data is deleted after the last private window closed (ADR 0041).
  • The shell and internal pages cannot leave their app:// origin; web content can neither navigate to app:// nor load it, because web sessions answer such requests with 403.
  • All app:// pages carry the strict Content Security Policy with Trusted Types.
  • Client certificates are never selected automatically.
  • The user agent carries neither the app nor the Electron token.
  • Spellchecking is off on Windows and Linux.
  • Every package sets the fuses listed above; the package smoke test reads them back from the installed binary.
  • The content blocker cancels requests of web pages that the default lists of uBlock Origin name, including the Badware risks list and the Online Malicious URL Blocklist (ADR 0027). Its data is built in CI from the lists and from scriptlet sources whose hashes are recorded in the repository, and ships with the package; the browser downloads no lists. A frame preload hides elements, applies procedural rules and runs scriptlets in every web frame (ADR 0028, ADR 0033), and popups that the lists name do not open. The shield in the toolbar counts the blocked requests of the page and turns the blocker off for a site’s registrable domain (contentBlocker.allowedSites); the decision for a request depends on the site of the page it belongs to.

Not implemented yet: HTTPS-First, DNS over HTTPS, the warning page for malware and phishing sites, the signed filter feed, and the web platform API inventory in CI.