Skip to content

linuxfabrik.lfops.bitwarden_item (lookup)

Fetch (or create) a Bitwarden login item

Synopsis

  • Looks up a password item in Bitwarden by name (and optional username, folder, collection and organization), or directly by Bitwarden item ID.
  • If the lookup is by name and no matching item is found, a new login item is created on the fly. This makes the plugin idempotent for automation. The first run creates the secret, every subsequent run returns the same item.
  • If the lookup is by id and the item is not in the local cache, the plugin falls back to a single API call. If the ID still does not resolve, the plugin fails - IDs are never auto-created.
  • If a name-based search returns more than one match, the plugin fails because it cannot decide which item to use.
  • On success, the plugin returns the full Bitwarden item object. username and password are additionally lifted to the top level so they can be addressed without going through the login sub-dictionary.
  • When name is omitted, a title is generated automatically as hostname - purpose (e.g. dbserver - MariaDB) or just hostname when no purpose is given.
  • Generated passwords use Python's secrets module (cryptographically strong RNG), not the Bitwarden generator. This lifts the 128-character limit and allows arbitrary character sets, including hex.
  • Items are read from a local on-disk cache backed by bw serve. A cached bw sync is performed at most every 60 seconds, so consecutive lookups in the same play do not hammer the API.

Available since LFOps 1.0.0.

Requirements

  • Bitwarden CLI bw version v2022.9.0 or newer. See https://bitwarden.com/help/article/cli/ for installation instructions.
  • You must be logged in and unlocked (bw login followed by bw unlock), and have the local API running, e.g. bw serve --hostname 127.0.0.1 --port 8087. The plugin connects to 127.0.0.1:8087 by default.

Optional Parameters

collection_id

  • Bitwarden collection ID the item belongs to. Used both as a search filter and, if the item has to be created, as the target collection.
  • Type: String.

folder_id

  • Bitwarden folder ID the item belongs to. Used both as a search filter and, if the item has to be created, as the target folder.
  • Type: String.

hostname

  • Hostname the password belongs to. Used to generate the item name when name is not given.
  • Type: String.

id

  • Look up an existing item by its Bitwarden item ID. When set, all other search filters are ignored. The plugin fails if the ID does not exist (no auto-creation).
  • Type: String.

name

  • Explicit name/title of the item. When set, disables automatic name generation from hostname and purpose.
  • Type: String.

notes

  • Notes to set when the item is created. Bitwarden limits notes to 10000 characters. Existing items are not modified by this lookup.
  • Type: String.
  • Default: Generated by Ansible.

organization_id

  • Bitwarden organization ID the item belongs to. Used both as a search filter and, if the item has to be created, as the target organization.
  • Type: String.

password_choice

  • Character set used for generating new passwords. To produce a hex password, set this to '0123456789abcdef' and ensure password_length is even. Existing passwords are never regenerated.
  • Type: String.
  • Default: 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ

password_length

  • Length of the password generated when the item does not yet exist. Must be positive. When generating hex passwords (see password_choice), it must also be even, otherwise the lookup fails.
  • Type: Number.
  • Default: 60

purpose

  • What the password is for (e.g. MariaDB, Rocky). Combined with hostname to build the item name when name is not given.
  • Type: String.

uris

  • List of URIs to attach when the item is created. Has no effect on already existing items.
  • Type: List.

username

  • Username for the login item. Used both as a search filter and, if the item has to be created, as the login.username value.
  • Type: String.

Examples

- name: 'The normal way using this lookup plugin. Search for the Bitwarden item using hostname, purpose and username. If not found, creates a new item called `appsrv01 - MariaDB`. Returns the password item, including a `username` and a `password` subkey.'
  ansible.builtin.debug:
    msg: "{{ lookup('linuxfabrik.lfops.bitwarden_item',
        {
          'hostname': 'appsrv01',
          'purpose': 'MariaDB',
          'username': 'mariadb-monitoring',
        },
      ) }}"

- name: 'If only the password is required, use the following lookup.'
  ansible.builtin.debug:
    msg: "{{ lookup('linuxfabrik.lfops.bitwarden_item',
        {
          'hostname': 'appsrv01',
          'purpose': 'MariaDB',
          'username': 'mariadb-monitoring',
        },
      )['password'] }}"

- name: 'Lookup by name. If not found, creates the item `appsrv01 - MariaDB`.'
  ansible.builtin.debug:
    msg: "{{ lookup('linuxfabrik.lfops.bitwarden_item',
        {
          'hostname': 'appsrv01',
          'purpose': 'MariaDB',
        },
      ) }}"

