op-fast is a proxy for the 1Password CLI, to make secret access much faster, like instantly ⚡
Benchmark 1: op read "op://Employee/Test Note/test"
Time (mean ± σ): 2.031 s ± 0.032 s [User: 0.072 s, System: 0.052 s]
Range (min … max): 1.980 s … 2.062 s 5 runs
Benchmark 2: op-fast read "op://Employee/Test Note/test"
Time (mean ± σ): 22.6 ms ± 1.7 ms [User: 4.9 ms, System: 4.1 ms]
Range (min … max): 21.2 ms … 25.2 ms 5 runs
Summary
op-fast read "op://Employee/Test Note/test" ran
90.00 ± 6.91 times faster than op read "op://Employee/Test Note/test"
It leverages OS keyrings to cache secrets that have already been fetched. To make it fast re-access without requiring re-authentication or network roundtrips.
- Offline access: Secrets cached in OS keyring (macOS Keychain, Linux keyutils)
- Configurable TTL: Set default expiration or per-secret patterns
- Full CLI compatibility: Drop-in replacement for
opcommand
Check out the releases page for pre-built binaries.
You can install it using Homebrew:
brew install cometkim/tap/op-fastOr from source:
cargo install op-fastBasic usage is same with the original 1Password CLI.
Read a secret reference:
# Read a password
op-fast read op://app-prod/db/password
# With variable substitution
VAULT=prod op-fast read 'op://$VAULT/db/password'
# Save to file (default mode: 600)
op-fast read -o ./key.pem op://app-prod/ssh/private-key
# Custom file mode
op-fast read -o ./key.pem --file-mode 644 op://app-prod/ssh/private-keyInject secrets into a config template:
# From stdin
echo 'password: {{ op://app-prod/db/password }}' | op-fast inject
# From file to file
op-fast inject -i config.yml.tpl -o config.yml
# With environment variables
echo 'db: op://$ENV/db/password' | ENV=prod op-fast inject
# Custom output file mode
op-fast inject -i config.yml.tpl -o config.yml --file-mode 600Supports two secret reference syntaxes:
{{ op://vault/item/field }}(enclosed)op://vault/item/field(unenclosed)
Pass secrets as environment variables to a process:
# With environment variable
DB_PASSWORD='op://app-prod/db/password' op-fast run -- printenv DB_PASSWORD
# Output: <concealed by 1Password>
# With env file
echo 'DB_PASSWORD=op://app-dev/db/password' > .env
op-fast run --env-file .env -- printenv DB_PASSWORD
# Switch environments with variables
cat .env
# DB_PASSWORD=op://$APP_ENV/db/password
APP_ENV=prod op-fast run --env-file .env -- printenv DB_PASSWORD
# Show secrets without masking
DB_PASSWORD='op://app-prod/db/password' op-fast run --no-masking -- printenv DB_PASSWORDManage the op-fast store (OS keyring + cache metadata):
# List all cached secrets
op-fast store list
# Clear a specific secret
op-fast store clear 'op://vault/item/field'
# Clear all cached secrets
op-fast store clearAny unrecognized command is passed through to the real op binary:
op-fast item list # => op item list
op-fast vault list # => op vault list
op-fast whoami # => op whoamiYou can even add an alias to your shell profile:
alias op=op-fastConfiguration file: ~/.config/op-fast/config.toml
# Default TTL for cached secrets (default: 1day)
default_ttl = "1day"
# Per-secret TTL patterns (glob syntax)
[ttl]
"op://prod/*" = "1hour"
"op://dev/*" = "7days"
"op://*/ssh/*" = "30days"| Variable | Description |
|---|---|
OP_FAST_CONFIG |
Custom config file path |
OP_FAST_STORE_DIR |
Custom cache directory |
OP_FAST_DEFAULT_TTL |
Override default TTL (e.g., 12h, 1day) |
Human-readable duration format:
30s- 30 seconds5m- 5 minutes1h- 1 hour1day- 1 day1w- 1 week
- Cache layer: LMDB stores cache metadata (TTL, timestamps), OS keyring stores secret values
- Batch fetching: Multiple uncached secrets fetched in a single
op injectcall - Automatic GC: Expired entries cleaned up with 10% probability on each invocation
Secrets stored in OS-native keyring (encrypted at rest)
MIT