I've spent the last couple days working on a 1Password integration into iTerm2. It will be an alternative data source to the mac Keychain that is currently used, but the same GUI for password management will be used by both. There's a lot to like about it - I was able to get up to speed quickly and the documentation is generally good. I thought you might like to know the problems I ran into:
- Performance is really poor. Getting a list of accounts (I have four) takes over 3 seconds. The command I'm running is
op item list --tags iTerm2 --format json | op item get --format=json.
- It's surprisingly difficult to get a list of (title, user name, item ID) for all items containing a tag. I settled on the pipeline above because it was the simplest way I could find. If I didn't need the ID it'd be easy, but the ID is essential for managing the list of passwords (e.g., to edit a username) or to fetch the current password for an item.
- The aforementioned pipeline produces concatenated JSON as output, which my tooling (Swift) requires gross hacks to parse - I need to turn it into an array of dictionaries by wrapping it in square brackets and adding commas between each item, which is very hard to do correctly.
- Errors are not machine-readable. I have to run regular expressions over them to guess what the error means. If you have localizations of your error messages, this is going to break. For example, to tell if you need to reauthenticate I have to look for an error containing "You are not currently signed in". It would be better to have different return codes for different errors or have a way to spit out errors in JSON that are machine-readable.
- I want to wrap the authentication step in a native GUI. Unfortunately,
op signin --raw writes directly to
/dev/tty. That means I would have to use forkpty() to launch
op if I want to know the text of the password prompt. Anything involving pseudoterminals is a PITA, and I say that as the author of a terminal emulator :)
- There is no secure way to change a password or add an item with a non-autogenerated password.
op item edit -h acknowledges this ("When setting sensitive values, carefully evaluate where you're using assignment statements. Command arguments can be visible to other processes on your machine"). There should be a way to provide a password via stdin rather than as a command-line attribute. This has forced me to only allow autogenerated passwords, which adds an extra step for users who have to go edit them through the native app. Obviously autogenerated passwords are better, but my users will undoubtedly need to share passwords with other non-1password users so this is a real limitation.
- The link on this page takes you to v1 of the CLI for macOS. Is that an oversight? https://developer.1password.com/docs/cli/v1/get-started/
- Errors aren't well documented. For example, I'd like to handle the case where enabling biometric authentication requires the 1password app to be locked and unlocked, but I only discovered it by accident. There are surely many more edge cases I would want to expose.
- I wish I could test whether biometric authentication is enabled. Currently I do it with a hack (try to get an item with a bogus ID and parsing the error message). This is important because it determines whether I need to prompt the user to enter their master password to fetch an auth token.
1Password Version: 8.7.0
Extension Version: Not Provided
OS Version: macOS 12.2.1
This is absolutely amazing, @gnachman2, thank you so much for all this feedback!
Some followups here:
1. This has been indeed brought up my multiple customers of the CLI. We're currently investigating the issue and hope to be able to roll out an optimisation soon. In the meantime, please, do let us know if enabling the cache benefits your performance. We have some more ideas to further improve the cache as well, but, for the command you listed, it should help! Let us know if you have any specific suggestions around this feature.
2. Indeed piping
op item listto
op item getshould be the easiest way to proceed here. I am not sure I fully get the picture though, can you tell me a bit more about your use-case? By ID, do you mean the ID of a field (I am asking since the ID of the item is already within
op item listoutput)? If not, what item details that are not within the
listoutput do you need in your workflow?
3. What format would be the easiest to parse for you? We want to make sure the CLI integrates with all the stacks and workflows, so please feel free to let us know, if you have specific suggestions here!
4. That's indeed a pet peeve of mine as well. We have an internal issue related to revamping our error-text, I'll make sure I'll look it up and bump it a bit, I see how annoying this can become, in an automated scenario.
5. Whenever I need to store the token in a file for testing purposes, I usually do
echo $(op signin --raw) > token.txt. Would this help, in your use-case? If not, what would something that would serve your use-case look like? I imagine something like a
--output-fileflag to the
signincommand, but I don't want to speculate :)
6. We are currently looking into adding the ability to pipe json into
op item edit, as well as allow passing a
--templateflag, similar in behaviour to
op item create. Would this serve your use-case? How would you envision something more...native looking like? Personally, I could see prompting securely, interactively, for a password and a password confirmation. Do you have any suggestions here?
7. Those are indeed the v1 docs, which exist in the developer portal as well. We noticed indeed that this link is currently the one that is accessed from the 'Get started' button of this page: https://1password.com/downloads/command-line/, and this is an oversight that is currently being addressed. Have you noticed this reference anywhere else?
8. I'll pass this feedback along to the biometric unlock team!
9. What I do in this scenario is an
op user get --me. We currently have, on our backlog, an issue about a command to show the authentication status, something like
op status. This is an issue also when biometric unlock is not enabled, so hopefully we'll get two birds with one stone here. What do you think about this?
Once again, thank you a lot for your feedback, and I'm looking forward to hearing from you again!
I don't see a big improvement by using --cache. I guess there might be something about the way I run
opthat prevents the cache from being effective. I fork and exec a new process each time, setting the OP_SESSION_my environment variable to ensure it's authenticated. Maybe the cache requires the same parent process each time?
op item listby itself doesn't give user names; otherwise it'd be perfect. My goal is to show this UI:
As for ID, I mean the item ID that
item listnormally shows. The unique identifier for the item. I need that to edit or delete the item.
A well-formed JSON document would be fine. Even newline-delimited JSON (http://ndjson.org/) would be better, because then I could parse each line as a separate document and know it would always be correct. So would a custom format specified with --format, although that would probably get pretty hairy to generalize.
I basically do this (but I save it in memory). The problem is I don't know what your password prompt says. For example: "Enter the password for [email protected] at my.1password.com". I guess there could be other messages, like if it doesn't know what your email address is, or the host name is not my.1password.com, or if something else goes wrong.
For my purposes I'd prefer JSON over interactive.
echo password | op item set IDwould be good enough for me, but I'm sure it'd be nice to generalize it to other fields as well since you could have non-password values that need to be kept secret. This affects both creating an account as well as changing an existing password.
No, nowhere else yet.
This works and is better than my hack. Thanks! An extension of op status would be great.
And I'll add an item 10: it'd be great if the CLI were open source. I could get to the bottom of things more easily.
Thanks so much for your help!
@gnachman2 Please consider sharing your integration!
I've been looking for something similar, and the only thing I've found thus far is built on the old CLI.
I'm sure once it's ready, Mr. Nachman will make it part of iTerm2. In case you're not aware, he's the developer.
@Techrocket9 It's in the nightly build, give it a try and send feedback. https://iterm2.com/nightly/latest
The feature looks promising!
It looks like it doesn't work when my mac is docked & closed though; I get stuck at the "Enable biometric auth for 1password" header with an empty item list even though the setting is enabled in the Developer area of 1Password 8.
P.S. Is there a preferred forum for iTerm2 feedback? I looked around in the menus of the nightly build and performed this search to no avail.
Thank you once again for all the suggestions, @gnachman2!
I've opened internal tickets to track most of your points above.
Please, do keep the feedback coming. :)
@Techrocket9 Please file a ticket at https://iterm2.com/bugs.
@Horia.Culea_1P Thank you! One other bit of feedback - the CLI seems to have gotten into a broken state on my machine. I posted in another thread, but I'll link it here to give it more visibility: https://1password.community/discussion/128167/cli-v2-not-connecting-to-desktop-app-sandbox-issue
Thank you for your feedback, and sorry for the late reply!
I believe the thread you linked above contains a potential cause for this issue. Were you able to confirm whether this is the root cause for you too/address the problem?
Looking forward to hearing from you.