Skip to main content

Salt Extension Modules for Bitwarden

Project description

bitwarden

Salt Extension Modules for Bitwarden

Introduction

This extension for Salt enables Salt to access and administer a Bitwarden vault/instance.

This project aims to eventually have 100% coverage of the Bitwarden Vault Management API and the Bitwarden Public (Organization Management) API. This extension is changing quickly, and while attempts will be made to not make breaking changes, the current focus is on functionality rather than syntax/API stability.

Requirements

This extension requires the bw Bitwarden CLI utility to be installed for functions that depend on the Bitwarden Vault Management API. Installation instructions are available here. It also has dependencies on the pyhumps, requests, and validators python packages, which are automatically installed.

Installation

An example state file for installing and configuring this extension on EL8 (RHEL, AlmaLinux, Rocky Linux, Oracle Linux, Scientific Linux, etc.):

# Install the NodeSource EL8 repo to get Node.js
cmd_nodesource-el8.repo:
  cmd.run:
    - name: curl -fsSL https://rpm.nodesource.com/setup_18.x | bash -
    - creates:
        - /etc/yum.repos.d/nodesource-el8.repo

# Bitwarden CLI depends on Node.js
pkg_nodejs:
  pkg.installed:
    - name: nodejs
    - require:
        - cmd_nodesource-el8.repo

# Install the Bitwarden CLI client (which includes the Vault Management REST API
# server)
npm_bitwarden_cli:
  npm.installed:
    - name: '@bitwarden/cli'
    - require:
        - pkg_nodejs

# Install the Bitwarden Salt Extension
pip_saltext.bitwarden:
  pip.installed:
    - name: saltext.bitwarden
    - require:
        - npm_bitwarden_cli

# Configure server options for Bitwarden REST API Server
file_/etc/sysconfig/bw-api:
  file.managed:
    - name: /etc/sysconfig/bw-api
    - user: root
    - group: root
    - mode: "0644"
    - contents: |
        # Command-line options for bw serve
        BITWARDENCLI_APPDATA_DIR=/etc/salt/.bitwarden
        OPTIONS="--hostname localhost --port 8087"
    - require:
        - pip_saltext.bitwarden
    - watch_in:
        - service_bw-api

# Create a systemd service unit file since one is not included in the package.
# Reloads systemctl if the file changes.
file_/etc/systemd/system/bw-api.service:
  file.managed:
    - name: /etc/systemd/system/bw-api.service
    - user: root
    - group: root
    - mode: "0644"
    - contents: |
        [Unit]
        Description=Bitwarden Vault Management API
        Documentation=https://bitwarden.com/help/cli/
        After=network.target

        [Service]
        EnvironmentFile=-/etc/sysconfig/bw-api
        User=salt
        Group=salt
        Type=simple
        WorkingDirectory=~
        ExecStart=/bin/bw serve $OPTIONS
        Restart=always

        [Install]
        WantedBy=multi-user.target
    - require:
        - file_/etc/sysconfig/bw-api
    - watch_in:
        - service_bw-api

# You must manually create files in /etc/salt/master.d/bitwarden.conf or
# /etc/salt/minion.d/bitwarden.conf (or both) depending on the context, with the following contents
# (substituting values as appropriate):
#
#  bitwarden:
#    driver: bitwarden
#    cli_path: /bin/bw
#    cli_conf_dir: /etc/salt/.bitwarden
#    cli_runas: salt
#    vault_url: https://bitwarden.com
#    email: user@example.com
#    password: CorrectHorseBatteryStaple
#    vault_api_url: http://localhost:8087
#    public_api_url: https://api.bitwarden.com
#    client_id: 25fa6fc6-deeb-4b42-a279-5e680b51aa58
#    client_secret: AofieD0oexiex1mie3eigi9oojooF3
#    org_client_id: organization.d0e19db4-38aa-4284-be3d-e80cff306e6c
#    org_client_secret: aWMk2MBf4NWXfaevrKyxa3uqNXYVQy

# Used for runner and SDB modules
file_/etc/salt/master.d/bitwarden.conf:
  file.exists:
    - name: /etc/salt/master.d/bitwarden.conf
    - require:
        - pip_saltext.bitwarden

# Used for execution, SDB and state modules
file_/etc/salt/minion.d/bitwarden.conf:
  file.exists:
    - name: /etc/salt/minion.d/bitwarden.conf
    - require:
        - pip_saltext.bitwarden

# Make sure the Bitwarden vault is logged in before we start the REST API server
# service otherwise the service will refuse to start
bitwarden_logged_in:
  bitwarden.logged_in:
    - name: logged_in
    - use_cli: True
    - profile: bitwarden

# Run the Bitwarden Vault Management REST API server `bw serve`
service_bw-api:
  service.running:
    - name: bw-api
    - enable: True
    - init_delay: 10
    - require:
        - bitwarden_logged_in

# State to reload systemctl
service_systemctl_reload:
  module.run:
    - name: service.systemctl_reload
    - onchanges:
        - file_/etc/systemd/system/bw-api.service

# Use firewalld to protect the Bitwarden Vault Management REST API server
service_firewalld:
  service.running:
    - name: firewalld
    - enable: True
    - reload: True

