CLI keeps prompting for authentication

Options
perhlom
perhlom
Community Member

Hi,

I'm trying to come up with the best way to use the CLI to load secrets into some dev/deploy scripts, and I can't figure out how to avoid 1Password prompting for authentication incessantly. I was expecting an authentication to stick at least a little bit, but two calls to "op read" back to back will have two authentication prompts back to back.

The main problem with the "op run" method is that you can't load credentials ad-hoc, but have to load all of them at the same time. That's a problem when different users have access to different things in a script. Everyone has access to certain development functions, but only some people have access to deployment functions. That makes it impossible to preload all credentials, because this will fail for everyone who doesn't have the Deployment vault shared to their account. So it's necessary to load credentials as needed, during the interactive script.

But "op read" is extremely user-hostile, and prompts for every single request. If I load 20 secrets at runtime, that's literally 20 authentication prompts, and 20 x 3-5 seconds of waiting. It's completely impossible to use "op read" for anything but a single credential. I'm struggling to understand why the "op read" command even exists.

Is there a way for CLI access to persist for a process? Then you could just authenticate on the first "op read", and every subsequent "op read", even for child processes, would just continue working.

And then is there a way to not have a 3-5 second delay on every single call of "op read"?

The only hack I can come up with is if non-deployment users still have a fake vault called "Deployment" filled with fake credentials that allow the script to be loaded even if they don't have a high-level vault shared with them. But then what when you have 5 or 10 areas of restricted access? Does every user need 9 fake vaults for every 1 real vault filled with fake credentials, just so that "op run" can work at all?

This is getting ugly, and I'm frankly a millimeter away from going back to Veracrypt volumes, which allows me to open and decrypt volumes at runtime, and have them automatically close again after some time. But those volumes are accessible to the whole system, which isn't good either.

Ideally, the CLI would:

  • Authenticate on first access and stay connected.
  • Read credentials in milliseconds, not seconds.
  • Have permissions per-vault that allow the access to persist just for that vault.
  • Be usable at runtime, and not requiring wrapping every bash script in "op run", which is some noisy syntax for what used to be clean. Every script now needs a "launcher" script just to not have to type that all the time.

I realize that there's this Connect thing that runs authentication containers. But that's a non-starter for us, because we have elaborate local Docker clusters for development that's managed by our scripts, and currently, all running containers are ours. It would be disruptive to have to tippy-toe around 1Password containers.

Is there really no way to simply have CLI access while a script is running without a the tax of repeated prompts and minute-long delays?

Per


1Password Version: 8.10.1
Extension Version: Not Provided
OS Version: Windows 11
Browser:_ Not Provided

Comments

  • perhlom
    perhlom
    Community Member
    Options

    After some investigation, this is what we understand.

    In short, 1Password and Git Bash don't go well together. Everything works as expected in Windows Terminal and PowerShell, but not in Git Bash. As we understand, this is because Windows Terminal is authenticated as a process using Windows Hello, so "op signin --raw" doesn't return anything, because a token isn't used to authenticate at all, Windows Hello is authenticating the processes against each other.

    But since Git Bash launches a new process for every command, this child process isn't authenticated with Windows Hello, causing it to re-prompt for Windows Hello authentication, which takes 3-5 seconds for every call.

    One (unacceptable) solution is to disable Windows Hello for the whole 1Password installation. But then your whole use of 1Password is without Windows Hello.

    The other option is to disable the CLI integration with the local 1Password installation, causing you to authenticate against the 1Password servers instead, but this invokes some new tricky issues:

    Git Bash's terminal isn't able to get text output from any of the OP commands, so invoking e.g. "op account add" or "op signin" is completely non-interactive. If you can guess the output, you can type the right things, but adding accounts is difficult.

    So the workflow would have to be that you do "op account add" in a Windows PowerShell, which is properly interactive. This involves entering your account email address, the --address (my.1password.com or similar), the secret key and the password. This adds the account to the CLI itself, making it also available in Git Bash afterwards.

    So now it's possible to go to Git Bash and do "OP_TOKEN=$(op signin --raw)", and guessing whether op signin is asking you for a password. If it does, it appears to freeze, but if you enter the password, you get a token back. All subsequent bash calls should then be in the form of "op read --debug "op://Development/Dev Secrets/Demo Values/TESTKEY" --session ${OP_TOKEN}".

    And now these calls are reasonably fast. I do need to figure out why any OP commands are non-interactive in Git Bash. It looks like 1Password is simply using another output pipe. Any help would be much appreciated.

    The downside is no Windows Hello. You have to enter your password every time. So it's a good idea to load the credentials only in a launchpad script, export your credentials, and then run all your scripts without being asked again.

  • Hi @perhlom:

    Great investigation there. I see that we have an internal discussion tracking this behavior, so I've added you as affected.

    Jack

    ref: dev/b5/op#2577

  • perhlom
    perhlom
    Community Member
    Options

    It strikes me that you should be able to both do Windows Hello and a token at the same time. I saw in another forum discussion that you considered them mutually exclusive, but I don't understand why.

    The Git Bash code would then say "export OP_TOKEN=$(op signin --raw)". When you receive this, you BOTH authenticate via Windows Hello, AND you return a code, which then becomes available to child processes of Git Bash. The parent process would already be authenticated with Windows Hello. Child processes would then run commands with --session $OP_TOKEN.

    Currently, the only way to do this is to disable the CLI integration, forcing you to type the full password all the time, which incentivizes short passwords.

    Secondly, I find that "op run" isn't viable when you have multiple vaults, some of which may not be available for all users. "Op run" stops on the first failure, which is expected for a user without deployment privileges. If you had a --ignore-errors, you would allow just loading the credentials that can be loaded for that user. The rest just wouldn't be loaded, causing later build scripts or CI to fail, which is desired and expected behavior. Build scripts already have error paths, and missing credentials are usually easy to debug. So you just have to ignore the errors and everything works out.

    So this is forcing into making my own reader that doesn't stop on errors. I'm reading items as JSON, iterating values and turning them into exported environment variables. I'd much rather use your substitution methods, but it just can't be done if any vault is missing. I've spent all day trying to cook up a workaround, and the only thing I can do is a bit of a behemoth of doing all the reading and exporting myself.

    An --ignore-errors flag would be the magic sauce.

  • perhlom
    perhlom
    Community Member
    edited March 2023
    Options

    I should note that the problem with not getting any output from Git Bash on "op ..." commands is alleviated by using Windows Terminal Preview and setting the executable path to "C:\Program Files\Git\bin\bash.exe", which is the underlying bash that Git Bash executes. So it's some kind of terminal emulation problem likely local to the exact terminal Git Bash ships with.

This discussion has been closed.