On this page · 9 sections
Summary. On 29 July 2026 Microsoft shipped azure_storage_sas 0.1.0, the first client-library capability built on the Azure SDK for Rust after it reached general availability in May 2026 and completed its 1.0.0 foundation in June. The crate builds user-delegation Shared Access Signatures (SAS) for Blob, Queue and other Storage resources, and it does one thing that matters for security: it grants scoped, time-limited access without putting an account key in your code. A user-delegation SAS is signed by Microsoft Entra ID, can live for at most 7 days, and shows up in Storage access logs, so it beats the older account-key model on traceability and blast radius. That model matters because leaked or hard-coded credentials remain a leading breach path, and IBM put the 2025 global average data breach at $4.44 million. This guide covers what shipped, why user-delegation SAS is the right default, the Rust code to mint a token, the crate's current limits, and the hardening steps for production.
What shipped in July 2026
The Azure SDK for Rust followed a clear release cadence in 2026: general availability in May, a 1.0.0 core in June, and the first storage client feature, azure_storage_sas, on 29 July, per the Azure SDK release blog by Justin Bettencourt. The crate is a user-delegation SAS builder. It lets a Rust service hand out narrow, expiring access to a specific blob or container so a client can upload or download directly against Storage, rather than proxying every byte through your API.
This filled a real gap. The Rust SDK had authentication and storage clients, but no first-party way to construct SAS tokens, a request tracked in the SDK's GitHub issue #1346. Teams had been hand-rolling the signing logic, which is exactly the kind of security-sensitive code you do not want to maintain yourself.
Why user-delegation SAS, not account or service SAS
Azure has three SAS types, and they are not equivalent on security. An account SAS and a service SAS are both signed with the storage account key, so anyone who can mint them needs that key, and the key itself is the crown-jewel secret. A user-delegation SAS is signed instead with a key derived from a Microsoft Entra ID identity, so your code authenticates with a managed identity or service principal and never touches the account key. Microsoft's own guidance calls the user-delegation SAS the most secure of the three in the SAS overview.
| Vector | Account SAS | Service SAS | User-delegation SAS |
|---|---|---|---|
| Signed with | Account key | Account key | Entra ID key |
| Account key in code | Yes | Yes | No |
| Max lifetime | Long | Long | 7 days |
| Identity in access logs | No | No | Yes |
| Revoke by rotating | Account key | Account key or policy | Entra credential |
| azure_storage_sas 0.1.0 support | No | No | Yes |
The azure_storage_sas crate deliberately supports only the user-delegation variant in 0.1.0. Account SAS and stored access policies are not supported. That is a defensible default: it steers Rust developers toward the keyless path and away from embedding the account key, which is the pattern that turns one leaked config file into full account compromise.
How it works
A user-delegation SAS is a two-step flow. First, your application authenticates to Entra ID and requests a user-delegation key from the Blob or Queue service. That key is what Microsoft signs, and it is bound to your identity and to a validity window. Second, you pass that key to a builder, add the resource, permissions and expiry, and produce the signed query string you append to a blob URL.
In the Rust SDK, the key comes from BlobServiceClient::get_user_delegation_key in azure_storage_blob, or QueueServiceClient::get_user_delegation_key in azure_storage_queue, as described in the crate's usage notes and mirrored in the REST Get User Delegation Key API. You then hand it to SasBuilder.
Dependencies
[dependencies]
azure_identity = "1"
azure_storage_blob = "1"
azure_storage_sas = "0.1"
time = "0.3"
tokio = { version = "1", features = ["full"] }
Minting a scoped, read-only blob token
use azure_identity::DefaultAzureCredential;
use azure_storage_blob::BlobServiceClient;
use azure_storage_sas::SasBuilder;
use time::{Duration, OffsetDateTime};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let account = "mystorageaccount";
let endpoint = format!("https://{account}.blob.core.windows.net");
// Authenticate with Entra ID. No account key anywhere in this process.
let credential = DefaultAzureCredential::new()?;
let service = BlobServiceClient::new(&endpoint, credential.clone(), None)?;
// Ask Storage for a user-delegation key valid for a short window.
let start = OffsetDateTime::now_utc();
let expiry = start + Duration::hours(1);
let udk = service.get_user_delegation_key(start, expiry).await?;
// Build a read-only SAS for one blob, HTTPS-only, expiring in one hour.
let token = SasBuilder::new(account, udk, expiry)
.blob("uploads", "invoice-1042.pdf")
.read()
.protocol_https_only()
.build()?;
let sas_url = format!("{endpoint}/uploads/invoice-1042.pdf?{token}");
println!("{sas_url}");
Ok(())
}
The token in that example can read exactly one blob, over HTTPS only, for one hour. Nothing else. The client that receives sas_url cannot list the container, cannot write, and cannot reach any other blob. When the hour passes, the URL is dead.
Tightening scope with permissions, IP range and protocol
The builder chains the controls you would expect. For an upload endpoint you grant write rather than read; for a listing you grant list at the container level; and you can pin the token to a caller's network with an IP range.
let token = SasBuilder::new(account, udk, expiry)
.container("uploads")
.write()
.list()
.protocol_https_only()
.ip_range("203.0.113.0", "203.0.113.255")
.build()?;
Each method narrows the grant. The rule of thumb: start from nothing and add only the permission, resource and window the client actually needs. A SAS can never grant more than the identity that signed it already holds, so pairing least-privilege Entra roles with least-privilege SAS gives you two layers, not one.
What the crate does not do yet
Version 0.1.0 is deliberately narrow, and knowing the edges saves you a wasted afternoon.
- Account SAS is not supported. If you genuinely need account-level operations, that path is not here, and in most designs you should not want it.
- Stored access policies are not supported, so you cannot yet bind a SAS to a server-side policy for central revocation. Revocation today means rotating the Entra credential or waiting out the short expiry.
- It is a 0.1.0 release. Treat the surface as still settling and pin the version, because a builder method name can change before 1.0.
For anything the crate cannot express, the create a user-delegation SAS reference documents the underlying string-to-sign, so you can verify what the builder produces rather than guess.
Hardening for production
A keyless token is safer by default, but the defaults still need discipline.
Keep tokens short. The 7-day maximum is a ceiling, not a target. Minutes-to-hours expiry is normal for upload and download links, and short windows shrink the value of any token that leaks. Cache the user-delegation key, not the SAS. Fetching a user-delegation key is a network call, so request one key per validity window and mint many SAS tokens from it, rather than calling Storage on every request. Bind to an identity where you can. In February 2026 Azure previewed user-bound user-delegation SAS, which restricts a token to a single Entra ID identity so a stolen URL cannot be replayed by anyone else, described in the Azure Storage announcement. Log and watch. User-delegation SAS actions carry the delegating identity into Storage access logs, so wire those logs into your monitoring and alert on unexpected scopes or volumes.
This is the same keyless direction other ecosystems are taking, from OIDC in package publishing to workload identity in CI, covered in our note on npm OIDC trusted publishing. If you also expose these tokens through an HTTP API, apply the same care to error semantics and retries that you would elsewhere, using RFC 9457 problem details for failures and idempotency keys for safe retries. The broader backend patterns sit in our 2026 web platform developer guide.
India and global considerations
For teams in India building on Azure, the keyless model lines up with data-access accountability under the Digital Personal Data Protection Act 2023 (DPDP). Because a user-delegation SAS records the delegating identity in access logs, you can show who granted access to a given object and for how long, which is far harder to reconstruct when every service shares one account key. The same property helps any team, anywhere, that has to answer an audit question about who could read a specific file on a specific day.
FAQ
How eCorpIT can help
eCorpIT is a Gurugram-based, senior-led engineering organisation, founded in 2021, that builds secure cloud backends across AWS, Microsoft and Google platforms. We design keyless access patterns, identity-based authorization and least-privilege storage flows, and we review Rust and cloud services for credential-handling risk aligned with ISO 27001:2022 practices. If you want a second set of eyes on how your application issues and scopes Storage access, contact us.
References
_Last updated: 31 July 2026._