# Lock down access to the Bitwarden Vault Management REST API to only the root user (uid 0) using
# firewalld because once the vault is unlocked, access is completely unauthenticated.
#
# See https://github.com/bitwarden/clients/issues/3932
#
# We directly manage the direct rules configuration file because the Salt firewalld state module
# doesn't support direct rules.
file_/etc/firewalld/direct.xml:
  file.managed:
    - name: /etc/firewalld/direct.xml
    - user: root
    - group: root
    - mode: "0644"
    - contents: |
        <?xml version="1.0" encoding="utf-8"?>
        <!--
        ########################################################################
        #                                                                      #
        #              THIS FILE IS MANAGED BY SALT - DO NOT EDIT              #
        #                                                                      #
        # The contents of this file are managed by Salt. Any changes to this   #
        # file may be overwritten automatically and without warning.           #
        ########################################################################
        -->
        <direct>
          <rule ipv="ipv4" table="filter" chain="OUTPUT" priority="0">-o lo -p tcp --dport 8087 -m owner --uid-owner root -j ACCEPT</rule>
          <rule ipv="ipv4" table="filter" chain="OUTPUT" priority="0">-o lo -p tcp --dport 8087 -m owner --uid-owner salt -j ACCEPT</rule>
          <rule ipv="ipv4" table="filter" chain="OUTPUT" priority="1">-o lo -p tcp --dport 8087 -j REJECT</rule>
          <rule ipv="ipv6" table="filter" chain="OUTPUT" priority="0">-o lo -p tcp --dport 8087 -m owner --uid-owner root -j ACCEPT</rule>
          <rule ipv="ipv6" table="filter" chain="OUTPUT" priority="0">-o lo -p tcp --dport 8087 -m owner --uid-owner salt -j ACCEPT</rule>
          <rule ipv="ipv6" table="filter" chain="OUTPUT" priority="1">-o lo -p tcp --dport 8087 -j REJECT</rule>
        </direct>
    - watch_in:
        - service_firewalld

The configuration files required vary depending on which module you wish to use:

module type file type
execution minion
runner master
sdb master, minion
state minion

Usage

This extension currently provides only read-only access to Bitwarden vaults using the sdb module, with other modules primarily for vault management such as logging in and unlocking the vault.

# SDB via runner module
salt-run sdb.get 'sdb://bitwarden/by-uuid/2fcd790a-70f7-43a2-b265-08a763873980/password'
CorrectHorseBatteryStaple
# SDB via execution module
salt-call sdb.get 'sdb://bitwarden/by-uuid/2fcd790a-70f7-43a2-b265-08a763873980/password'
local:
    CorrectHorseBatteryStaple

As always, you can also reference SDB modules in your pillar files:

example_pillar:
  some_password: {{ salt['sdb.get']('sdb://bitwarden/by-uuid/2fcd790a-70f7-43a2-b265-08a763873980/password') }}

The format of the SDB URI is as follows:

sdb://<profile>/by-uuid/<uuid>/<object>

Where <profile> is the profile defined in the master or minion configuration file, <uuid> is the UUID of the item, and <object> is one of:

  • name
  • username
  • password
  • totp
  • notes
  • creation_date
  • revision_date
  • deleted_date
  • password_revision_date

Additionally, password history can be retrieved with the following SDB URI format:

sdb://<profile>/by-uuid/<uuid>/password_history/by-index/<index>

Where <profile> is the profile defined in the master or minion configuration file, <uuid> is the UUID of the item, and index is a non-negative integer specifying which password to retrieve from the history (0 being the current password, 1 being the previous password, and so forth).

Lastly, custom fields can be retrieved with the following SDB URI format:

sdb://<profile>/by-uuid/<uuid>/fields/by-name/<field_name>/<object>

Where <profile> is the profile defined in the master or minion configuration file, <uuid> is the UUID of the item, <field_name> is the name of custom field, and object is one of:

  • value
  • type
  • linked_id

Note that the custom field name must be unique within an item. Bitwarden does not enforce unique custom field names, so that is left up to the user.

The UUID of an item can be found using the Bitwarden CLI:

bw list items --search "Google Account" --pretty
[
  {
    "object": "item",
    "id": "2fa63ad5-e4e4-43d4-a089-3fadcf455be2",
    "organizationId": null,
    "folderId": null,
    "type": 1,
    "reprompt": 0,
    "name": "Google Account",
    "notes": null,
    "favorite": false,
    "login": {
      "uris": [
        {
          "match": null,
          "uri": "https://accounts.google.com"
        }
      ],
      "username": "user@example.com",
      "password": "aTjSsJvhQY5E24",
      "totp": "AEM1HEESIEV8YAED8THUBEHOOW",
      "passwordRevisionDate": null
    },
    "collectionIds": [],
    "revisionDate": "1970-01-01T00:00:00.000Z"
  }
]

Docs

Module documentation is available at https://ggiesen.gitlab.io/salt-ext-bitwarden.

Bugs

Bugs can be reported using the Issue Tracker.

Contributing

All contributions are welcome and very much appreciated. Contributing guide coming soon. Contributing can take many forms, including:

  • Reporting bugs
  • Feature requests
  • Code submissions (bug fixes/new features/improve code quality)
  • Writing tests
  • Writing documentation
  • Detailing use cases
  • Writing blog posts

License

This project is licensed under the Apache Software License. See LICENSE for the licence text.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

saltext.bitwarden-0.0.1b15.tar.gz (28.3 kB view hashes)

Uploaded Source

Built Distribution

saltext.bitwarden-0.0.1b15-py2.py3-none-any.whl (32.9 kB view hashes)

Uploaded Python 2 Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page