Skip to content

[Storage] Create Session Support for GET Requests#47264

Open
weirongw23-msft wants to merge 22 commits into
Azure:mainfrom
weirongw23-msft:weirongw23/sessions-private
Open

[Storage] Create Session Support for GET Requests#47264
weirongw23-msft wants to merge 22 commits into
Azure:mainfrom
weirongw23-msft:weirongw23/sessions-private

Conversation

@weirongw23-msft
Copy link
Copy Markdown
Member

No description provided.

@weirongw23-msft weirongw23-msft marked this pull request as ready for review June 1, 2026 16:44
Copilot AI review requested due to automatic review settings June 1, 2026 16:44
@github-actions github-actions Bot added the Storage Storage Service (Queues, Blobs, Files) label Jun 1, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces opt-in “session-based” authentication for eligible GET blob requests (notably downloads) by adding a pipeline policy that can acquire/cache a short-lived session credential per container and use it to sign subsequent GET requests. It also adds the generated CreateSession REST operation/models and a new recorded test covering session behavior.

Changes:

  • Added StorageSessionPolicy + container-scoped session cache, and plumbed use_session=True into the sync pipeline creation path.
  • Added generated create_session operation + models/enums to support the service’s session creation API.
  • Added a recorded test and updated proxy sanitizers for session credentials.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
sdk/storage/azure-storage-blob/azure/storage/blob/_shared/policies.py Adds sync session auth policy + cache and request signing logic.
sdk/storage/azure-storage-blob/azure/storage/blob/_shared/base_client.py Adds use_session kwarg handling and wires StorageSessionPolicy into the sync pipeline.
sdk/storage/azure-storage-blob/azure/storage/blob/_shared/policies_async.py Introduces an async session policy stub (currently unimplemented).
sdk/storage/azure-storage-blob/azure/storage/blob/_generated/operations/_container_operations.py Adds generated create_session request builder + operation.
sdk/storage/azure-storage-blob/azure/storage/blob/_generated/aio/operations/_container_operations.py Adds generated async create_session operation.
sdk/storage/azure-storage-blob/azure/storage/blob/_generated/models/_models_py3.py Adds generated session models: CreateSessionConfiguration, CreateSessionResponse, SessionCredentials.
sdk/storage/azure-storage-blob/azure/storage/blob/_generated/models/_azure_blob_storage_enums.py Adds generated enum AuthenticationType.
sdk/storage/azure-storage-blob/azure/storage/blob/_generated/models/init.py Re-exports new generated models/enums.
sdk/storage/azure-storage-blob/azure/apiview-properties.json Updates API view surface list for new types/ops.
sdk/storage/azure-storage-blob/tests/conftest.py Adds test-proxy sanitizers for session token/key.
sdk/storage/azure-storage-blob/tests/test_container.py Adds recorded test validating bearer-vs-session auth behavior and per-container session usage.
sdk/storage/azure-storage-blob/CHANGELOG.md Documents the new opt-in session authentication feature.

Comment thread sdk/storage/azure-storage-blob/azure/storage/blob/_shared/policies.py Outdated
Comment thread sdk/storage/azure-storage-blob/tests/conftest.py Outdated

assert session1 != session2

c1b1_actual = container1.download_blob(c1b1_name, raw_response_hook=make_capture("c1_download")).readall()
Comment thread sdk/storage/azure-storage-blob/tests/test_container.py Outdated
Comment thread sdk/storage/azure-storage-blob/azure/storage/blob/_shared/policies_async.py Outdated
Comment thread sdk/storage/azure-storage-blob/CHANGELOG.md
Copy link
Copy Markdown
Member

@jalauzon-msft jalauzon-msft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments on the sync policy itself, did not look at much else yet

if http_request.method != "GET":
return False
parsed = urlparse(http_request.url)
segments = [s for s in parsed.path.split("/") if s]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is more of a meta point for URL parsing in the PR as a whole but I'm leaving here as an example. Azurite/emulators use URLs like 127.0.0.1/account/container which would break all the container parsing logic. Not sure if we care about that (probably eventually we will need to)

Comment thread sdk/storage/azure-storage-blob/azure/storage/blob/_shared/policies.py Outdated
Comment thread sdk/storage/azure-storage-blob/azure/storage/blob/_shared/policies.py Outdated
return response # bearer was used; nothing session-related to react to

status = response.http_response.status_code
error_code = response.http_response.headers.get("x-ms-error-code", "")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think response might have the error code already parsed?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't seem like there's a dedicated error_code property on response.http_response itself, but it's in the headers.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about response itself?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I didn't see any attributes in response that has any error codes.

Comment thread sdk/storage/azure-storage-blob/azure/storage/blob/_shared/policies.py Outdated
Comment thread sdk/storage/azure-storage-blob/azure/storage/blob/_shared/policies.py Outdated
Comment thread sdk/storage/azure-storage-blob/azure/storage/blob/_shared/policies.py Outdated
Comment thread sdk/storage/azure-storage-blob/azure/storage/blob/_shared/policies.py Outdated
Comment thread sdk/storage/azure-storage-blob/azure/storage/blob/_shared/policies.py Outdated
Comment thread sdk/storage/azure-storage-blob/azure/storage/blob/_shared/base_client.py Outdated

_, session_pipeline = self._create_pipeline(credential, sdk_moniker=self._sdk_moniker, **sub_kwargs)
generated = AzureBlobStorage(container_url, self.api_version, base_url=container_url)
generated._client._pipeline = session_pipeline # pylint: disable=protected-access
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The constructor of AzureBlobStorage can take a pipeline instead of doing it this way.

StorageSessionPolicy(
account_name=self.account_name,
session_client_factory=_session_client_factory,
use_session=True,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is always passed as True? That probably means we don't need it in the policy and if the policy is present, it does its thing?

Comment thread sdk/storage/azure-storage-blob/azure/storage/blob/_shared/policies.py Outdated
return response # bearer was used; nothing session-related to react to

status = response.http_response.status_code
error_code = response.http_response.headers.get("x-ms-error-code", "")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about response itself?

Comment thread sdk/storage/azure-storage-blob/tests/test_container.py Outdated
captured = {}

def make_capture(label):
def _hook(response):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why hook inside a hook? You shouldn't need that. You may need to declare captured as nonlocal here though.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a way for the hook to distinguish between requests we're making. For example, an upload should use bearer token and download might use sessions. The label helps distinguish that. We still make the checks through captured[label]. I don't think we have to make it nonlocal if we are mutating captured in place.

Comment thread sdk/storage/azure-storage-blob/tests/test_container.py Outdated
for p in getattr(pipeline, "_impl_policies", []):
if type(p).__name__ == "StorageSessionPolicy":
return p
raise AssertionError("StorageSessionPolicy not found on the pipeline")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these inline functions could be helpers, so they aren't duplicated? Even could be shared across sync and async. With the exception of maybe make_capture since it needs a local... but maybe there is something for that too.

assert auth.startswith("Session ")
return auth[len("Session ") :].split(":", 1)[0]

def find_session_policy(pipeline):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pretty jank, but I'll allow it for now :D

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:D :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Storage Storage Service (Queues, Blobs, Files)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants