A FUSE filesystem that exposes secrets from 1Password as virtual files.
Features:
- Command allowlists - restrict which processes can read each secret
- Read limits - secrets can self-destruct after N reads
- Write-back support - update secrets directly through the filesystem
Note
This is a prototype and it is currently limited in the security it provides. While it is still better than a simple filesystem based secret, it is possible to bypass the allowlisting mechanism with a well-timed TOCTOU "swap" attack. Currently looking at improving the security model using fanotify & eBPF for Linux, and ESF for Darwin.
- Open and unlock the 1Password app
- Select your account or collection at the top of the sidebar
- Navigate to Settings > Developer
- Under "Integrate with the 1Password SDKs", select Integrate with other apps
- (Optional) For biometric unlock, go to Settings > Security and enable Unlock using Touch ID (macOS) or Windows Hello (Windows)
See 1Password SDK documentation for more details.
go install github.com/evict/secrets-fuse@latestCreate a configuration file at ~/.config/secret-fuse.conf or config.yaml:
op_account: "my.1password.com" # default 1Password account (optional)
secrets:
- reference: "op://VAULT-UUID/ITEM-UUID/FIELD"
filename: "secrets.json"
max_reads: 1 # 0 = unlimited
writable: true # optional: allow writing back to password manager
allowed_cmds: # optional: restrict which commands can read this secret
- "/usr/bin/myapp *"
- "/usr/bin/pyton /opt/server.py"
symlink_to: "~/.config/app/secrets.json" # optional: create symlink to secret
# op_account: "other.1password.com" # optional: override account for this secretSet writable: true to allow writing to the secret file. Changes are written back to the password manager. A backup of the previous value is created automatically (e.g., field_previous for fields, .bak for document files).
The symlink_to field creates a symlink pointing to the mounted secret file. Supports ~ expansion. The symlink is created on mount and removed on unmount. Only existing symlinks will be replaced; regular files are not overwritten.
The op_account field specifies which 1Password account to use for desktop app integration. It can be set at the top level as a default, or per-secret to override.
Priority: OP_ACCOUNT environment variable > config file op_account
The allowed_cmds field accepts glob patterns matched against the full command line or executable path:
/usr/bin/myapp- exact matchpython *- any python command*/node *- node from any path- Empty list or omitted = allow all
- List your accounts to get the account URL:
op account listUse the value from the URL column (e.g., my.1password.com).
- List your vaults to get the vault UUID:
op vault list- List items in a vault to get the item UUID:
op item list --vault VAULT-UUID- Get item details to see available fields:
op item get ITEM-UUIDCommon fields: password, username, credential, notesPlain
# Get account URL
$ op account list
URL EMAIL
my.1password.com user@example.com
# Get vault UUID
$ op vault list
ID NAME
abc123... Personal
# Get item UUID
$ op item list --vault abc123
ID TITLE
def456... API Key
# Check available fields
$ op item get def456
...
password: ********
...
# Configure
secrets:
- reference: "op://abc123/def456/password"
filename: "api-key.txt"# Mount with default path (/tmp/secrets-mount)
secrets-fuse
# Mount with custom path
secrets-fuse -mount /run/user/$(id -u)/secrets
# Mount with explicit config
secrets-fuse -mount /tmp/secrets -config /path/to/config.yaml
# Enable debug logging
secrets-fuse -debug-mount: Mount point for the secrets filesystem (default:/tmp/secrets-mount)-config: Path to configuration file (default:~/.config/secret-fuse.conforconfig.yaml)-max-reads: Default maximum reads per secret, 0 = unlimited (default: 0)-debug: Enable FUSE debug logging
Press Ctrl+C to unmount. If the filesystem is busy, close any files or terminals using the mount and try again.