- name: 'Lookup by ID'
  ansible.builtin.debug:
    msg: "{{ lookup('linuxfabrik.lfops.bitwarden_item',
        {
          'id': '9b527543-8335-41fb-b83f-8c35f4bd86e7',
        },
      ) }}"

- name: 'Lookup (all parameters), and - if needed - create a hex-based password (256 chars length = 128 bit hex)'
  ansible.builtin.debug:
    msg: "{{ lookup('linuxfabrik.lfops.bitwarden_item',
        {
          'hostname': 'appsrv74',
          'purpose': 'MariaDB',
          'username': 'mariadb-admin',
          'organization_id': '3334651d-8dd8-4221-bdb6-e4f8d695e7f1',
          'collection_id': '5d1d231a-4264-4b16-a0d3-324d168f210d',
          'password_length': 256,
          'password_choice': '01234567890abcdef',
          'notes': 'Please be careful.',
          'uris': [
            'https://www.example.com',
            'https://packages.example.com',
          ],
        },
      ) }}"

- name: 'Lookup multiple items at once'
  ansible.builtin.debug:
    msg: "{{ lookup('linuxfabrik.lfops.bitwarden_item',
        {
          'hostname': 'appsrv03',
          'purpose': 'MariaDB',
          'username': 'mariadb-admin',
          'organization_id': 'e4f526c4-b39d-4fa8-8645-d10373ee1f2d',
          'collection_id': '706793bc-4123-481d-a550-669f0b079ad6',
        },
        {
          'hostname': 'appsrv04',
          'purpose': 'MariaDB',
          'username': 'mariadb-admin',
          'organization_id': '832f727b-e666-4ae4-8c34-308dbbba7c99',
          'collection_id': '16ea112a-dd5f-4f68-9dfb-95a9f302a8a5',
        },
      ) }}"

Return Values

collectionIds

  • List of collection IDs in which the item is.
  • Type: List.
  • Returned: always.
  • Sample:

    yaml - 9f665810-549f-4b27-829c-93dab1e806e3

favorite

  • Whether the item is favorited or not.
  • Type: Bool.
  • Returned: always.
  • Sample: False

folderId

  • Bitwarden folder ID in which the item is.
  • Type: String.
  • Returned: always.
  • Sample: d27186d7-665a-4dde-bc4c-c0c824ca1207

id

  • Unique Bitwarden password item ID.
  • Type: String.
  • Returned: always.
  • Sample: 220c250a-302c-40d4-a5e1-fbb63a78b8d1

login

  • A Bitwarden login object (dictionary).
  • Type: Dictionary.
  • Returned: always.

name

  • Name/Title of the password item.
  • Type: String.
  • Returned: always.
  • Sample: appsrv01 - MariaDB

notes

  • Some notes about the cipher.
  • Type: String.
  • Returned: always.
  • Sample: Automatically generated by Ansible.

object

  • Type of the Bitwarden object. Always returns item.
  • Type: String.
  • Returned: always.
  • Sample: item

organizationId

  • The ID of the organization.
  • Type: String.
  • Returned: always.
  • Sample: e7d88250-5d1f-411c-b2f0-692c38da7b6f

password

  • The password. Same as under the login dict, but at a higher level for easier access.
  • Type: String.
  • Returned: always.
  • Sample: 6VuIkoKQmCl9Yyv3xpgjU6SF2ecs6k

reprompt

  • If Bitwarden should re-prompt for the master password when accessing this item.
  • Type: Number.
  • Returned: always.
  • Sample: 0

revisionDate

  • Date/Time the item was created or last modified.
  • Type: String.
  • Returned: always.
  • Sample: 2019-01-28T15:31:34.300Z

type

  • Bitwarden item type. Always 1 (login) for items handled by this plugin. Other Bitwarden types (2 secure note, 3 card, 4 identity) are filtered out and never returned.
  • Type: Number.
  • Returned: always.
  • Sample: 1

username

  • Username to which the password belongs. Same as under the login dict, but at a higher level for easier access.
  • Type: String.
  • Returned: always.
  • Sample: root

Notes

  • Only login items (Bitwarden type 1) are supported. Cards, secure notes and identities are ignored.
  • TOTP secrets are not managed; the totp field is set to an empty string on creation.
  • URIs on existing items are not edited by this lookup; they are only set at item creation time.
  • Organization, collection and folder IDs can be copied from the URL in the Bitwarden web vault.
  • The cache file lives in $XDG_RUNTIME_DIR (falling back to /tmp) and is shared across this plugin and the bitwarden_item module within the same controller session.

Authors

  • Linuxfabrik GmbH, Zurich, Switzerland, https://www.linuxfabrik.ch