Caching and expiry in DPoP token provider - #30
Merged
Merged
Conversation
langsamu
commented
Aug 19, 2026
| import type { TokenProvider } from "./TokenProvider.js" | ||
| import type { GetIssuerCallback } from "./GetIssuerCallback.js" | ||
|
|
||
| type CacheEntry = { created: number, tokenResult: oauth.TokenEndpointResponse, dpopKey: CryptoKeyPair } |
Collaborator
Author
There was a problem hiding this comment.
Locally represents what we cache.
Will move out of here once cache also moves out.
| return new Request(request, {headers}) | ||
| } | ||
|
|
||
| private async obtainToken(request: Request): Promise<CacheEntry> { |
Collaborator
Author
There was a problem hiding this comment.
All upgrade logic except caching is unchanged in this extracted method.
| headers.set("Authorization", ["DPoP", tokenResult.access_token].join(" ")) | ||
|
|
||
| return new Request(request, {headers}) | ||
| return {created: Date.now(), tokenResult, dpopKey} |
Collaborator
Author
There was a problem hiding this comment.
In the newly extracted method we don't actually upgrade the request.
That has moved to 32-37 above.
jeswr
reviewed
Aug 20, 2026
|
|
||
| async upgrade(request: Request): Promise<Request> { | ||
| let tokenData = this.#cache.get(request.url) | ||
| if (tokenData === undefined || isExpired(tokenData)) { |
Contributor
There was a problem hiding this comment.
Suggested change
| if (tokenData === undefined || isExpired(tokenData)) { | |
| // TODO: Support proactive refreshing as well | |
| if (tokenData === undefined || isExpired(tokenData)) { |
jeswr
reviewed
Aug 20, 2026
| } | ||
|
|
||
| async upgrade(request: Request): Promise<Request> { | ||
| let tokenData = this.#cache.get(request.url) |
Contributor
There was a problem hiding this comment.
The request url is not necessarily the right cache key. I'd suggest a callback to map from request to key.
For instance, we will often want this token to be shareable across all URLs in one or multiple storages.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This change adds initial token caching functionality to the DPoP token provider: Access tokens will be cached locally until they expire.
The resulting current functionality is that the second fetch to a given URI will only issue the unauthenticated original request and the upgraded request. UI, disco, dynreg are bypassed.
All requests with the same request URI get the same cached token. DPoP proofs are still calculated anew per request.
In a future change I will expose the cache in the provider constructor so it can be supplied and managed by the caller. But here it's private to the provider instance.
Later I will also want to add some headroom to the expiry calculation. A few seconds to account for the time it takes for requests to travel.
Also will need to think more carefully about token responses that lack expiry. This is likely to involve changes to the reactive authentication algorithm itself rather than this provider.