Skip to content

feat: add Microsoft Entra ID (passwordless) auth for the Azure Blob backend - #2802

Merged
sylvestre merged 1 commit into
mozilla:mainfrom
babrekel:feat/azure-entra-id-auth
Aug 11, 2026
Merged

feat: add Microsoft Entra ID (passwordless) auth for the Azure Blob backend#2802
sylvestre merged 1 commit into
mozilla:mainfrom
babrekel:feat/azure-entra-id-auth

Conversation

@babrekel

@babrekel babrekel commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Closes #1118.

Summary

sccache's Azure Blob backend currently supports only connection-string
(shared-key) authentication, which fails against storage accounts that have
shared-key access disabled — an increasingly common security baseline (and one
some Azure Policy configurations mandate).

This adds a Microsoft Entra ID (passwordless) path: when no connection
string is configured, the Azblob operator is built without an account key or
SAS token, so OpenDAL (via its reqsign dependency) resolves an Entra
credential from the ambient environment and signs each request with an OAuth
bearer token.

Behavior

  • Shared key (unchanged): SCCACHE_AZURE_CONNECTION_STRING keeps its
    existing behavior, byte-for-byte.

  • Entra ID (new): with no connection string, select the account via either

    • SCCACHE_AZURE_STORAGE_ACCOUNT — endpoint synthesized as
      https://{account}.blob.core.windows.net, or
    • SCCACHE_AZURE_ENDPOINT — a full endpoint for sovereign clouds / custom
      DNS, validated as an https URI (plain http accepted only for a loopback
      host).

    Credentials then resolve from the environment: a service principal
    (AZURE_TENANT_ID / AZURE_CLIENT_ID / AZURE_CLIENT_SECRET), workload
    identity (AZURE_FEDERATED_TOKEN_FILE), or a managed identity via IMDS.

  • The two modes are mutually exclusive, enforced on both the env and
    file-config surfaces; blank values from a file config are treated as absent.

  • A container configured with no auth source: an ambient env var only warns and
    disables the backend (so a stray variable can't take down an unrelated cache),
    whereas an explicit [cache.azure] block errors clearly at startup.

No new dependencies — opendal/services-azblob and reqsign are already pulled
in by the existing azure feature.

Testing

  • cargo fmt --check, cargo clippy --all-targets -- -D warnings,
    cargo check --no-default-features (with and without --features azure), and
    cargo test --features azure all pass.
  • Unit tests cover endpoint synthesis / precedence / trailing-slash handling,
    https + host-injection validation, empty-string normalization, auth-mode
    selection, mutual exclusivity (both operands), the no-auth error, and config
    parsing across the env and TOML surfaces.
  • The passwordless request path (IMDS / token exchange) cannot run in CI
    without a live account; a key-less Azblob build is confirmed to engage
    reqsign's OAuth loader chain rather than going anonymous. In practice this
    path has been running as the compilation-cache backend for a CI fleet,
    authenticating to Azure Blob Storage via workload identity
    (AZURE_FEDERATED_TOKEN_FILE).

Docs

docs/Azure.md and docs/Configuration.md are updated with the new variables,
precedence, mutual exclusivity, the https/loopback rule, and an Azurite note.

…ackend

sccache's Azure backend only supported connection-string (shared-key)
auth, which fails against storage accounts that disable shared-key
access. Add a passwordless path that authenticates with Microsoft Entra
ID (OAuth bearer tokens) instead.

* When no connection string is set, the Azblob operator is built with no
  account key or SAS token, so OpenDAL/reqsign resolve credentials from
  the ambient environment (service principal, workload identity, or a
  managed identity via IMDS) and sign each request with a bearer token.
* The blob endpoint comes from SCCACHE_AZURE_ENDPOINT (validated as an
  https URI; http is allowed only for a loopback host) or is synthesized
  from SCCACHE_AZURE_STORAGE_ACCOUNT as
  https://{account}.blob.core.windows.net.
* The connection-string path is unchanged, and the two auth modes are
  mutually exclusive, enforced on both the env and file config surfaces.
  Blank values from a file config are treated as absent.
* An explicit [cache.azure] block with no auth source errors clearly at
  startup, whereas an ambient container env var with no auth source only
  warns and disables the backend so it cannot take down an unrelated
  cache.

Includes unit tests for endpoint resolution, auth-mode selection,
mutual exclusivity, endpoint/account validation, and config parsing
(env + TOML), plus documentation in docs/Azure.md and
docs/Configuration.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: babrekel <babrekel@microsoft.com>
@babrekel
babrekel force-pushed the feat/azure-entra-id-auth branch from c14afdc to d8f47bd Compare August 10, 2026 21:16
@codecov-commenter

codecov-commenter commented Aug 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.88268% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 73.14%. Comparing base (46e96ab) to head (d8f47bd).

Files with missing lines Patch % Lines
src/config.rs 98.44% 3 Missing ⚠️
src/cache/azure.rs 99.35% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2802      +/-   ##
==========================================
+ Coverage   72.90%   73.14%   +0.23%     
==========================================
  Files          72       72              
  Lines       37275    37615     +340     
==========================================
+ Hits        27176    27512     +336     
- Misses      10099    10103       +4     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@sylvestre
sylvestre merged commit 67683cc into mozilla:main Aug 11, 2026
51 checks passed
@sylvestre

Copy link
Copy Markdown
Collaborator

thanks!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Entra ID authentication support

3 participants