## op (1Password CLI)
[...]
### Safe patterns
- **Discover items using metadata only:** `op item list --categories <category> --vault <vault-id> --format json`
- **Pass a secret to a command:** put a secret reference in an environment variable and let `op run` resolve it only for the child process:
```sh
API_KEY='op://<vault-id>/<item-id>/<field>' op run -- <command>
```
Use a command that does not print the secret or its environment. Never pass `--no-masking`.
- **Enter secrets in a browser:** follow the procedure below.
- **Never expose secrets through agent tooling:** do not run `op read` or a secret-bearing `op item get` as a standalone tool call, interpolate its output into a tool-call argument, or use the clipboard or a regular temporary file.
### Browser logins in Codex
1. Find the exact login using metadata only. Record the item ID, vault ID, and the item's saved URLs; do not fetch fields yet:
```sh
op item list --categories Login --vault 7gnoy3xakiss55tevxazktcxou --format json |
jq -r '.[] | [.id, .title, .vault.id, ((.urls // []) | map(.href) | join(" "))] | @tsv'
```
2. **Origin check (mandatory):** before filling anything, confirm the registrable domain of the tab's current origin matches one of the item's saved URLs from step 1. On mismatch, abort—do not fill, and do not switch to a different item to make it match. Re-run the check after any navigation or redirect before a fill, including the 2FA page.
3. Before fetching secrets, locate and uniquely validate the required fields and submit control. Keep those handles for submission. If the site splits username and password across pages, repeat steps 3–6 with a fresh FIFO and fetch only the field needed on each page.
4. In one yielded agent-shell command, create a protected FIFO and start the secret writer under a 120-second watchdog. The command prints only the temporary directory path; the writer blocks until the browser-side reader connects; if abandoned, the watchdog kills the writer and trashes the directory so the FIFO cannot deliver credentials to a later reader:
```sh
login_item_id='ITEM_ID_FROM_STEP_1'
login_vault_id='VAULT_ID_FROM_STEP_1'
login_fields='label=username,label=password' # Use one label for a split login.
login_pipe_dir=$(mktemp -d /tmp/op-browser-login.XXXXXX)
chmod 700 "$login_pipe_dir"
mkfifo "$login_pipe_dir/secret"
chmod 600 "$login_pipe_dir/secret"
printf '%s\n' "$login_pipe_dir"
/opt/homebrew/bin/op item get "$login_item_id" \
--vault "$login_vault_id" \
--fields "$login_fields" \
--format json > "$login_pipe_dir/secret" &
login_writer_pid=$!
( sleep 120; kill "$login_writer_pid"; trash "$login_pipe_dir" ) 2>/dev/null &
login_watchdog_pid=$!
wait "$login_writer_pid"
login_status=$?
kill "$login_watchdog_pid" 2>/dev/null
exit "$login_status"
```
If the watchdog fires before the step-5 read completes, start again from step 4 with a fresh FIFO.
5. In the same Node session that controls the form, read `<printed-directory>/secret` once with `node:fs/promises`, parse the top-level JSON field array, select values by field label rather than array order, and fill the pre-validated controls without emitting the values. Submit immediately with the pre-validated login control—do not take a DOM snapshot, AX/app-state dump, screenshot, field read, or other page-state read between filling and submission. If the read or parse throws, report a sanitised error only—never the buffer contents.
6. Confirm that the yielded writer exited 0, then run `trash "<printed-directory>"`. On any error or interruption, terminate or poll the writer as needed and trash the directory. Before retrying, inspect the page because the previous attempt may already have submitted.
7. For 2FA, first re-run the origin check (step 2), then locate and uniquely validate the OTP field and confirm control. Repeat steps 4–6 with a fresh FIFO, replacing the `op item get` invocation in step 4 with:
```sh
/opt/homebrew/bin/op item get "$login_item_id" \
--vault "$login_vault_id" \
--otp > "$login_pipe_dir/secret"
```
Keep the backgrounding, watchdog, and `wait` scaffolding around it unchanged. Trim the FIFO value before filling the OTP field, then confirm immediately without an intervening page-state read.
If retrieval fails, use metadata-only diagnostics such as `op --version` and `op item list ... | jq 'length'`. Never print a secret to test access, spawn `op` from the browser's Node process, switch authentication methods, use the clipboard, or broaden vault access.