# Isolate file and interface privileges in an Electron tool

Canonical page: https://yishto.com/en/learn/application-platforms/electron-transcript-workbench/

Author: [Yishto](https://yishto.com/en/about/)

Separate Electron main, preload, and renderer responsibilities in an interview workbench, using approved file IDs, narrow IPC messages, and explicit transcription job states.

Published: 2026-11-10
Updated: 2026-11-10

An interview workbench lets users select audio, follow transcription jobs, and correct segments. File access and execution have greater privileges than the interface. Exposing Node.js directly to a page gives untrusted text or scripts an opportunity to influence local operations.

Use synthetic audio or explicitly selected teaching files. Begin with a fake transcription adapter. Real local or cloud engines require separate format, resource, and data-flow checks. No claim is made that a recording has been transcribed accurately here.

## Connect three execution boundaries

Electron's main process runs in a Node.js environment and manages windows and local capabilities. Renderers display pages, while preload supplies a limited bridge. A window's renderer should not receive arbitrary filesystem, shell, or raw IPC capabilities.

Use context isolation, renderer sandboxing, and no unnecessary Node integration. These settings do not validate messages. Check sender, frame origin, action, and parameters. A generic channel-and-arguments interface can undermine privilege separation despite enabled isolation.

Expose specific capabilities for choosing audio, starting and canceling jobs, and reading status. Return serializable data rather than internal privileged objects. Logs should avoid full user paths, document contents, and secrets.

## Track approved files and jobs

A user action asks the main process to open the operating system picker. Main records the selected path and returns a temporary file ID, display name, and size. Later renderer requests refer to that ID, preventing arbitrary page-supplied paths from broadening access.

An approval record associates the ID with the permitted window and lifetime. Invalidate it when appropriate. Recheck file existence, type, and size before starting because conditions can change after selection. Return clear failure instead of leaving an operation queued forever.

Jobs have IDs, file IDs, phase, progress, error code, and cancellation state. Queued, running, completed, failed, and canceled outcomes differ. Output segments retain timestamps for review. Names, numbers, and terminology still need checking; model output is not a guarantee of accuracy.

## Create the minimal Electron project

Follow the official starter and pin dependencies. Create main, preload, and renderer files. After application readiness, main creates a window loading the local interface with explicit secure webPreferences and a restricted content security policy. These are reader execution steps, not evidence of a tested application.

First implement selection and verify that cancellation creates no job. Connect a delayed fake engine through restricted `ipcMain.handle` handlers and preload methods. Show filename, start, progress, and cancel controls. Main owns every authorization check.

Then add an engine adapter without blocking the main process. Define input formats, segment outputs, and termination conditions. Do not construct executable commands from model text. If an external process is required, generate parameters from controlled configuration and approved file records, with a separately reviewed execution environment.

## Check a narrow contract offline

The Python model permits one action with a preapproved ID and rejects additional fields. It includes no Electron runtime, picker, IPC sender, or filesystem.

```python
approved = {"F-1"}
def permit(message):
    return (isinstance(message, dict) and set(message) == {"action", "file_id"}
            and message["action"] == "transcribe" and message["file_id"] in approved)
assert permit({"action": "transcribe", "file_id": "F-1"})
assert not permit({"action": "delete", "file_id": "F-1"})
assert not permit({"action": "transcribe", "file_id": "/private/file"})
print(permit({"action": "transcribe", "file_id": "F-1"}))
```

The output is `True`. Deletion and arbitrary paths are rejected. The real handler also needs type and length checks, window ownership, frame-origin validation, and unknown-ID handling. A valid shape does not establish authorization, so this function is not a complete security implementation.

Define a schema per action. Canceling requires job ownership; status queries return only visible jobs. Invalid requests produce controlled errors without disclosing internal paths.

## Cancel and recover transcription jobs

Record cancellation intent, notify the executor, and confirm termination. The interface should claim cancellation only when execution cannot commit a result or resources have been released. A late success must not restore a canceled job to completed state.

Write output to tracked temporary storage and commit a segment index after validation. Preserve existing confirmed results on failure. Persist only the information necessary for intended recovery. After restart, determine whether a job can run again or needs the user to reapprove its file.

Cleanup covers only tracked application-created files. Never infer a recursive deletion target from renderer-provided directories. Set size, concurrency, and queue limits from resource testing rather than unmeasured speed promises.

## Explain local and cloud data paths

A local engine needs installed resources; a cloud engine uploads data and needs credentials. Explain the selected path before sending and stop further upload when canceled. Keep service secrets in an appropriately restricted environment, outside the renderer.

Transcription quality varies with language, noise, and audio conditions. The Whisper paper provides model background, not proof of arbitrary interview accuracy. Support replay, editing, and review markers. Exports should preserve source and correction state so generated text is not confused with a final approved record.

Separate corrected segments from engine output. A new transcription creates a candidate instead of replacing reviewed text. Export explicitly selects a candidate or corrected version. Validate time ranges against audio duration and retain gaps or overlaps for review.

Progress reflects executor-reported phases; unknown progress needs an indeterminate indicator. Validate output structure, timestamp ordering, text fields, and size. Structural validity does not establish accuracy or completeness. Empty audio and unrecognized speech should produce understandable states rather than false success.

## Exercise: test privileges and installation

With the fake engine, test unauthorized IDs, extra fields, unknown actions, window closure, disappeared files, and results arriving after cancellation. Every path must reach a defined error or terminal state while the interface remains responsive.

Package and install on intended desktop systems, checking file selection, assets, and permissions. Updates need trusted sources and signing policy, and security dependencies need maintenance. Record tested artifacts and systems. Passing the IPC model establishes only its contract, not complete application security or transcription quality.

## Sources & further reading

- [Electron process model](https://www.electronjs.org/docs/latest/tutorial/process-model)
- [Electron security guidance](https://www.electronjs.org/docs/latest/tutorial/security)
- [Robust Speech Recognition via Large-Scale Weak Supervision](https://arxiv.org/abs/2212.04356)

Sources checked on 2026-11-10. Examples are teaching data, not production measurements.

## Related guides

- [After a program starts: processes, memory, and files](https://yishto.com/en/learn/computing/process-memory-files/)
- [Handle images, speech, and video inside an application](https://yishto.com/en/learn/ai-foundations/multimodal-image-and-speech/)
