Connect Multi FileFeeds to Azure Blob Storage
Configure an Azure Blob Storage connection and use it as a source or destination on a Multi FileFeed. OneSchema reads from and writes to your container using short-lived Workload Identity Federation credentials — no long-lived storage account keys or SAS tokens.
Availability: Multi FileFeeds with Azure Blob Storage connections enabled.
This guide walks through three things:
- Creating an Azure Blob connection in OneSchema, including running the setup script that provisions a federated identity credential on a Microsoft Entra ID app registration in your tenant.
- Using that connection as a source on a Multi FileFeed, so OneSchema polls a container on a schedule and ingests new blobs.
- Using that connection as a destination on a Multi FileFeed, so OneSchema writes processed output files into a container.
A single Azure Blob connection can back both directions — you do not need separate connections for source and destination usage. RBAC role assignments on the storage account decide what the connection's principal can do.
Terminology
| Term | Direction | Meaning |
|---|---|---|
| Azure Blob source | Your container → OneSchema | A polling configuration on a Multi FileFeed. OneSchema lists and ingests matching blobs on a schedule. |
| Azure Blob destination | OneSchema → your container | A write configuration on a Multi FileFeed. OneSchema writes each output file into your container and prefix. |
| Azure Blob connection | Shared connection object | A saved OneSchema connection pointing at a Microsoft Entra ID app registration in your tenant via Workload Identity Federation. |
| Federated identity credential | Microsoft Entra ID app registration setting | A trust relationship on the app registration that lets an external OIDC issuer (OneSchema's runtime) acquire a token for the app, without a secret. |
How it works
OneSchema does not store long-lived storage account keys, client secrets, or SAS tokens. Instead, OneSchema's workloads present a short-lived OIDC token issued by their own runtime to the Microsoft identity platform, which validates it against a federated identity credential you configure on a Microsoft Entra ID app registration in your tenant.
sequenceDiagram
participant OS as OneSchema runtime
participant AAD as Microsoft identity platform
participant SP as Your Entra ID app registration
participant BLOB as Your Azure Storage account
OS->>OS: Read runtime OIDC token<br/>(projected by the runtime, never persisted)
OS->>AAD: Token request — present OIDC token<br/>as client_assertion for {tenant_id, client_id}
AAD->>SP: Validate token against federated identity credential
SP-->>AAD: Federated credential trusts this issuer/subject
AAD-->>OS: Microsoft Entra ID access token<br/>(scope: storage.azure.com/.default)
OS->>BLOB: List / Get / Put blob
BLOB-->>OS: Response (gated by RBAC on the storage account)
A few things follow from this design:
- No keys to rotate. OneSchema never sees a client secret, SAS token, or storage account key. Credentials live for the duration of one operation (Microsoft Entra ID access tokens are valid for ~1 hour).
- Read vs. write is RBAC. Microsoft Entra ID issues a single resource scope (
https://storage.azure.com/.default); whether the token can read or write a given blob is decided by RBAC role assignments on the storage account. GrantStorage Blob Data Readerfor source-only access andStorage Blob Data Contributorfor destination access. - Setup is one-time per app registration. The setup script provisions a Microsoft Entra ID app registration, configures the federated identity credential, and grants the role assignments. Once it's in place, you can create as many OneSchema connections as you like against the same tenant — though each OneSchema connection is scoped to a single storage account.
Prerequisites
You will need:
| Requirement | Notes |
|---|---|
| Admin role in OneSchema | Required to create or edit connections. |
| Azure Blob feature enabled | If you do not see an Azure Blob Storage tab on the Connections page, contact your OneSchema representative. |
| An Azure tenant and subscription | The tenant that owns the storage account you want to read from or write to. |
az CLI | The setup script is bash and uses the Azure CLI. You must be authenticated (az login) as a principal with permission to create app registrations and assign roles. |
| Azure permissions for the script runner | At minimum: ability to create app registrations and federated identity credentials in the tenant, plus Owner or User Access Administrator on the storage account so the script can create the RBAC role assignments. |
| OIDC federation values from OneSchema | The issuer URL and subject claim that OneSchema's runtime will present. Contact OneSchema customer support to receive the current values — see the Federation values section below for what to ask for and where to paste them. |
You will also need the storage account name and the resource group that contains it.
Federation values
These values identify the OIDC token OneSchema's runtime presents to Microsoft Entra ID. They are stable per OneSchema deployment, so the same values apply to every Azure Blob connection you create. The generated setup script contains FEDERATION_ISSUER='{ONESCHEMA_OIDC_ISSUER}' and FEDERATION_SUBJECT='{ONESCHEMA_OIDC_SUBJECT}' placeholders — replace them with the Issuer and Subject you receive from OneSchema before running the script. The Audience is already hardcoded in the script and doesn't need editing. If you set up the federated credential through the Azure Portal instead, paste the Issuer and Subject into the corresponding fields there.
| Field | Value |
|---|---|
| Issuer URL | Contact OneSchema customer support to receive the current value. |
| Subject | Contact OneSchema customer support to receive the current value. |
| Audience | api://AzureADTokenExchange |
The audience matches Microsoft's default for the "Kubernetes accessing Azure resources" federated-credential scenario, so the Azure Portal will pre-fill it for you if you set up the credential through the UI.
Step 1 — Create an Azure Blob connection in OneSchema
- Open Connections → Azure Blob Storage and click Create Azure Blob Storage connection.
- Give the connection a name your team will recognize (e.g.
acme-prod-blob). - Fill in your Microsoft Entra ID tenant ID and your target storage account name. The form generates a setup script tailored to those values.
- Copy the generated script into an editor and replace the two
{ONESCHEMA_OIDC_ISSUER}and{ONESCHEMA_OIDC_SUBJECT}placeholders with the values from the Federation values section above. The other variables are already filled in for you. - Run the script in a terminal where
azis authenticated against the right subscription. The script:- Creates a Microsoft Entra ID app registration named
oneschema-blob(rename via the advanced section). - Creates a service principal for the app.
- Configures a federated identity credential trusting OneSchema's OIDC issuer.
- Grants the service principal
Storage Blob Data ReaderandStorage Blob Data Contributoron the storage account. - Prints the Application (client) ID at the top of its output.
- Creates a Microsoft Entra ID app registration named
- Paste the printed Client ID into the App registration (client) ID field on the form.
- Click Test connection. OneSchema's backend will mint a federated access token against your tenant and verify that it can call the Blob endpoint. The Save button unlocks once the test succeeds.
Prefer the Azure Portal? You can do the same setup through Microsoft Entra ID → App registrations → New registration, then add a federated credential using the "Kubernetes accessing Azure resources" scenario with the Issuer and Subject from the Federation values section. The Audience field defaults to api://AzureADTokenExchange for that scenario. Finally, grant the app Storage Blob Data Reader and/or Storage Blob Data Contributor on the storage account.
Step 2 — Use the connection as a source
- Open a Multi FileFeed and switch to its settings.
- Under Source, choose Azure Blob.
- Pick the connection you just created.
- Enter the container name (no
az://scheme, no leading slash) and an optional prefix for the folder OneSchema should poll. - Optionally add a file filter (a case-insensitive regular expression matched against each blob's key after the prefix is stripped).
- Pick a pull frequency — hourly or daily at a chosen UTC time.
Each poll processes only matching blobs that have not been ingested before (deduplicated by (container, key, ETag)). Source connections use only the Storage Blob Data Reader role.
Step 3 — Use the connection as a destination
- Open a Multi FileFeed and switch to its settings.
- Under Destination, choose Azure Blob.
- Pick the connection you just created.
- Enter the container name and an optional prefix.
Each output file the workflow produces will be uploaded into <container>/<prefix>/<file-name>. Existing blobs are overwritten in place; Azure assigns a new ETag, and any retention policy on the storage account decides whether the old version is kept. Destination connections use the Storage Blob Data Contributor role.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
Test connection reports access_denied with "federated identity assertion rejected" | The federated identity credential on the app registration does not trust OneSchema's OIDC issuer/subject, or the tenant/client IDs in the form do not match the ones the script created. | Re-run the script with the correct OIDC values, or fix the issuer/subject on the existing federated credential under Microsoft Entra ID → App registrations → Certificates & secrets. |
Source target shows failed_container | The app registration's service principal does not have Storage Blob Data Reader on the storage account, or the container name is wrong. | Verify the container exists and that the service principal has at least Storage Blob Data Reader at the storage account scope. |
Destination target shows failed_container | The service principal lacks Storage Blob Data Contributor. | Add the Storage Blob Data Contributor role assignment on the storage account. |
| Polling never picks up a new blob | The file-filter regex is too strict, or the blob was uploaded with a timestamp older than the current cursor. | Loosen the file filter or upload a new blob with a fresh timestamp. The cursor advances after each successful ingest. |
Updated about 10 hours ago