feat(azureblob): support Azure Managed/Workload Identity - #36
Merged
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Add config.backends.azureblob.managedIdentity. When true the chart renders jclouds.identity and jclouds.credential as empty strings, which is the only state that makes the azureblob-sdk provider use Azure's DefaultAzureCredential (the AKS workload-identity-injected AZURE_CLIENT_ID/TENANT_ID/FEDERATED_TOKEN_FILE). Before this, jclouds.identity was emitted only when 'account' was set, and always as the account name, so an empty/empty identity+credential was unexpressible: with account set identity was the account (a static identity disables managed identity), and with account empty the identity line was absent, not an empty string. The account name now goes in the endpoint (unchanged default), never in identity. A render-time guard rejects the auth-breaking misconfigs (non-sdk provider, a static key/SAS alongside managed identity, or no endpoint). Static-key and SAS paths are untouched. No image bump (andrewgaul/s3proxy:3.3.0 already supports it).
CRThaze
force-pushed
the
CRThaze/s3proxy-azureblob-managed-identity
branch
from
September 3, 2026 11:05
dd20b23 to
02601b1
Compare
📝 README.md PreviewThe following changes to Click to expand diffdiff --git a/README.md b/README.md
index eead0ce..6a66033 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# s3proxy
-  
+  
A Helm chart for deploying S3Proxy - Access other storage backends via the S3 API
@@ -23,7 +23,7 @@ The chart tracks S3Proxy (`andrewgaul/s3proxy`) through `appVersion` (currently
S3Proxy `3.0.0` deprecated the Apache jclouds storage backends (`s3`, `aws-s3`, `azureblob`, `filesystem`, `transient`) in favor of SDK / NIO2 providers. Upstream has announced that `3.3.0` is the last release to bundle jclouds and that future releases "will lack its Atmos and B2 storage backends" (no jclouds-free release has shipped yet; `3.3.0` remains the latest). The jclouds providers still work on 3.x, but are deprecated:
- `filesystem` / `transient`: already default to the non-deprecated `*-nio2` variants (`nio2: true`).
-- `azureblob`: **defaults to `provider: azureblob-sdk`** (the Azure SDK provider, which signs correctly against custom endpoints such as Azurite). The legacy jclouds `azureblob` provider is deprecated and mis-signs against custom endpoints; set `provider: azureblob` only if you specifically need it. On real Azure, `azureblob-sdk` may require `config.backends.azureblob.regions` for bucket creation.
+- `azureblob`: **defaults to `provider: azureblob-sdk`** (the Azure SDK provider, which signs correctly against custom endpoints such as Azurite). The legacy jclouds `azureblob` provider is deprecated and mis-signs against custom endpoints; set `provider: azureblob` only if you specifically need it. On real Azure, `azureblob-sdk` may require `config.backends.azureblob.regions` for bucket creation. For AKS Managed/Workload Identity (no static key), set `config.backends.azureblob.managedIdentity: true` — see "Example 3b" below.
- `s3`, `googleCloudStorage`, `openstackSwift`: SDK providers exist upstream (`aws-s3-sdk`, `google-cloud-storage-sdk`, `openstack-swift-sdk`). `rackspaceCloudfiles` is OpenStack-Swift-compatible and may be served by `openstack-swift-sdk`. Migrating the chart defaults to the SDK providers is tracked separately.
- `b2` (and Atmos, if ever added) are jclouds-only with **no SDK successor**. These are the backends upstream has said future releases will drop.
@@ -157,6 +157,12 @@ The following section lists the configurable parameters of the s3proxy chart and
<td><code>string</code></td>
<td><code>""</code></td>
</tr>
+ <tr>
+ <td><code>config.backends.azureblob.managedIdentity</code></td>
+ <td>Use Azure Managed/Workload Identity instead of a static account key or SAS token. Requires <code>provider: azureblob-sdk</code>; mutually exclusive with <code>key.<i></code> and <code>sasToken.</i></code>. When true the chart renders both <code>jclouds.identity</code> and <code>jclouds.credential</code> empty, which makes azureblob-sdk fall back to Azure's <code>DefaultAzureCredential</code> (consuming the AKS workload-identity env <code>AZURE_CLIENT_ID</code>/<code>AZURE_TENANT_ID</code>/<code>AZURE_FEDERATED_TOKEN_FILE</code>). Set <code>account</code> (or <code>endpoint</code>) for the storage endpoint, annotate the ServiceAccount with <code>azure.workload.identity/client-id</code> (<code>serviceAccount.annotations</code>) and label the pod <code>azure.workload.identity/use: "true"</code> (<code>podLabels</code>).</td>
+ <td><code>bool</code></td>
+ <td><code>false</code></td>
+ </tr>
<tr>
<td><code>config.backends.azureblob.provider</code></td>
<td>Provider type. Defaults to <code>azureblob-sdk</code> (Azure SDK): it signs correctly against custom endpoints (Azurite, Azure Gov/China, private endpoints) and is the non-deprecated provider on S3Proxy 3.x. The legacy jclouds <code>azureblob</code> provider is deprecated upstream and mis-signs against custom endpoints; on real Azure <code>azureblob-sdk</code> may require <code>regions</code> to be set for bucket creation.</td>
@@ -945,6 +951,40 @@ Install:
helm install s3proxy-azure ./s3proxy -f values-azure.yaml
```
+### Example 3b: Azure Blob with Managed / Workload Identity (no static key)
+
+On AKS with Workload Identity, set `managedIdentity: true` instead of an account
+key or SAS token. The chart then renders both `jclouds.identity` and
+`jclouds.credential` empty, which makes the `azureblob-sdk` provider fall back to
+Azure's `DefaultAzureCredential` — it reads the federated token AKS injects
+(`AZURE_CLIENT_ID` / `AZURE_TENANT_ID` / `AZURE_FEDERATED_TOKEN_FILE`). The storage
+account name goes in the endpoint, never in the identity.
+
+```yaml
+# values-azure-mi.yaml
+config:
+ backends:
+ filesystem:
+ enabled: false
+ azureblob:
+ enabled: true
+ provider: "azureblob-sdk" # required: the legacy jclouds provider can't do token auth
+ managedIdentity: true
+ account: "mystorageaccount" # used for the endpoint; NOT emitted as jclouds.identity
+ # endpoint: "https://mystorageaccount.blob.core.windows.net" # or set explicitly
+
+# Bind the pod to the AKS user-assigned identity:
+serviceAccount:
+ create: true
+ annotations:
+ azure.workload.identity/client-id: "<managed-identity-client-id>"
+podLabels:
+ azure.workload.identity/use: "true"
+
+persistence:
+ enabled: false
+```
+
### Example 4: Google Cloud Storage Backend
```yaml
|
📊 Helm Render Diff SummaryChart
🔍 Detailed Changes📝 Changes in
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
S3Proxy's
azureblob-sdkbackend uses Azure'sDefaultAzureCredential(AKSWorkload Identity) only when both
jclouds.identityandjclouds.credentialrender as empty strings. The chart could not express that state, so managed
identity was impossible — you could only use a static account key or a SAS token.
Root cause
In
configmap.yaml,jclouds.identitywas emitted only whenaccountwas set,and always as the account name. So:
accountset → identity = account (a non-empty identity disables managed identity);accountempty → the identity line was absent, not an empty string.Either way, empty/empty identity+credential was unreachable.
Change
config.backends.azureblob.managedIdentity(defaultfalse). When true, thechart renders
jclouds.identity=andjclouds.credential=empty and keeps thestorage account name in the endpoint (never in the identity).
azureblob-sdkprovider,a static key/SAS token set alongside managed identity, or no endpoint.
test-values/azureblob-managed-identity.yamlrender scenario (also covers theworkload-identity SA annotation + pod label), wired into the lint-render matrix.
charts/s3proxy/README.md.gotmpl(root
README.mdis regenerated from the template by CI, not hand-edited here).0.4.2→0.4.3.No image/appVersion bump —
andrewgaul/s3proxy:3.3.0already supports this.Backward compatibility
Static-key (inline + existingSecret) and SAS-token paths are unchanged — verified by
re-rendering the existing
azureblob.yamlandazureblob-existing-secret.yamlscenarios (identical
jclouds.identity/credential output).How to configure (AKS Workload Identity)
Test evidence
helm templaterendersjclouds.provider=azureblob-sdk, the endpoint, and emptyjclouds.identity=/jclouds.credential=; nosecret-azureblob.propertiesiscreated.
helm lintpasses. All three guard misconfigs fail at render time.