[discuss] Windows `gopass edit` proposal
Motivation
As on Linux and Mac, the desired behavior for gopass edit on Windows is that the secret never touches disk in plaintext.
gopass edit documents that on platforms other than Linux and Mac, it uses the system's default "TMP" during editing. The user's text editor uses the secret stored in a temporary file while editing it.
On Windows, this logic causes a potential security problem.
The problem
Windows' response to os.MkdirTemp() is a directory on permanent disk storage, at the path %LocalAppData%\temp.
The consequence is that the secret is written to permanent disk storage in plaintext, potentially exposed to (forensic?) recovery, even if this is limited to the duration of the edit.
Proposal for discussion
The proposal is to use WinFSP, a "FUSE-like" user-space filesystem program for Windows.
This is achievable in pure Golang through the go-winfsp API provided by WinFsp, a native Golang library, with no extra compile-time dependency.
Inspiration
Rclone uses WinFsp to implement the "Memory" remote.
Rclone's approach relies on cgofuse, also provided by WinFsp, but which depends on CGO at compile time.
Unlike cgofuse, the go-winfsp API allows avoiding the compile-time dependency.
WinFsp is a runtime dependency in Rclone, being a Microsoft-signed driver (https://winfsp.dev/rel/).
In Rclone, it elegantly checks for the dependency and prints a HINT to the user when needed.
C:> rclone mount :memory:my_ram_dir\ C:\ramdisk --vfs-cache-mode writes
2026/09/01 18:59:13 CRITICAL: Fatal error: failed to mount FUSE fs: mount stopped before calling Init: mount failed: cgofuse: cannot find winfsp
Hint: Install WinFsp from https://winfsp.dev/rel/WinFsp can be installed on Windows from https://winfsp.dev/rel/, or via winget:
winget install -e --id WinFsp.WinFsp
Considerations
Future
- In the future,
gopass editcould discuss making WinFsp a requirement for thegopass editaction on Windows, aligning this with enhanced security requirements. - The WinFsp
go-winfspAPI repository could have a fork under the gopass GitHub org, serving as the source for the libraries used inmount_windows.go. In this case, fallback to in-disk edit must be explicitly enabled.
Limitations
Under memory pressure, the operating system can still page these bytes out to pagefile.sys on disk.
This is the same class of residual risk that /dev/shm already has on Linux when swap is enabled; it's not a regression, but it's also not swap-proof.
Proof of concept
This is a working proof of concept: https://github.com/KodiakK-bit/gopass-fork.
The PoC implements pkg/tempfile/mount_windows.go, which uses the go-winfsp API to make winfsp calls and mount a directory in RAM.
Basic architecture
The PoC is an "opt-in" proposal for the feature, entirely optional.
Mounting gopass edit's temp storage in RAM on Windows must be explicitly enabled.
If not enabled, pkg/tempfile/mount_windows.go applies exactly the same behavior as pkg/tempfile/mount_others.go.
The implementation strives to strictly follow gopass's design, ensuring that CGO is not introduced.
Files
pkg/tempfile/mount_windows.go: Core implementation of the "opt-in" feature, extensively and thoroughly commented.docs/config.md: Documents how to enable the feature on Windows.pkg/tempfile/file.go: Implements only the mountHandle for Windows.pkg/tempfile/mount_others.go: Removed from the Windows build (and reimplemented inmount_windows.gofor fallback, depending on configuration).
Activation
The optional feature can be enabled via an environment variable or a file (dotfile-like).
set GOPASS_WINFSP_MODE=<mode>- Create a file at
%AppData%\gopass-winfsp\modewith<mode>as its content.
Modes
off(default): Preserves currentgopassbehavior (writes to disk in%TEMP%)auto: Uses WinFsp if found on the system. Automatically falls back to%TEMP%on disk if not found. Emits warnings to the user.require: Prevents editing if WinFsp is not installed on the system, and emits a warning.
Build
The fork implementing the "opt-in" feature with mount_windows.go builds successfully:
podman run --rm \
-e GOPATH=/go -e GOOS=windows -e GOARCH=amd64 -e CGO_ENABLED=0 \
-v "$PWD:/app" \
golang:1.27 /bin/bash -c '
mkdir -p /opt && cd /opt
git clone https://github.com/KodiakK-bit/gopass-fork.git
cd gopass-fork
git checkout edit_windows_winfsp
go build
cp ./gopass.exe /app
'Source: gopasspw/gopass