Which service(blob, file, queue, table) does this issue concern?
Blob
Which version of the Azurite was used?
main at 1436cad (after #2749, unreleased). 3.37.0 does not implement Put Blob From URL yet.
What problem was encountered?
Azure accepts x-ms-copy-source-authorization: Bearer <token> to authorize the source of Put Blob From URL, Copy Blob From URL and Put Block From URL. Microsoft's docs say: "Only a bearer scheme is supported for Microsoft Entra." Within one account this is the way to authorize the source under Entra ID. A request signed with Shared Key does not authorize its source on the real service; the Azure SDK's recorded live responses show 401 CannotVerifyCopySource until the source is authorized.
Azurite never reads the header. The generated layer parses it (specifications.ts), but no handler code uses it. BlockBlobHandler.readCopySource fetches the source over loopback with only the source URL's path and query, host, accept-encoding and the source-condition headers. A SAS on the source URL is therefore checked, while a bearer token in x-ms-copy-source-authorization is dropped. A source in a private container is then refused with 403 AuthorizationFailure, surfacing as CannotVerifyCopySource, even with --oauth basic and a token Azurite would accept on the destination request.
Steps to reproduce the issue?
- Start Azurite from
main with --oauth basic over HTTPS.
- Upload a blob
src to a private container using a bearer token.
- Send
PUT /<container>/dst with x-ms-copy-source: https://…/<container>/src (no SAS), x-ms-copy-source-authorization: Bearer <same token>, Authorization: Bearer <same token>, x-ms-blob-type: BlockBlob and Content-Length: 0.
Expected: 201, as on Azure. Actual (read from the code, not run): 403 CannotVerifyCopySource.
Have you found a mitigation/solution?
Put a SAS on the source URL instead. Under Entra ID alone, that means an extra Get User Delegation Key request per copy. A fix could forward the bearer token from x-ms-copy-source-authorization as the Authorization header of the loopback source read, so that the normal OAuth path authenticates it.
Which service(blob, file, queue, table) does this issue concern?
Blob
Which version of the Azurite was used?
mainat1436cad(after #2749, unreleased). 3.37.0 does not implement Put Blob From URL yet.What problem was encountered?
Azure accepts
x-ms-copy-source-authorization: Bearer <token>to authorize the source of Put Blob From URL, Copy Blob From URL and Put Block From URL. Microsoft's docs say: "Only a bearer scheme is supported for Microsoft Entra." Within one account this is the way to authorize the source under Entra ID. A request signed with Shared Key does not authorize its source on the real service; the Azure SDK's recorded live responses show401 CannotVerifyCopySourceuntil the source is authorized.Azurite never reads the header. The generated layer parses it (
specifications.ts), but no handler code uses it.BlockBlobHandler.readCopySourcefetches the source over loopback with only the source URL's path and query,host,accept-encodingand the source-condition headers. A SAS on the source URL is therefore checked, while a bearer token inx-ms-copy-source-authorizationis dropped. A source in a private container is then refused with403 AuthorizationFailure, surfacing asCannotVerifyCopySource, even with--oauth basicand a token Azurite would accept on the destination request.Steps to reproduce the issue?
mainwith--oauth basicover HTTPS.srcto a private container using a bearer token.PUT /<container>/dstwithx-ms-copy-source: https://…/<container>/src(no SAS),x-ms-copy-source-authorization: Bearer <same token>,Authorization: Bearer <same token>,x-ms-blob-type: BlockBlobandContent-Length: 0.Expected:
201, as on Azure. Actual (read from the code, not run):403 CannotVerifyCopySource.Have you found a mitigation/solution?
Put a SAS on the source URL instead. Under Entra ID alone, that means an extra Get User Delegation Key request per copy. A fix could forward the bearer token from
x-ms-copy-source-authorizationas theAuthorizationheader of the loopback source read, so that the normal OAuth path authenticates it.