go-cloud icon indicating copy to clipboard operation
go-cloud copied to clipboard

blob/azureblob: No way to refresh a user delegation credential when using OAuth client credentials token provider

Open praneetloke opened this issue 4 years ago • 4 comments

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 UserDelegationCredential to OpenBucket's options.credentials property:
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.

praneetloke avatar May 27 '21 06:05 praneetloke

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.

vangent avatar May 27 '21 18:05 vangent

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.

praneetloke avatar May 27 '21 20:05 praneetloke

I think this might be stale after #3156.

vangent avatar Aug 09 '22 20:08 vangent

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.TokenCredential interfaces, 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.

praneetloke avatar Aug 10 '22 01:08 praneetloke

Fixed by #3156.

vangent avatar Aug 10 '22 21:08 vangent