Hello,
We are using a containerized python tool to automate some collection management stuff, and it suddenly stopped working. The code looks like that :
from oauthlib.oauth2 import BackendApplicationClient
from requests_oauthlib import OAuth2Session
from atolcd import config
class Bitwarden:
def __init__(self):
self.organization_id=config.get('bitwarden', 'organization_id')
self.client_id='organization.' + self.organization_id
self.client_secret=config.get('bitwarden', 'client_secret')
# these 3 lines are tasked to retrieve secrets from a local config files. Works just fine, the value is properly retrieved and up to date.
oauthclient = BackendApplicationClient(client_id=self.client_id)
self.client=OAuth2Session(client=oauthclient)
self.client.fetch_token(token_url='https://identity.bitwarden.com/connect/token', client_id=self.client_id, client_secret=self.client_secret, include_client_id=True)
As of today, when executing this, it fails on the last line, with the following stacktrace :
File "/usr/local/lib/python3.11/site-packages/atolcd/bitwarden.py", line 21, in __init__
self.client.fetch_token(token_url='https://identity.bitwarden.com/connect/token', client_id=self.client_id, client_secret=self.client_secret, include_client_id=True)
File "/usr/local/lib/python3.11/site-packages/requests_oauthlib/oauth2_session.py", line 366, in fetch_token
self._client.parse_request_body_response(r.text, scope=self.scope)
File "/usr/local/lib/python3.11/site-packages/oauthlib/oauth2/rfc6749/clients/base.py", line 427, in parse_request_body_response
self.token = parse_token_response(body, scope=scope)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/oauthlib/oauth2/rfc6749/parameters.py", line 441, in parse_token_response
validate_token_parameters(params)
File "/usr/local/lib/python3.11/site-packages/oauthlib/oauth2/rfc6749/parameters.py", line 451, in validate_token_parameters
raise MissingTokenError(description="Missing access token parameter.")
oauthlib.oauth2.rfc6749.errors.MissingTokenError: (missing_token) Missing access token parameter.
I thought of a change in Bitwarden’s Public API authentication workflow, but it doesn’t seem so. Going through the doc’s CURL call with our own client_id/_secret works just fine. I’m a perfect noob in terms of OAuth and stuff, but from what I understand, the token is delivered for requests with :
- valid
client_id
andclient_secret
(as we saw, it is) - grant_type is
client_credentials
(turns out it is implemented by thisBackendApplicationClient
thingy in python’s oauthlib) - scope is
scope=api.organization
==> this might be the missing bit here.
If I understand correctly, the Missing access token parameter
simply states that the API’s answer don’t contain the expected field. This is probably due to the API answering 401 unauthorized or something like that. Since I’m using valid client values and apparently valid grant_type
, the only thing I’m not explicitly specifying is the scope.
However, removing the scope from the working CURL request does not result in a fail call, the access token is properly sent back. Plus, we never had to specify the scope so far, and the API doc hasnt change for a while now.
What am I missing ?
PS : apologies for the “app:cli” tag, I’m obviously not using the CLI here, but Discourse want me to add at least two tags, and it doesnt seem to have an API tag that I could use.