Skip to content

Conversation

@jensens
Copy link
Contributor

@jensens jensens commented Sep 17, 2025

The session credentials file (IAM authentication file for the Google Service Account) was static. Thus we were not able to serve multiple clients within one usage of this library. For security reason one should use for each environment a different Service Account.

To get dynamic credential-data a new protocol CredentialProvider was introduced using the same plugin mechanism as already known from the image handler and pass data provider. Any integration now can provide such an provider and lookup a credential file by issuer_id.

If there is no provider configured, fall back to fetch credentials from settings.

Additional we provide a method to directly pass the credentials (as parsed dictionary) to the API methods (api.py). If passed in, provider an fallback are bypassed.

The session was refactored to reflect this. Since we use AuthorizedSession each issuer now gets its own session per thread. Integrators need to take care to not explode the number of sessions.

@jensens
Copy link
Contributor Author

jensens commented Sep 17, 2025

TODO:

  • write test for plugin CredentialProvider mechanism and for .session.SessionManager._credentials_for_issuer
  • check overage for more places to add tests if needed

@jensens jensens force-pushed the multi-issuer-dynamic-credentials branch from d249c85 to 198b0f0 Compare September 17, 2025 17:23
@rnixx
Copy link
Contributor

rnixx commented Sep 19, 2025

@zworkb @loechel please add your review

@rnixx
Copy link
Contributor

rnixx commented Sep 26, 2025

There was an error in save_link which was not easy to fix. We use this package in an async environment and delegate the API calls to a thread executor to avoid blocking. Turns out, using the sync dynamic settings plugin, there is no clean way hooking back up to the async world to fetch the credentials (which is required in our case). To avoid ugly hacks, the API has been extended to accept the parsed credentials as dict. This makes the dynamic settings plugin obsolete for now, at least in our environment.

Next, the dynamic plugin looks up the credentials by issuer id, which is fine as long as the system is set up to use a dedicated service account for each issuer id. Technically, a service account can be used to create passes for multiple issuers. If we want to keep the dynamic settings plugin as is, we have to add a description about it's restrictions to the documentation. The second case described is provided by passing the credentials file to the API calls.

For our major issue, the lack of async support, the API must be extended by async versions of all API calls. The google auth package provides an experimental aiohttp based implementation, which is subordinate due to the lack of HTTP2 support. There exists a pull request with a httpx based implementation here googleapis/google-auth-library-python#1255 . A possible solution may be to integrate the code from the PR in this package, as it not seems that there is much progress on the issue. But this is out of scope for me right now.

@jensens jensens force-pushed the multi-issuer-dynamic-credentials branch from 850d178 to 9f46fae Compare September 26, 2025 08:54
…load the credentials every time a session is requested. so functools caches are used here.
@rnixx
Copy link
Contributor

rnixx commented Sep 30, 2025

Close in favor of #58

@rnixx rnixx closed this Sep 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants