1password-client icon indicating copy to clipboard operation
1password-client copied to clipboard

vault query must be provided in case of service account

Open KellerLukas opened this issue 1 year ago • 2 comments

Describe the bug When using OnePassword.get_item while using a OP_SERVICE_ACCOUNT_TOKEN, then an error message is returned:

Using service account, for supported commands see: https://developer.1password.com/docs/service-accounts/use-with-1password-cli#supported-commands [ERROR] 2025/01/05 22:26:55 a vault query must be provided when this command is called by a service account. Please specify one either through the --vault flag or through piped input

and eventually a JSONDecodeError is raised

To Reproduce Steps to reproduce the behavior:

  1. have OP_SERVICE_ACCOUNT_TOKEN set as env variable
  2. run the following code:
from onepassword import OnePassword
op = OnePassword()
item_uuid = "myuuid"
op.get_item(uuid=item_uuid)

Expected behavior I want to be able to specify the vault uuid as required.

using 1password v1.0.9, 1password-cli v2.30.3 and python v3.13 on macOS Sequoia

KellerLukas avatar Jan 05 '25 21:01 KellerLukas

This could for example be fixed by modifying the get_item method as follows:

    def get_item(uuid: str | bytes, fields: str | bytes | list | None = None, vault_uuid: Optional[str]=None):
        """
        Helper function to get a certain field, you can find the UUID you need using list_items

        :param uuid: Uuid of the item you wish to get, no vault needed
        :param fields: To return only certain detail use either a specific field or list of them
            (Optional, default=None which means all fields returned)
        :param vault_uuid: When using service account, a vault_uuid must be provided (Optional, default=None)
        :return: Dictionary of the item with requested fields
        """
        if isinstance(fields, list):
            item_list = json.loads(read_bash_return(
                "op item get {} --format=json --fields label={}{}".format(uuid, ",label=".join(fields), f" --vault {vault_uuid}" if vault_uuid else ""),
                single=False))
            item = {}
            if isinstance(item_list, dict):
                item[fields[0]] = item_list["value"]
            else:
                for i in item_list:
                    item[i["id"]] = i["value"]
        elif isinstance(fields, str):
            item = {
                fields: read_bash_return(
                    "op item get {} --fields label={}{}".format(uuid, fields, f" --vault {vault_uuid}" if vault_uuid else ""), single=False).rstrip('\n')
            }
        else:
            item = json.loads(read_bash_return("op item get {} --format=json{}".format(uuid, f" --vault {vault_uuid}" if vault_uuid else ""), single=False))
        return item

KellerLukas avatar Jan 05 '25 21:01 KellerLukas

Thanks @KellerLukas ... feel free to submit a PR and we can work together to get it merged. Do remember to update the README if you add anything major functionality, if needed.

dtpryce avatar Jan 06 '25 12:01 dtpryce