This is a personal unofficial project. I have no affiliation with Bitwarden. Use at your own risk. Issues and feedback are welcome.
Python wrapper for Bitwarden Secrets Manager CLI
This module contains the BWS class, which is a Python wrapper for the bws CLI application. The BWS class allows users to retrieve secrets stored in a Bitwarden Secrets Manager project. The module uses subprocess to call the bws CLI. The bws CLI application (v.0.4.0+) must be downloaded separately and already present on your system (ideally in a PATH directory).
You must also have a Bitwarden Secrets Manager account with an existing project, secret(s) and machine account.
- Activate your environment of choice.
- Download bitwarden_secrets_manager_python.
- Navigate to the folder containing
pyproject.tomland runpip install ./
from bitwarden_secrets_manager_python import BWS
Optionally use logging to see useful information, especially if using in a Jupyter Notebook or troubleshooting. Secrets and keys will not be logged.
logging.basicConfig(format='%(message)s', level=logging.INFO)
Initialize a BWS object with:
- The project name as it appears in Bitwarden Secrets Manager.
- If the BWS_ACCESS_TOKEN environment variable has not been set in your environment, provide the token as a string.
- Your machine account that your access token is for must have at least
Readaccess to your project (allowing get-like operations only).Read and writeaccess is necessary to use functionality that adds, updates, or deletes secrets.
- Your machine account that your access token is for must have at least
- By default, the class uses the
bwsorbws.exeapplication found in aPATHdirectory, but a direct path to the application can also be supplied. - Note: your project must already exist and contain at least one secret, otherwise initialization will fail.
- Another note: your project cannot have any duplicate key names. Although Bitwarden Secrets Manager does support duplicate key names (and keys instead by
id), theBWSclass mostly abstracts theidfield for ease of use, keying on the key name (key) instead. This class will not allow creation of duplicate key names when using its CRUD interfaces. Be careful not to break compatibility by adding duplicate key names via the CLI, web interface, or other tools.
Example if bws is not in your PATH and a token is not set as an environment variable:
my_bws = BWS(project_name='my_project_name', bws_access_token='my_token', bws_path='path/to/bws')Example if bws is in your PATH and a token is set as an environment variable:
my_bws = BWS(project_name='my_project_name')Note that each BWS object corresponds to a single project and service account. If you have multiple projects and/or service accounts to access, create separate BWS objects for each one.
Upon initialization, all of the secrets in the given project are cached in the BWS instance. After initialization, get-like operations will read from the cache. Adds, updates, and deletes will update in your Bitwarden Secrets Manager account and incrementally update the cache, keeping the cache and online account in sync without unnecessary traffic. Out-of-bound changes to secrets made after initialization will not be reflected in the cache unless refresh_secrets_cache() is called on the instance.
Get a secret value:
secret_value = my_bws['secret_key']
# or
secret_value = my_bws.get_secret('secret_key')['value']
# or
secret_value = my_bws.get_secret('secret_key', value_only=True)Add a secret:
my_bws['secret_key'] = 'secret_value' # same as updating
# or
my_bws.add_secret('secret_key', 'secret_value')Update a secret:
my_bws['secret_key'] = 'secret_value' # same as adding
# or
my_bws.update_secret_value('secret_key', 'secret_value')Delete a secret:
del my_bws['secret_key']
# or
my_bws.delete_secret('secret_key')Get all secrets as a dictionary keyed by key:
my_bws.as_dict()Get all secrets as a list of tuples:
my_bws.items()Get number of secrets:
len(my_bws)Check if a secret exists:
'secret_key' in my_bwsOther arbitrary calls to BWS CLI using your access token (but not your project name):
my_bws.call_and_return_text(cl_args=['project', 'get', bws.PROJECT_ID], print_to_console=True, as_json=True)# use for making sure the CLI is working
my_bws.help()
my_bws.version()See bws.py for more information.