op-rotate is a local terminal application for working through credential
rotation across one or more 1Password accounts. It discovers items in the
vaults you choose, presents them one at a time, opens their websites, and
records the remediation work you complete.
It does not change credentials itself, modify 1Password items, or store secret values. You remain in control of every rotation.
- Works across multiple 1Password accounts and vaults.
- Includes every item category, not only logins.
- Tracks credentials, TOTP, recovery codes, and sessions independently.
- Supports priorities, flags, search, filtering, and category-wide skipping.
- Saves every action immediately to a local SQLite database, so work can be stopped and resumed safely.
- Opens item URLs in your default browser without automating the website.
- Provides progress reports, CSV export, database backup, and complete local state removal.
- Reads secret-bearing 1Password responses into zeroizing buffers and never persists complete item payloads.
- Linux or macOS
- A Rust nightly toolchain (the project pins nightly in
rust-toolchain.toml) - 1Password CLI installed and configured
- An authenticated 1Password session for each account you want to use
Sign in through the 1Password desktop app integration, or run:
op signin --account <account>Build and install from this checkout:
cargo install --path . --lockedAlternatively, run it directly during development:
cargo run --releaseStart the TUI:
op-rotateOn first launch, select the vaults to include with Space, then press
Enter. The selection is saved for later sessions. Use
op-rotate --rescope to show the scope selector again.
To restrict discovery to particular 1Password categories:
op-rotate --categories "Login,API Credential,SSH Key"Press ? at any point in the TUI for the complete contextual help. The main working keys are:
| Key | Action |
|---|---|
| j/k or arrows | Move between items |
| Tab | Switch between list and detail views |
| o | Open the primary URL |
| u | Choose a URL to open |
| p/t/r/x | Mark credential, TOTP, recovery codes, or sessions complete |
| P/T/R/X | Choose the full state for a dimension, including undo and N/A |
| a | Mark all applicable dimensions complete |
| s/i | Toggle skipped or investigate |
| S | Skip all pending items in the current category |
| 1–4 | Set critical, high, normal, or low priority |
| F | Edit flags |
| / | Search |
| f | Filter and sort |
| g | Show progress |
| q | Quit |
An item is complete when every applicable dimension is resolved. Unknown dimensions deliberately block completion until you select a state or skip the item.
Inspect accounts and vaults without changing local progress:
op-rotate scan
op-rotate scan --account my-account --vault PersonalShow locally recorded progress without calling op:
op-rotate statusExport progress using IDs only by default:
op-rotate export
op-rotate export --output report.csv--include-titles fetches titles live from 1Password and writes them into the
CSV. This intentionally places account metadata outside 1Password, so use it
only when needed.
Back up the progress database:
op-rotate backup
op-rotate backup --output op-rotate-state.dbRemove the database, SQLite sidecars, log, and empty application data directories:
op-rotate purgeThe command asks for confirmation and warns when outstanding progress would be
lost. Use --yes only for intentional non-interactive removal. Exports and
backups written elsewhere are not removed.
Run op-rotate --help or op-rotate <command> --help for every option.
Items can receive a default priority based on URL domains. Create
~/.config/op-rotate/config.toml on Linux (or the platform-equivalent config
directory) with rules such as:
[[priority_rule]]
priority = "critical"
domains = ["github.com", "tailscale.com"]
[[priority_rule]]
priority = "high"
domains = ["example.com"]Rules are evaluated from top to bottom, and the first matching rule wins. A domain also matches its subdomains. Priorities selected manually in the TUI take precedence.
1Password remains the source of truth for item information. The local database contains item, vault, and account IDs; remediation states; priorities; flags; revision numbers; and timestamps. It does not contain titles, URLs, passwords, keys, TOTP seeds, recovery codes, notes, or complete 1Password payloads.
Default Linux paths are:
- Database:
~/.local/share/op-rotate/state.db - Log:
~/.local/state/op-rotate/op-rotate.log - Configuration:
~/.config/op-rotate/config.toml
The equivalent platform application directories are used on macOS. Files and directories containing local state are created with restrictive permissions where the platform supports them. Logs contain command metadata and errors, never command output or secret values.
The 1Password integration is read-only. Commands are executed directly without a shell, every item operation specifies its account and vault, and raw output is discarded immediately after the minimal display metadata or credential presence has been parsed.
cargo fmt --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-featuresFor development without a configured 1Password account, enable the built-in fake dataset:
cargo run --features fake -- --fakeThe optional live adapter integration test runs only when explicitly enabled:
OP_ROTATE_INTEGRATION_TESTS=1 cargo test integration_account_list_and_whoamiLicensed under the MIT License.