feat: enforce scoped ADLS SAS authorization - #158
Conversation
|
🎉 Thanks for your first pull request to floci-az! Your CI checks need a maintainer to approve them before they run. That is GitHub's standard gate on first-time contributors, not a problem with your PR — so if the checks look like they are doing nothing, that is why. Once a maintainer approves, CI and the compatibility suite start automatically. Nothing is needed from you in the meantime. While you wait, a couple of things that make review faster:
Come join us in Slack — it is the fastest way to reach maintainers if you get stuck, or want feedback on an approach before investing more time in it. |
|
| Filename | Overview |
|---|---|
| src/main/java/io/floci/az/core/auth/UserDelegationKeyMaterial.java | Uses a process-local random master key to derive stable, account-scoped delegation keys without retaining the prior public derivation. |
| src/main/java/io/floci/az/core/auth/StorageSasAuthorization.java | Enforces user-delegation signature, key-window, resource-scope, path-scope, and operation-permission checks. |
| src/main/java/io/floci/az/services/blob/BlobServiceHandler.java | Applies SAS authorization to implemented Blob and ADLS-backed read, list, create, write, and delete operations. |
| src/main/java/io/floci/az/services/blob/UserDelegationKeyService.java | Issues delegation keys from the shared application-scoped key-material service. |
| src/test/java/io/floci/az/services/BlobServiceTest.java | Covers signature rejection, key validity, resource and directory scope, and operation-specific permission enforcement. |
| compatibility-tests/sdk-test-java/src/test/java/io/floci/az/compat/DataLakeCompatibilityTest.java | Verifies accepted and denied user-delegation SAS behavior through the Java Data Lake SDK. |
Sequence Diagram
sequenceDiagram
participant SDK as Azure SDK
participant Auth as SAS Verifier
participant Handler as Blob Handler
participant Policy as SAS Authorization
participant Store as Blob Backend
SDK->>Auth: Blob/ADLS request with SAS
Auth->>Auth: Parse token and validate time window
Auth-->>Handler: AuthContext with parsed SAS
Handler->>Policy: Authorize operation and resource path
Policy->>Policy: Validate delegation key and signature
Policy->>Policy: Check scope and permission
alt Authorized
Policy-->>Handler: Allowed
Handler->>Store: Read or mutate resource
Store-->>SDK: Azure-compatible response
else Denied
Policy-->>SDK: 403 Azure error
end
Reviews (3): Last reviewed commit: "feat: enforce scoped ADLS SAS authorizat..." | Re-trigger Greptile
|
Thank you for taking this from parsing to actual enforcement, and for keeping the new types in Two things, and the first one is our fault. We merged #166 today and it touched The second is that I have not finished checking the SAS field semantics against Azurite yet. Given this flips a permissive path into an enforcing one I would rather not sign off from a skim. The pieces I want to walk properly are the signed permission to operation mapping, the Nothing looks wrong so far. I will come back with specifics once you have rebased. |
Summary: - Add parsed storage SAS context and deterministic shared user-delegation signing key material. - Validate user-delegation SAS signatures, resource scope, path scope, and operation permissions before Blob-backed ADLS operations. - Add Blob and Java DataLake SDK compatibility coverage for accepted and denied SAS behavior. - Signed user-delegation key-window validation now includes: skt/ske, signed key identity/service, and SAS expiry bounded by key expiry Type of change: - [x] New feature (feat:) Azure Compatibility: - Matches Java Azure SDK DataLake user-delegation SAS string-to-sign behavior for the compatibility-suite SDK version. - SDK test source compile verified with repo-local Maven cache. Checklist: - [x] `./mvnw test` passes locally - [x] New or updated integration test added. - [x] Commit messages follow Conventional Commits.
|
Want your agent to iterate on Greptile's feedback? Try greploops. |
|
Thank you for this, and sorry it sat with me so long. A change that turns a permissive path into an enforcing one deserved a proper pass rather than a skim, and I have now done it. The signing is right. I compared the string-to-sign field by field against Azurite and your ordering matches its Three things worth a follow up issue rather than holding this: the signing uses the 2020-12-06 layout regardless of No blockers from my side. |
|
🎉 This PR is included in version 0.11.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
# [0.11.0](floci-io/floci-az@0.10.0...0.11.0) (2026-08-18) ### Bug Fixes * **blob:** persist upload HTTP properties ([floci-io#166](floci-io#166)) ([28cd215](floci-io@28cd215)), closes [floci-io#163](floci-io#163) * **core:** omit Content-Type on bodyless error responses ([floci-io#185](floci-io#185)) ([51b545a](floci-io@51b545a)) * **cosmos:** enforce item ETag conditions ([floci-io#167](floci-io#167)) ([dd5ae45](floci-io@dd5ae45)), closes [floci-io#160](floci-io#160) [floci-io#161](floci-io#161) * **cosmos:** evaluate correlated EXISTS queries ([floci-io#168](floci-io#168)) ([fbaa6bf](floci-io@fbaa6bf)), closes [floci-io#162](floci-io#162) * **dns,tls:** converge dns and tls clusters on floci-aws baseline 0142dc4 ([floci-io#177](floci-io#177)) ([90736bc](floci-io@90736bc)) * **docker:** converge docker cluster on floci-aws baseline 0142dc4 ([floci-io#178](floci-io#178)) ([eb0bf42](floci-io@eb0bf42)), closes [floci-io#157](floci-io#157) [floci-io#95](floci-io#95) * **entra:** make EntraStore participate in /_admin/reset ([floci-io#195](floci-io#195)) ([a370440](floci-io@a370440)) * **functions:** accept deployment packages larger than 20 MB ([floci-io#196](floci-io#196)) ([c247f32](floci-io@c247f32)), closes [floci-io#192](floci-io#192) * **postgres:** answer 202 with Location so azurerm 3.x and 4.x both apply ([floci-io#135](floci-io#135)) ([3a11776](floci-io@3a11776)) * **sql:** replace retired Azure SQL Edge image ([floci-io#139](floci-io#139)) ([11fc293](floci-io@11fc293)), closes [floci-io#138](floci-io#138) * **storage:** converge storage cluster on floci-aws baseline 0142dc4 ([floci-io#180](floci-io#180)) ([7b375a7](floci-io@7b375a7)) * **storage:** serve service-properties XML for table, queue, and blob ([floci-io#134](floci-io#134)) ([1848a4d](floci-io@1848a4d)), closes [floci-io#132](floci-io#132) [floci-io#131](floci-io#131) ### Features * **cosmos:** container DefaultTimeToLive (TTL) with per-document overrides ([floci-io#141](floci-io#141)) ([d4f1d70](floci-io@d4f1d70)), closes [floci-io#126](floci-io#126) * enforce scoped ADLS SAS authorization ([floci-io#158](floci-io#158)) ([3f951ae](floci-io@3f951ae)) * Entra ID phase 2 — auth-code+PKCE grant + Microsoft Graph slice ([floci-io#143](floci-io#143)) ([913954b](floci-io@913954b)), closes [floci-io#120](floci-io#120) * **release:** release parity, one-button release cut, and the -compat image ([floci-io#188](floci-io#188)) ([6fe9958](floci-io@6fe9958)) * **servicebus:** support message sessions ([floci-io#190](floci-io#190)) ([dccc3dd](floci-io@dccc3dd)), closes [floci-io#159](floci-io#159) ### Performance Improvements * **docker:** stop duplicating the native binary into a second image layer ([floci-io#187](floci-io#187)) ([5354201](floci-io@5354201))
Thanks! |
Summary
Type of change
Azure Compatibility
Checklist
./mvnw testpasses locally