go-cloud
go-cloud copied to clipboard
blob/azureblob: No way to refresh a user delegation credential when using OAuth client credentials token provider
Is your feature request related to a problem? Please describe.
Yes it is.
With #2681 the ability to specify a UserDelegationCredential for the credential property. However, there is no way to refresh that key. User delegation keys have a maximum expiration time of 7 days (see Expiry request property in docs).
Describe the solution you'd like
I am looking for a way to pass a "user delegation refresher" func similar to how a token refresher func can be passed to NewTokenCredential (a feature of the azure-storage-blob-go SDK). Basically, some way for the SignedURL to refresh the user delegation credential and only if the credential it has is of that type. It's not applicable for a shared key credential.
Describe alternatives you've considered
N/A
Additional context
- Generate a user delegation key according to https://docs.microsoft.com/en-us/rest/api/storageservices/get-user-delegation-key
- Then provide the
UserDelegationCredentialtoOpenBucket'soptions.credentialsproperty:
b, err := azureblob.OpenBucket(ctx, pipeline, accountName, containerName, azureblob.Options{
// this will become stale after its expiration time and a long-running service will not be able to generate signed URLs after that
credential: myUserDelegationCredential
})
By contrast, if the auth mechanism used is MSI, then SignedURL does have a refresh mechanism for that.
TBH I'm not sure how to do this. If you have an idea, send a PR.
An alternative might be to recreate your Bucket periodically (e.g., every hour or so), giving it a new user delegation key.
An alternative might be to recreate your Bucket periodically (e.g., every hour or so), giving it a new user delegation key.
Yeah this is what I was thinking as a workaround. But not sure that would work well in practice even as a workaround. I'll try send a PR for this.
I think this might be stale after #3156.
I think so too. It seems that the Azure SDK for Go accepts an implementation of the TokenCredential interface. Also stated in the azblob package doc file:
The clients support different forms of authentication. The azblob library supports any of the
azcore.TokenCredentialinterfaces, authorization via a Connection String, or authorization with a Shared Access Signature token.
If a user constructs a ServiceClient using Azure SDK's NewServiceClient (which accepts a TokenCredential object) and passes that to Go Cloud's OpenBucket, then it should work since the client calls GetToken on the implementation. So it might be possible for a user to provide an implementation of a user delegation key requestor that can maintain an internal state of the token with expiration and therefore handle expiration themselves.
Note: My investigation in this comment was done in a browser looking at the changes #3156 and also referencing the Azure SDK for Go repo, so please excuse me if I overlooked something and also take what I said with caution.
Fixed by #3156.