Accessing 1Password items from the terminal

I save things like API keys in 1Password. Today I figured out how to access those from macOS terminal scripts.

My initial goal was to make a Fly.io API key available in an environment variable, without copying and pasting it.

Claude pointed me to the op 1Password terminal app. Here are the official installation instructions, which boil down to:

brew install 1password-cli

Then open 1Password and find the Developer tab in settings and enable the 1Password CLI option:

1Password developer settings have a clear CLI enabling checkbox

Having done this, the op command is ready to use. To see a list of vaults:

op vault list

This asked me for my Touch ID before running:

1Password access requested - a Touch ID prompt

I only have one vault, so I got back this:

ID                            NAME
db6xmelzrupwlyrfbiy5ltrnfy    Personal

There are a few ways to access items. One is to find the item ID using op items list and grep:

op items list | grep 'Datasette Cloud Dev'

This displayed:

uv4maokwxaaymkmoxawwcyfeve    Datasette Cloud Dev Simon     Personal     4 minutes ago

You can then access the item using op item get and that ID:

op item get uv4maokwxaaymkmoxawwcyfeve

This output what looked like YAML:

ID:          uv4maokwxaaymkmoxawwcyfeve
Title:       Datasette Cloud Dev Simon
Vault:       Personal (db6xmelzrupwlyrfbiy5ltrnfy)
Created:     27 minutes ago
Updated:     5 minutes ago by Simon Willison
Favorite:    false
Version:     2
Category:    LOGIN
Fields:
  username:    fly token
  password:    FlyV1 fm2_...

You can also use the direct title of the item, like this:

op item get 'Datasette Cloud Dev Simon'

We just want the password, to write into an environment variable. Using --fields password nearly gets us that:

op item get 'Datasette Cloud Dev Simon' --fields password

Output:

"FlyV1 fm2_..."

This is wrapped in double quotes. The easiest way I found to strip those was to pipe it through jq -r - where the -r tells jq to output the raw value:

op item get 'Datasette Cloud Dev Simon' --fields password | jq -r

Output:

FlyV1 fm2_...

Then I assigned it to an environment variable like this:

export FLY_API_KEY=$(op item get 'Datasette Cloud Dev Simon' --field password | jq -r)

And used that key in an API call like this:

curl 'https://api.machines.dev/v1/apps?org_slug=datasette-cloud-dev' \ 
  -H "Authorization: $FLY_API_KEY"

Which output:

{"total_apps":0,"apps":[]}

Created 2024-07-09T20:26:25-07:00 · Edit