How to read data from file with `op create item`?

Options
isme_es
isme_es
Community Member
edited June 2021 in CLI

The help shows only how to do this using command substitution.

op get template "Login" > login.json
op create item "Login" "$(op encode < login.json)"

This seems risky when combined with bash's debug tracing mode (set -x).

It's a common mode to include in automated scripts. I include by default following Tom Van Eyck's advice.

Debug tracing mode echos the result of command substitution.

So executing the create command above in trace mode renders this:

+ op create item Login eyJmaWVsZHMiOlt7ImRlc2lnbmF0aW9uIjoidXNlcm5hbWUiLCJuYW1lIjoidXNlcm5hbWUiLCJ0eXBlIjoiVCIsInZhbHVlIjoiIn0seyJkZXNpZ25hdGlvbiI6InBhc3N3b3JkIiwibmFtZSI6InBhc3N3b3JkIiwidHlwZSI6IlAiLCJ2YWx1ZSI6IiJ9XSwibm90ZXNQbGFpbiI6IiIsInBhc3N3b3JkSGlzdG9yeSI6W10sInNlY3Rpb25zIjpbXX0
{"uuid":"6r65tcu33f4flmhcfi5qnpe2qe","createdAt":"2021-06-30T11:27:56.613417287+02:00","updatedAt":"2021-06-30T11:27:56.613417573+02:00","vaultUuid":"7bb6kgvfmpuekr5tcv6EXAMPLE"}

I can recover the plain text input easily by decoding from base64:

$ echo "eyJmaWVsZHMiOlt7ImRlc2lnbmF0aW9uIjoidXNlcm5hbWUiLCJuYW1lIjoidXNlcm5hbWUiLCJ0eXBlIjoiVCIsInZhbHVlIjoiIn0seyJkZXNpZ25hdGlvbiI6InBhc3N3b3JkIiwibmFtZSI6InBhc3N3b3JkIiwidHlwZSI6IlAiLCJ2YWx1ZSI6IiJ9XSwibm90ZXNQbGFpbiI6IiIsInBhc3N3b3JkSGlzdG9yeSI6W10sInNlY3Rpb25zIjpbXX0" | base64 --decode
[omit trace]
{"fields":[{"designation":"username","name":"username","type":"T","value":""},{"designation":"password","name":"password","type":"P","value":""}],"notesPlain":"","passwordHistory":[],"sections":[]}base64: invalid input

This example has some noise at the end because the coreutils base64 command doesn't understand base64url, but it's close enough.

I suppose I can avoid it by ensuring not to run op commands in trace mode.

I'd feel safer being able to read the item data from a file so that sensitive data would not be echoed in any case.

Database CLI tools face the same problem of receiving a password to log in without leaking it to command logs. psql's .pgpass file and mysql's .mylogin.cnf are two solutions I'm aware of.

Does op have a similar option?

I'm using CLI version 1.10.3.


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

Comments

  • ag_April
    edited July 2021
    Options

    Hello @isme_es,

    I'm sorry to hear that you aren't able to obfuscate the encoded item that you're passing into the op create item command.

    At the moment, the create item command only supports receiving the encoded item as a command-line argument. There is not currently a means by which you can pass a filename or similar. Unfortunately, this does mean that the encoded item will be printed out whenever your script is run in a set -x or set -o xtrace context. I'll bring it up with the team that this feature is something that we should support. ref: dev/b5/op#1470

    In the meantime, as a workaround, you can wrap any calls to op create item with a command to turn off xtrace and to optionally re-enable xtrace if it had been previously enabled. Here is an example script that shows how you might do that:

    #!/usr/bin/env bash
    
    set -x
    
    # If the script has xtrace enabled, remember that
    [[ "$SHELLOPTS" =~ xtrace ]] && is_xtrace=1
    
    # Disable xtrace for the create item command
    set +x
    op create item Login "$(op encode < login.json)"
    
    # If xtrace was previously enabled, re-enable it
    [[ "$is_xtrace" ]] && set -x
    
    exit 0
    

    I hope that this helps. Let us know if you have any further questions.

    April

  • zcutlip
    zcutlip
    Community Member
    Options

    I came searching for this exact issue.

    The encoded json argument will be world readable on most operating systems by enumerating processes (such as with ps -ef, etc). Doing the encode in a sub-shell isn't possible when executing programmatically, such as with Python's subprocess, since no shell is invoked.

    An option, e.g., -f, to read from a file on disk, or e.g., -- to read from standard in would be much appreciated.

  • Hello @zcutlip,

    Thanks for raising that. We are aware of the problems that are possible by requiring that the encoded JSON be passed as an argument, instead of via a file or stdin. It's something that we are working on addressing in an upcoming release, but I don't have an estimated timeline for you at this point.

    Please feel free to write in with any additional feedback or concerns.

  • zcutlip
    zcutlip
    Community Member
    Options

    It's something that we are working on addressing in an upcoming release, but I don't have an estimated timeline for you at this point.

    No worries. Thanks for looking into it

  • You're welcome!

  • zcutlip
    zcutlip
    Community Member
    Options

    From 11.12.1 release notes:

    You can now create items using a template file loaded from disk. {1620}

    Thank you for this 🙏

    I'm in the (slow) process of adding item creation to pyonepassword and this will simplify things.

    Reading from stdin would also be great, but this is good too. I can now create an adequately protected temp file to write the template to for item creation.

    Cheers 🍻
    Zach

  • I'm glad to hear you like it, Zach!

    One thing to note when protecting that created temp file. On macOS, Linux, etc., you should set umask. Since Windows uses hierarchical directory permissions, the safest place that we're able to recommend is in your user’s home directory.

    On macOS and Linux:

    umask 077   # Prevent others from reading your template file
    
    op get template login | \
      jq '(.fields[] | select(.designation == "username")).value = "zcutlip"' > login.json
    op create item login --template login.json --title "My New Item"
    rm login.json
    

    On Windows (PowerShell):

    cd "$HOME"   # Prevent others from reading your template file
    
    op get template login | \
      jq '(.fields[] | select(.designation == "username")).value = "zcutlip"' > login.json
    op create item login --template login.json --title "My New Item"
    rm login.json
    
  • isme_es
    isme_es
    Community Member
    Options

    Great work. Thanks for addressing this!

  • Thank you! Glad you like it!

This discussion has been closed.