option to enumerate signed-in accounts or latest signed-in

zcutlip
zcutlip
Community Member

I'm trying to use op in a scripted situation, and I'd like to avoid requiring the account shorthand be specified. The most common case in my situation is that only one account is configured for op. To that end, I'm wondering if any of the following are possible:

  • A command or argument to have op tell me the latest signed-in account
  • A command to enumerate accounts op has configured on this device
  • A command to have op tell me the path to its config so I can parse the json in my script to get details I need

Thanks!


1Password Version: Not Provided
Extension Version: Not Provided
OS Version: Not Provided
Sync Type: Not Provided

Comments

  • felix_1p
    felix_1p
    1Password Alumni

    At the moment the config file is either at $XDG_CONFIG_HOME/.op/config or $HOME/.op/config depending on your setup.

    What exactly do you plan to do? If you don't want to specify the account and there is only a single account then op signin will just work (it will log into the last signed in account).

  • zcutlip
    zcutlip
    Community Member

    What exactly do you plan to do?

    The main issue is that I need to set the session key in an OP_SESSION_<account shorthand> environment variable. I'm doing this in python, so I can't use the eval $(op signin) shell magic; I have to use --raw. But there's no way I'm aware of to programmatically work out what the user chose (or had chosen for them) as the account shorthand during initial sign-in.

    I've considered using --session for all subsequent op invocations but since the session key is world readable in the process table (e.g., ps -ef will reveal it) I'd rather not go that route.

    Cheers,
    Zach

  • I have few ideas here, so I hope you don't mind me jumping in over the weekend! The first is to use a specific hardcoded shorthand for your script. That way, you can specify the account you'd like to use with the script by changing the shorthand in op.

    The second would be to use the information Felix gave to read the config file, which provides the shorthand of the last account that signed in. In python, you could fetch this information with the following code snippet:

    import os, json
    
    home_path = os.environ.get("XDG_CONFIG_HOME") or os.environ.get("HOME") or os.environ.get("USERPROFILE")
    config_path = os.path.join(home_path, ".op", "config")
    
    with open(config_path) as file:
        config = json.load(file)
        shorthand = config.get("latest_signin")
    

    The caveat to this is that the config file could change over time, so you may need to update your code to handle this.

    The third is to take the output of op signin (without --raw) and interpret that in python. To achieve that, you could do something like this:

    import subprocess
    
    signin_output = subprocess.check_output(["./op", "signin"], text=True)
    env = output.partition("\n")[0].partition(" ")[2].partition("=")
    
    # env[0] is set to the environment variable name (OP_SESSION_<account shorthand>), and env[2] is set to the value (the session key).
    # These can be passed into subsequent subprocess calls
    

    The fourth is to use --session itself. I know you said you're reluctant to use this — are there any particular situations you're envisaging might occur that you'd like to avoid when using this method?

  • zcutlip
    zcutlip
    Community Member

    Hey thanks @Matthew_1P, I appreciate your input!

    What I'm doing currently is kind of a combo of (1) and (2):
    Provide account shorthand as a kwarg:
    https://github.com/zcutlip/pyonepassword/blob/41bf4bb3e211f9178aa3bfbb84a2edb3e6021c35/pyonepassword/pyonepassword.py#L83

    In some cases the user may not know (or remember) the shorthand they chose. I didn't know mine. So if shorthand is None, try to parse the config from one of its places and use latest_signin:
    https://github.com/zcutlip/pyonepassword/blob/41bf4bb3e211f9178aa3bfbb84a2edb3e6021c35/pyonepassword/_py_op_cli.py#L42
    Also, I missed USERPROFILE on this; thanks for the tip!

    Option (3), parsing stdout, looks doable based on your example. I'll have a look.

    For option (4), just as a quick PoC I was able to run ps -ef in a tight loop as another user and easily see the session token, which I assume must be protected.

    As far as I know there's no reliable way to mask command sensitive command line args and the canonical way to protect sensitive inputs to command line programs is to use environment variables.

    Thanks, and I'll look into option 3 as a fallback.
    Zach

  • felix_1p
    felix_1p
    1Password Alumni

    For option (4), just as a quick PoC I was able to run ps -ef in a tight loop as another user and easily see the session token, which I assume must be protected.

    I meant to mention this on the GitHub issue but might as well here: The session token alone is not useful to anyone. It's basically an encryption key used to decrypt the session file which contains the actual sensitive information. So protecting your session files is even more important (but op also verifies that their permissions are as expected).

    Of course there isn't really anything you can do to prevent access from the root user.

    We should definitely extend our documentation to explain more how these things fit together and how would one go about protecting their information in certain situations.

  • zcutlip
    zcutlip
    Community Member

    The session token alone is not useful to anyone. It's basically an encryption key used to decrypt the session file which contains the actual sensitive information.

    Awesome; this is really useful to know. Just out of curiosity, where does the session file live? I don't see it in ~/.op.

    We should definitely extend our documentation to explain more how these things fit together and how would one go about protecting their information in certain situations.

    That'd be helpful.

    Thanks for the clarification!

  • Just out of curiosity, where does the session file live? I don't see it in ~/.op.

    In the current version of the CLI tool, session files live in /tmp/com.agilebits.op.1000 (or .1001 and so on if subsequent users call op).

    As far as I know there's no reliable way to mask command sensitive command line args

    As Felix mentioned, you don't actually need to do this when using --session with the CLI tool, but I recently found out that it's possible to do something like this when working on a personal project. Since version 3.3 of the Linux kernel, /proc (which provides information about running processes) can be mounted with the hidepid option. I won't go into details here since it may vary by system and you don't need to do it for op, but I just thought I'd share in case you weren't aware of this option like I wasn't :smile:

  • zcutlip
    zcutlip
    Community Member

    but I just thought I'd share in case you weren't aware of this option like I wasn't

    I certainly wasn't. Thanks!

  • ag_ana
    ag_ana
    1Password Alumni

    On behalf of Matthew, you are welcome!

This discussion has been closed.