--- name: proton-pass description: Proton Pass secret management — vaults, items, TOTP, SSH keys, and secret injection via the official pass-cli version: 1.0.0 category: productivity platforms: [linux, macos] dependencies: - pass-cli >= 2.1.0 (official Proton Pass Rust CLI) metadata: hermes: tags: [proton, pass, secrets, passwords, vault, totp, ssh] auth: independent — pass-cli manages its own encrypted local session limitations: - "pass-cli is a separate binary; not bundled with Hermes" - "Secrets retrieved into agent context — user should be aware of prompt logging" - "Interactive login requires a browser or TTY for credential input" - "PAT (personal access token) login recommended for headless/automation use" --- # Proton Pass Hermes Skill A Hermes skill that wraps the official [Proton Pass CLI](https://protonpass.github.io/pass-cli/) (`pass-cli`) for agent use. Provides full vault and item lifecycle management — list vaults, retrieve secrets, search, create, edit, delete, TOTP codes, SSH key injection, and secret-injected command execution. ## Installation ### Prerequisites The skill shells out to `pass-cli` v2.1.0+ (Rust binary). Install it: ```bash # Linux/macOS — official installer curl -fsSL https://proton.me/download/pass-cli/install.sh | bash # Or build from source (requires Rust toolchain) git clone https://github.com/ProtonPass/pass-cli.git cd pass-cli && cargo build --release cp target/release/pass-cli ~/.local/bin/ ``` ### Authentication `pass-cli` manages its own encrypted session. Authenticate once: ```bash # Interactive (prompts for password, TOTP, extra password) pass-cli login --interactive your@proton.me # Or personal access token (recommended for automation) PROTON_PASS_PERSONAL_ACCESS_TOKEN=pst_xxxx...xxxx::TOKENKEY pass-cli login # Verify auth pass-cli info ``` ### Verifying Setup ```bash pass-cli test # connection + auth check pass-cli vault list --output json # should show your vaults pass-cli item list --output json # should show items ``` ## Tools ### Auth Tools #### `proton_pass_login` Authenticate with Proton Pass. Three modes: | Mode | Description | When to Use | |------|-------------|-------------| | `interactive` | Prompts for password, TOTP, extra password | Initial setup, interactive sessions | | `pat` | Personal access token | CI/CD, headless, automation | | `web` | Browser-based OAuth | SSO, hardware key support | ```json { "name": "proton_pass_login", "description": "Authenticate with Proton Pass.", "parameters": { "properties": { "mode": { "type": "string", "enum": ["interactive", "pat", "web"] }, "username": { "type": "string", "description": "Proton account email" }, "token": { "type": "string", "description": "PAT token (pat mode only)" } } } } ``` **CLI mapping:** - Interactive: `pass-cli login --interactive [username]` - PAT: `pass-cli login --personal-access-token ` - Web: `pass-cli login` --- #### `proton_pass_logout` End the current Proton Pass session and clear cached credentials. ```json { "name": "proton_pass_logout", "description": "End the current Proton Pass session.", "parameters": {} } ``` **CLI mapping:** `pass-cli logout` --- #### `proton_pass_auth_status` Check whether you're authenticated, with account info from `pass-cli info`. ```json { "name": "proton_pass_auth_status", "description": "Check authentication status.", "parameters": {} } ``` **CLI mapping:** `pass-cli info` --- #### `proton_pass_test` Test the pass-cli connection and authentication validity. ```json { "name": "proton_pass_test", "description": "Test connection and authentication.", "parameters": {} } ``` **CLI mapping:** `pass-cli test` --- ### Vault Tools #### `proton_pass_vaults` List all accessible Proton Pass vaults with share IDs and metadata. ```json { "name": "proton_pass_vaults", "description": "List all vaults.", "parameters": {} } ``` **CLI mapping:** `pass-cli vault list --output json` **Returns:** JSON array of vault objects with `share_id`, `name`, and metadata. --- #### `proton_pass_vault_create` Create a new vault. ```json { "name": "proton_pass_vault_create", "description": "Create a new vault.", "parameters": { "properties": { "name": { "type": "string", "description": "Vault name." } }, "required": ["name"] } } ``` **CLI mapping:** `pass-cli vault create --name ` --- #### `proton_pass_vault_delete` Permanently delete a vault and all its contents. **Cannot be undone.** ```json { "name": "proton_pass_vault_delete", "description": "Delete a vault permanently.", "parameters": { "properties": { "share_id": { "type": "string", "description": "Vault share ID." }, "vault_name": { "type": "string", "description": "Vault name." } } } } ``` **CLI mapping:** `pass-cli vault delete --share-id ` or `--vault-name ` --- ### Item Tools #### `proton_pass_list` List all items in a vault (names only, no secret values). ```json { "name": "proton_pass_list", "description": "List items in a vault.", "parameters": { "properties": { "vault_name": { "type": "string", "description": "Vault name." }, "share_id": { "type": "string", "description": "Vault share ID." } } } } ``` **CLI mapping:** `pass-cli item list [vault-name] --output json` --- #### `proton_pass_get` Retrieve a specific item's full details — passwords, usernames, URLs, notes, custom fields. > **⚠️ Security:** Secrets enter the agent context. Be aware of prompt logging implications. ```json { "name": "proton_pass_get", "description": "Get full item details.", "parameters": { "properties": { "share_id": { "type": "string" }, "vault_name": { "type": "string" }, "item_id": { "type": "string" }, "item_title": { "type": "string" }, "uri": { "type": "string", "description": "pass:// URI shortcut." }, "field": { "type": "string", "description": "Specific field (password, username, etc.)." } } } } ``` **CLI mapping:** - By ID: `pass-cli item view --share-id --item-id --output json` - By title: `pass-cli item view --vault-name --item-title --output json` - By URI: `pass-cli item view pass://vault/item/field --output json` --- #### `proton_pass_search` Search items across vaults by title or name. Lists items and applies client-side filtering since pass-cli has no dedicated search subcommand. ```json { "name": "proton_pass_search", "description": "Search items by title/name.", "parameters": { "properties": { "query": { "type": "string", "description": "Search query." }, "vault_name": { "type": "string", "description": "Optional: restrict to vault." }, "share_id": { "type": "string", "description": "Optional: restrict to vault by share ID." } }, "required": ["query"] } } ``` --- #### `proton_pass_create` Create a new login or note item in a vault. ```json { "name": "proton_pass_create", "description": "Create a new item.", "parameters": { "properties": { "type": { "type": "string", "enum": ["login", "note"] }, "vault_name": { "type": "string" }, "share_id": { "type": "string" }, "title": { "type": "string" }, "username": { "type": "string" }, "password": { "type": "string" }, "generate_password": { "type": "boolean" }, "url": { "type": "string" }, "note": { "type": "string" } }, "required": ["title"] } } ``` **CLI mapping:** `pass-cli item create login --title "..." --username "..." [--generate-password=...]` --- #### `proton_pass_edit` Update fields on an existing item. ```json { "name": "proton_pass_edit", "description": "Update item fields.", "parameters": { "properties": { "share_id": { "type": "string" }, "vault_name": { "type": "string" }, "item_id": { "type": "string" }, "item_title": { "type": "string" }, "fields": { "type": "object", "description": "Key-value map of fields to update." } } } } ``` **CLI mapping:** `pass-cli item update --share-id <sid> --item-id <iid> --field password=newpass` --- #### `proton_pass_delete` Permanently delete an item. ```json { "name": "proton_pass_delete", "description": "Delete an item.", "parameters": { "properties": { "share_id": { "type": "string" }, "vault_name": { "type": "string" }, "item_id": { "type": "string" }, "item_title": { "type": "string" } } } } ``` **CLI mapping:** `pass-cli item delete --share-id <sid> --item-id <iid>` --- #### `proton_pass_totp` Get the current TOTP code for an item that has two-factor authentication configured. ```json { "name": "proton_pass_totp", "description": "Get TOTP code for an item.", "parameters": { "properties": { "share_id": { "type": "string" }, "vault_name": { "type": "string" }, "item_id": { "type": "string" }, "item_title": { "type": "string" }, "uri": { "type": "string" } } } } ``` **CLI mapping:** `pass-cli item view --share-id <sid> --item-id <iid> --field totp` --- #### `proton_pass_share_item` Share an item with another user. ```json { "name": "proton_pass_share_item", "description": "Share an item with another user.", "parameters": { "properties": { "share_id": { "type": "string" }, "vault_name": { "type": "string" }, "item_id": { "type": "string" }, "item_title": { "type": "string" }, "email": { "type": "string" }, "role": { "type": "string", "enum": ["viewer", "editor", "manager"] } }, "required": ["email"] } } ``` **CLI mapping:** `pass-cli item share --share-id <sid> --item-id <iid> email@example.com --role editor` --- ### Secret Injection Tools #### `proton_pass_inject` Run a shell command with secrets injected into environment variables. Uses `pass-cli run` which resolves `pass://` URIs in env vars before executing. Secrets are masked in stdout/stderr by default. ```json { "name": "proton_pass_inject", "description": "Run command with secret-injected env vars.", "parameters": { "properties": { "command": { "type": "string", "description": "Command to execute." }, "env_files": { "type": "array", "items": {"type": "string"}, "description": ".env files to load." }, "no_masking": { "type": "boolean", "description": "Disable secret masking." } }, "required": ["command"] } } ``` **CLI mapping:** `pass-cli run --env-file .env -- ./my-app` **Example usage:** ```bash export DB_PASSWORD='pass://Production/Database/password' pass-cli run -- ./my-app ``` --- ### SSH Agent Tools #### `proton_pass_ssh_load` Load SSH keys from Proton Pass into the system's SSH agent. Requires `SSH_AUTH_SOCK` to be set. ```json { "name": "proton_pass_ssh_load", "description": "Load SSH keys from Proton Pass.", "parameters": { "properties": { "share_id": { "type": "string", "description": "Restrict to a vault." }, "vault_name": { "type": "string", "description": "Restrict to a vault." } } } } ``` **CLI mapping:** `pass-cli ssh-agent load [--share-id <sid>]` --- #### `proton_pass_ssh_agent_start` Start Proton Pass CLI as the SSH agent (foreground). Sets `SSH_AUTH_SOCK` to the agent's Unix socket. ```json { "name": "proton_pass_ssh_agent_start", "description": "Start Proton Pass as SSH agent.", "parameters": { "properties": { "share_id": { "type": "string" }, "vault_name": { "type": "string" } } } } ``` **CLI mapping:** `pass-cli ssh-agent start` --- #### `proton_pass_ssh_daemon_start` / `_status` / `_stop` Start, check, or stop the Proton Pass SSH agent background daemon. ```json { "name": "proton_pass_ssh_daemon_start", "description": "Start SSH daemon.", "parameters": { "properties": { "share_id": { "type": "string" }, "vault_name": { "type": "string" }, "log_file": { "type": "string", "description": "Log file path." } } } } ``` **CLI mapping:** `pass-cli ssh-agent daemon start|status|stop` --- ### Utility Tools #### `proton_pass_generate_password` Generate a random password or passphrase and optionally save it to a vault. ```json { "name": "proton_pass_generate_password", "description": "Generate password or passphrase.", "parameters": { "properties": { "length": { "type": "integer", "description": "Password length (default: 20)." }, "passphrase": { "type": "boolean", "description": "Generate passphrase." }, "word_count": { "type": "integer", "description": "Passphrase word count (default: 4)." }, "save": { "type": "boolean", "description": "Save to vault." }, "vault_name": { "type": "string" }, "title": { "type": "string" } } } } ``` **CLI mapping:** `pass-cli item create login --title "..." --generate-password=20,uppercase,symbols` --- ## Implementation All tools shell out to `pass-cli` via Python `subprocess`. The implementation module lives at `scripts/tools.py` in this skill directory. ### General Pattern ```python import subprocess import json import shlex def _run_pass(args: list[str], timeout: int = 15) -> dict: """Run a pass-cli command and return structured output.""" try: result = subprocess.run( [binary] + args, capture_output=True, text=True, timeout=timeout ) if result.returncode != 0: return {"success": False, "error": result.stderr.strip()} # Auto-parse JSON output try: data = json.loads(result.stdout) return {"success": True, "data": data} except json.JSONDecodeError: return {"success": True, "output": result.stdout.strip()} except subprocess.TimeoutExpired: return {"success": False, "error": f"Command timed out after {timeout}s"} except FileNotFoundError: return {"success": False, "error": "pass-cli not found. Install via official installer."} ``` ### Output Format pass-cli supports `--output json` on most commands, making parsing straightforward. The tools auto-detect JSON output and return structured data directly. When the CLI returns non-JSON (e.g., login prompts, info output), the raw text is returned in an `output` field. ### Binary Path The pass-cli binary location can be configured via: - Environment variable: `PROTON_PASS_CLI_PATH` (e.g., `/usr/local/bin/pass-cli`) - Default: `pass-cli` (searched via `PATH`) ## Dependencies | Dependency | Required | Notes | |------------|----------|-------| | `pass-cli` (>= 2.1.0) | Yes | Official Proton Pass Rust CLI. [GitHub](https://github.com/ProtonPass/pass-cli) | | `ssh-agent` | Optional | Required for SSH key load functionality. Present on most systems. | | `openssh-client` | Optional | For SSH operations. | ## Security ### Secret Context Exposure **This is the most important consideration for this skill.** Passwords and secrets returned by `pass-cli` enter the agent's context directly. This is expected (the agent needs secrets to use them), but has implications: - **Prompt logging** — Secrets may appear in chat history or session logs - **`proton_pass_inject`** — Sets temporary env vars for subprocesses with automatic masking of secrets in stdout/stderr - **`proton_pass_get`** — Returns full item details including passwords. Use only when the agent genuinely needs the value - **Client-side filtering** — `proton_pass_search` retrieves item names only, not secret values ### Session Security - pass-cli stores session data encrypted in the platform-specific secure location - Session persists until explicit logout (`proton_pass_logout`) - Personal Access Tokens provide scoped, revocable access — recommended over full credential login for automation - SSH keys stored in Proton Pass are encrypted at rest within the vault ### Best Practices 1. **Use PAT for automation** — Avoid interactive password/PIN entry in CI/CD 2. **Minimize `get` calls** — Retrieve only the secrets you need, not entire items 3. **Prefer `inject`** — Use `proton_pass_inject` to pass secrets as env vars to subprocesses rather than reading them into agent context 4. **Log out after batch operations** — `proton_pass_logout` when done with a session 5. **Environment variables** — Set `PROTON_PASS_CLI_PATH` if `pass-cli` isn't in `PATH` ## Limitations 1. **pass-cli must be installed separately** — Not bundled with Hermes 2. **Secrets in agent context** — Use `inject` mode to minimize exposure 3. **Interactive login needs TTY** — Browser or credential prompts require user interaction 4. **SSH agent requires `SSH_AUTH_SOCK`** — Only works when an SSH agent is running 5. **No native search** — pass-cli's `item view` supports lookup by title, but full text search is implemented client-side via listing + filtering 6. **TOTP field access** — Uses the `totp` field on items via `item view --field totp`; works only if TOTP is configured for that item ## Related - [Proton Pass CLI Documentation](https://protonpass.github.io/pass-cli/) - [Proton Pass CLI GitHub](https://github.com/ProtonPass/pass-cli) - [Secret References Syntax](https://protonpass.github.io/pass-cli/commands/contents/secret-references/) - [ARCHITECTURE.md](../../ARCHITECTURE.md) — Hermes-Proton integration design (section 4)