Skip to main content

llm-1password

test

An llm plugin that keeps model API keys in 1Password.

I wrote this so llm can resolve keys from op:// references at call time. The durable store holds the reference only.

$ llm 1password doctor
op: /usr/local/bin/op
auth: SERVICE_ACCOUNT

$ llm 1password check
openai OK

refs.json is mode 0600 in a 0700 directory. The wrap that owns resolution is _wrapped_get_key in llm_1password.py.

Install

Requires Python 3.10+, llm 0.32 or newer, and the 1Password CLI.

llm install llm-1password

From a checkout:

git clone https://github.com/dallascrilley/llm-1password.git
cd llm-1password
llm install -e .

If llm itself fails with No module named 'httpx' before any plugin loads, that is an llm 0.32 packaging gap:

pipx inject llm httpx

Confirm the plugin loaded:

llm plugins
llm 1password doctor
llm 1password check

doctor prints the chosen op binary and its user_type. check prints No references registered. until you set one.

Use

llm 1password set openai 'op://Vault/Item/credential'
llm 1password check
llm 1password doctor
llm prompt 'hello'
llm 1password unset openai

set writes the reference under llm's user directory at 1password/refs.json. It does not write keys.json. The llm prompt line needs a reference op read can resolve. Run check first and look for OK.

If you previously stored a plaintext key for the same alias, remove that alias (llm keys path) so this plugin owns the name.

check exits 1 if any registered reference fails to resolve.

How resolution works

  1. If $HOME/.local/bin/op exists, is executable, and is a non-world-writable regular file, the plugin uses it. That lets a local wrapper sit in front of the official CLI.
  2. Otherwise it uses op on PATH, with the same file checks.
  3. It runs op read -- <ref>. A missing binary, a non-zero exit, a timeout, empty output, or a non-UTF-8 payload aborts the model call.

llm 1password doctor prints the chosen binary and the op whoami user_type field (SERVICE_ACCOUNT, or whatever op reports).

An explicit --key / input= value is not replaced by a registered alias unless that value itself is the alias. Unregistered op:// strings in keys.json or the environment are rejected rather than fetched or sent to the provider (_reject_bare_op_uri).

Security model

Surface Holds
refs.json op:// references only, mode 0600 in a 0700 directory
Process memory Secret value for the life of that llm process
check / doctor / errors Alias and OK/FAIL or binary/auth mode. Never the secret, never the reference path

If op read fails, the plugin raises an error and does not call the model.

What this package does not do

  • Resolve op:// inside prompts, templates, or fragments.
  • Hide the op:// URI from ps while op read is running.
  • Wrap assignments such as model.key = "op://...". Those bypass llm.get_key.
  • Uninstall leftover plaintext keys from keys.json.

See SECURITY.md for reporting and the guarantees the package aims for.

License

Apache-2.0

Metadata

Release files for llm-1password 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for llm-1password 0.1.0
File Size Uploaded
llm_1password-0.1.0.tar.gz 13.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for llm-1password 0.1.0
File Interpreter ABI Platform
llm_1password-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 23.1 kB

Release files / llm_1password-0.1.0.tar.gz

Download URL llm_1password-0.1.0.tar.gz
Size 13.1 kB
Tags Source
SHA-256 checksum
How to use checksums
2de74881b485fefbec1d3cc94169f955dd73c4f0ead46aea02769498f38ff0bb
BLAKE2b-256 checksum
How to use checksums
5ff0a1e520f59664ea24a98370cd9c74e5a7cfa2f42869c35a4ccc0638c92e30
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Release files / llm_1password-0.1.0-py3-none-any.whl

Download URL llm_1password-0.1.0-py3-none-any.whl
Size 10.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e37d91900e26793846c3adeb846ab210d38268f735d629ab7e85c4c710dad4f2
BLAKE2b-256 checksum
How to use checksums
a0335ce4a8c8c524d0704013ed49115b213370fb3988b4bceaf0c03139744faf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page