Skip to content

Commit d94a783

Browse files
committed
v1.0.0
- interface changes will break any existing implementations - black formatting - add full CRUD support for secrets within a project - add ability to access secrets fields other than values - specify that at least one secret is required to already exist in a project - specify and enforce that project cannot have duplicate key names - improve organization, type hinting, and docs - update readme - fix passing stderr through to logging and exceptions - update to newest CLI syntax - other minor changes
1 parent 6894f03 commit d94a783

4 files changed

Lines changed: 1027 additions & 83 deletions

File tree

README.md

Lines changed: 74 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,23 @@
22
This is a personal **unofficial** project. I have no affiliation with Bitwarden. Use at your own risk. Issues and feedback are welcome.
33

44
# Python wrapper for [Bitwarden Secrets Manager](https://bitwarden.com/help/secrets-manager-overview/) CLI
5-
This module contains the `BWS` class, which is a Python wrapper for the `bws` [CLI application](https://bitwarden.com/help/secrets-manager-cli/). The 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 must be [downloaded separately](https://github.com/bitwarden/sdk/releases) and already present on your system (ideally in a `PATH` directory).
5+
This module contains the `BWS` class, which is a Python wrapper for the `bws` [CLI application](https://bitwarden.com/help/secrets-manager-cli/). 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](https://github.com/bitwarden/sdk/releases) and already present on your system (ideally in a `PATH` directory).
66

7-
You must also have opted-in to the Bitwarden Secrets Manager beta and have generated a project, secret(s) and service account.
7+
You must also have a Bitwarden Secrets Manager account with an existing project, secret(s) and machine account.
88

99
# How to use the `BWS` class
1010

1111
## Install
1212
1. Activate your environment of choice.
13-
2. Download [bws_python](https://github.com/jdhalbert/bitwarden_secrets_manager_python/releases).
13+
2. Download [bitwarden_secrets_manager_python](https://github.com/jdhalbert/bitwarden_secrets_manager_python/releases).
1414
3. Navigate to the folder containing `pyproject.toml` and run `pip install ./`
1515

1616
## Import
1717
```
18-
from bws_python import BWS
18+
from bitwarden_secrets_manager_python import BWS
1919
```
2020

21-
Optionally use `logging` to see useful information, especially if using in a Jupyter Notebook or troubleshooting:
21+
Optionally use `logging` to see useful information, especially if using in a Jupyter Notebook or troubleshooting. Secrets and keys will not be logged.
2222
```import logging
2323
logging.basicConfig(format='%(message)s', level=logging.INFO)
2424
```
@@ -27,26 +27,88 @@ logging.basicConfig(format='%(message)s', level=logging.INFO)
2727
Initialize a `BWS` object with:
2828
- The project name as it appears in Bitwarden Secrets Manager.
2929
- If the BWS_ACCESS_TOKEN environment variable has not been set in your environment, provide the token as a string.
30+
- Your machine account that your access token is for must have at least `Read` access to your project (allowing get-like operations only). `Read and write` access is necessary to use functionality that adds, updates, or deletes secrets.
3031
- By default, the class uses the `bws` or `bws.exe` application found in a `PATH` directory, but a direct path to the application can also be supplied.
32+
- **Note: your project must already exist and contain at least one secret, otherwise initialization will fail.**
33+
- **Another note: your project *cannot* have any duplicate key names.** Although Bitwarden Secrets Manager does support duplicate key names (and keys instead by `id`), the `BWS` class mostly abstracts the `id` field 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.
3134

3235
Example if `bws` is not in your `PATH` and a token is not set as an environment variable:
33-
```
36+
```python
3437
my_bws = BWS(project_name='my_project_name', bws_access_token='my_token', bws_path='path/to/bws')
3538
```
3639

3740
Example if `bws` is in your `PATH` and a token is set as an environment variable:
38-
```
41+
```python
3942
my_bws = BWS(project_name='my_project_name')
4043
```
4144

4245
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.
4346

44-
## Accessing individual secrets
45-
Access secrets from the BWS object as a key/value dictionary.
47+
### Note on Caching Behavior
48+
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.
49+
50+
## Interacting with secrets
51+
Get a secret value:
52+
```python
53+
secret_value = my_bws['secret_key']
54+
# or
55+
secret_value = my_bws.get_secret('secret_key')['value']
56+
# or
57+
secret_value = my_bws.get_secret('secret_key', value_only=True)
4658
```
47-
secret_value = my_bws['key']
48-
all_secrets = my_bws.items()
59+
60+
Add a secret:
61+
```python
62+
my_bws['secret_key'] = 'secret_value' # same as updating
63+
# or
64+
my_bws.add_secret('secret_key', 'secret_value')
65+
```
66+
67+
Update a secret:
68+
```python
69+
my_bws['secret_key'] = 'secret_value' # same as adding
70+
# or
71+
my_bws.update_secret_value('secret_key', 'secret_value')
72+
```
73+
74+
Delete a secret:
75+
```python
76+
del my_bws['secret_key']
77+
# or
78+
my_bws.delete_secret('secret_key')
79+
```
80+
81+
Get all secrets as a dictionary keyed by `key`:
82+
```python
83+
my_bws.as_dict()
84+
```
85+
86+
Get all secrets as a list of tuples:
87+
```python
88+
my_bws.items()
89+
```
90+
91+
Get number of secrets:
92+
```python
93+
len(my_bws)
94+
```
95+
96+
Check if a secret exists:
97+
```python
98+
'secret_key' in my_bws
99+
```
100+
101+
Other arbitrary calls to BWS CLI using your access token (but not your project name):
102+
```python
103+
my_bws.call_and_return_text(cl_args=['project', 'get', bws.PROJECT_ID], print_to_console=True, as_json=True)
49104
```
50105

51106
## Other functions
52-
See docstrings in `bws.py` for other functionality.
107+
108+
```python
109+
# use for making sure the CLI is working
110+
my_bws.help()
111+
my_bws.version()
112+
```
113+
114+
See `bws.py` for more information.

0 commit comments

Comments
 (0)