Calling the CLI from a Go program

firelizzard
firelizzard
Community Member

I'm working on a Go program and I want to call op, using the PolKit/app integration so a dialog appears prompting the user to type in their password. This works when I run op directly from my shell, but it does not work when I exec op from my Go program. So far what I have is effectively exec.Command("/usr/local/bin/op", ...).Output(). However, that is failing with [ERROR] 2022/12/05 14:23:19 error initializing client: connecting to desktop app: read: connection reset, make sure the CLI is correctly installed and Connect with 1Password CLI is enabled in the 1Password app. All --debug does is add DEBUG | NM request: NmRequestAccounts.


1Password Version: CLI 2.7.3, desktop 8.9
Extension Version: 2.3.8
OS Version: Gentoo Linux
Browser:_ Firefox

Comments

  • firelizzard
    firelizzard
    Community Member

    I figured it out. Both the executable that calls op and the directory that executable is in must be owned by root.

  • Hi @firelizzard:

    Thanks for reaching out about this. This is something we're aware of, and I've added you as affected to our internal tracking issue.

    Jack

    ref: dev/core/core#18349

  • firelizzard
    firelizzard
    Community Member

    @Jack.P_1P, thanks for the update. I have a workaround (chmod root:root) but the behavior is odd and it does make it considerably harder to use a debugger on my executable. I tried to reproduce it with a test executable in place of op but I could not replicate the owner-dependent behavior. I tried running op with strace, but that gave me the same error. I read that ptrace no longer respects setuid/setgid bits because of potential vulnerabilities, but I expected to see a failed setgid syscall, which I did not see. So I guess op is using the effective GID or doing some other magic.

  • You're very welcome.

  • rsyring
    rsyring
    Community Member
    edited December 2022

    Any resolution to this? I'm having the same problem trying to call op from a Python script.

    Additionally, setting the python binary and it's directory to be owned by root did not resolve my issues.

    Logs. First one shows successful signin from bash CLI. Second one shows attempt from Python using it's subprocess module.

    INFO 2022-12-23T03:05:50.345 tokio-runtime-worker(ThreadId(10)) [1P:native-messaging/op-native-core-integration/src/lib.rs:305] Extension connecting.
    INFO 2022-12-23T03:05:50.345 tokio-runtime-worker(ThreadId(10)) [1P:native-messaging/op-native-core-integration/src/lib.rs:307] Extension connection accepted.
    ERROR 2022-12-23T03:05:54.467 tokio-runtime-worker(ThreadId(2)) [1P:native-messaging/op-native-core-integration/src/connection_handler.rs:60] message from b5x was None: EndConnection
    ERROR 2022-12-23T03:05:54.467 tokio-runtime-worker(ThreadId(2)) [1P:native-messaging/op-native-core-integration/src/connection_handler.rs:31] Dropping connection with b5x due to error handling incoming message: EndConnection
    WARN 2022-12-23T03:06:14.128 tokio-runtime-worker(ThreadId(2)) [1P:foundation/op-sys-info/src/process_information/linux.rs:247] binary permission verification failed for /shared/apps/pyenv/versions/3.10.6/bin/python3.10
    INFO 2022-12-23T03:06:14.128 tokio-runtime-worker(ThreadId(2)) [1P:native-messaging/op-native-core-integration/src/lib.rs:305] Extension connecting.
    ERROR 2022-12-23T03:06:14.128 tokio-runtime-worker(ThreadId(2)) [1P:native-messaging/op-native-core-integration/src/lib.rs:477] Failed to accept new connection.: PipeAuthError(UnknownPeer(BinaryPermissions))

  • rsyring
    rsyring
    Community Member

    I'd add this to my past comment but it is apparently being moderated:

    $ op --version
    2.12.0
    $ 1password --version
    8.9.10

  • gunzy83
    gunzy83
    Community Member
    edited February 2023

    Apologies for the duplicate comments. Every time I reloaded the page a few hours later my draft was still sitting there and my comment was not there.

  • gunzy83
    gunzy83
    Community Member
    edited February 2023

    Dupe

  • gunzy83
    gunzy83
    Community Member

    I have run into this a number of times now, and it is frustrating because it slows my development work, particularly when I just want to use existing integrations in things like Ansible but also not rely on system dependencies like system python. It appears that the op cli communicates which process is calling it to the 1password desktop app, which then checks for root ownership of that binary.

    My main test case that was simple to get going was running task (taskfile.dev) installed via asdf-vm (installed in my user directory). Running the op read command in a task cmds entry would result in failure:

    WARN  2023-02-14T08:14:33.816 tokio-runtime-worker(ThreadId(5)) [1P:foundation/op-sys-info/src/process_information/linux.rs:247] binary permission verification failed for /home/$USER/.asdf/installs/task/3.17.0/bin/task
    INFO  2023-02-14T08:14:33.816 tokio-runtime-worker(ThreadId(5)) [1P:native-messaging/op-native-core-integration/src/lib.rs:305] Extension connecting.
    ERROR 2023-02-14T08:14:33.816 tokio-runtime-worker(ThreadId(5)) [1P:native-messaging/op-native-core-integration/src/lib.rs:481] Failed to accept new connection.: PipeAuthError(UnknownPeer(BinaryPermissions))
    

    However, adding a shim script in the middle (run using system bash which is owned by root) works. This led me to creating this script in ~/.bin/op (~/.bin is on my path) for my test cases:

    #!/bin/bash
    /usr/bin/op $@
    

    I was using pstree -aps $$ in earlier versions of the script to look at the process call tree, but it really wasn't necessary as it appears only the one immediately before running op actually matters. With this, calling op directly from task, python and others just work. This is trivially bypassing the restriction on binary ownership which just seems to get in the way.

    @Jack.P_1P Forgive my ignorance, you can tell me this is all kinds of awful and to knock it off, but would it be possible to share with us the security reasons for the binary ownership restriction? It would also be good for this to be documented somewhere.

    @rsysring I saw you were trying to use pyenv. I am wondering if the shim process the pyenv and other tools like asdf use may be an issue also.

  • Hi @gunzy83:

    Sorry about that, it looks like your comments might have got caught in our spam filter. What I can tell you is that we're looking into this and hope to share more soon.

    Jack

  • gunzy83
    gunzy83
    Community Member

    Thanks Jack.

  • gunzy83
    gunzy83
    Community Member

    @asdfasdfasdfasdf the lookup plugin still does not support op v2: https://github.com/ansible-collections/community.general/issues/5303 so I think that is unrelated for now but once support is merged it will also be affected by this binary check issue if you are not using system python (owned by root).

  • rsyring
    rsyring
    Community Member

    @gunzy83 thanks so much for the details in your Feb 14th post. The op script workaround is a great find. Also, I agree with your sentiments that the binary permissions check seems more annoying than helpful and should be documented.

    @Jack.P_1P I don't suppose you have an update yet on this?

  • Hi folks,

    Sorry for the delay here. I don't have anything else to share just yet, but we are looking into solutions at this time.

    Jack

  • smgt
    smgt
    Community Member

    I'm trying to build a CLI tool using go. Running into the same problems as mentioned above when "Connect with 1Password CLI" is enabled. I can get it to work if I use the regular session token.

  • smgt
    smgt
    Community Member

    After playing around a little more it seems to be certain criteria that needs to be fulfilled to make it work. You can not just run your Go program using go run main.go for example. The executable needs to be in some system executable dir like /usr/bin or /usr/local/bin. The executable needs to be owned by root, chown root:root exe and the permissions needs to be 755, chmod 755 exe. I haven't played around extensively with different users and permissions.
    I've tried to run the exe from a path in my home dir (/home/$USER/bin) that's in the path $PATH but I don't seem to be able to run the exe in that dir and make it work even if the owner is root and permissions are 755 (rwxr-xr-x).

    I'm planning to do the following to continue to develop the Go.

    1. Disable "Connect with 1Password CLI"
    2. Add a function to handle op signin session tokens
    3. Develop
    4. Test
    5. During release move the compiled binary to /usr/bin and change user to root and permissions to 755
    6. Enable "Connect with 1Password CLI"
  • gunzy83
    gunzy83
    Community Member

    @smgt Your findings echo mine, I also found that unless the directory tree from the binary to the root directory is all owned by root it will fail. If any of the parent, grandparent etc directories are not root owned it will fail. I did my testing in /opt, /media and /home (below user specific directories).

  • terinjokes
    terinjokes
    Community Member

    @Jack.P_1P This restriction causes problems for any integrations with 1Password when the use has GUI integration enabled. This has broken some of my integration, as well as community tooling such as kubectl-passman.

  • Thank you everyone for digging into this and bringing this to our attention. Unfortunately we've got no updates to share at this point, but this is on our radar we'll make sure to let y'all know once this gets prioritised and eventually resolved. Thank you for your understanding!

    Best,
    Horia

  • Joris_1P
    edited June 2023

    Hey all!

    Thanks for your patience. I'm checking back in to let you know that we released a new beta version of 1Password for Linux (8.10.8-24) yesterday that should allow you to use the CLI from a program that itself is not owned by root. You can follow the instructions here to install a beta release of the app. The fix will also be included in the next minor stable release, which will be out in a few weeks.

    Let me know if that fixes the problem for you.

    Joris

  • Quick update on this: we've now also released 1Password for Linux 8.10.8 stable . That means the fix is now available on all release channels.

This discussion has been closed.