Azure authentication¶
Sleet needs write access to the Azure Storage container that holds the feed. This page covers the ways to give it access, starting with the recommended one.
How Sleet picks a credential¶
Sleet looks at two source properties:
| Settings | What Sleet uses |
|---|---|
path set, no connectionString |
Microsoft Entra ID, through DefaultAzureCredential from the Azure Identity library. Sleet takes the storage account URL from path. |
connectionString set |
The connection string. path is optional, and is only checked against the container URL. |
Use path without a connection string whenever you can. Tokens from Entra ID expire on their own, and access is controlled with Azure roles instead of a shared account key.
Microsoft Entra ID¶
DefaultAzureCredential tries these credentials in order, and uses the first one that works:
- Environment variables for a service principal.
- Workload identity, for example on Azure Kubernetes Service.
- Managed identity, on Azure hosts such as virtual machines and App Service.
- Visual Studio sign-in.
- Azure CLI sign-in (
az login). - Azure PowerShell sign-in (
Connect-AzAccount). - Azure Developer CLI sign-in (
azd auth login).
Sleet never opens a browser to sign in. See Microsoft's credential chains article for details on each credential.
sleet.json:
{
"sources": [
{
"name": "feed",
"type": "azure",
"container": "feed",
"path": "https://myaccount.blob.core.windows.net/feed/"
}
]
}
Assign a data role¶
The identity that runs Sleet needs the Storage Blob Data Contributor role. This role lets Sleet read, write, and delete blobs, list the container, and take the lease that locks the feed.
Note
The Owner and Contributor roles manage the storage account, but they don't grant access to blob data through Entra ID. Assign Storage Blob Data Contributor even if you own the account.
Assign the role on the storage account:
az role assignment create \
--assignee <user-or-app-id> \
--role "Storage Blob Data Contributor" \
--scope /subscriptions/<subscription-id>/resourceGroups/my-resource-group/providers/Microsoft.Storage/storageAccounts/myaccount
To limit access to the feed container, add /blobServices/default/containers/feed to the end of the scope. The container must exist before you can assign a role on it, so create it first.
New role assignments can take a few minutes to apply. Until then, Sleet fails with a 403 AuthorizationPermissionMismatch error.
Sign in on your machine¶
Sign in with the Azure CLI, then run Sleet in the same shell:
A Visual Studio or Azure PowerShell sign-in also works.
Service principal¶
For a build server that isn't on Azure, create a service principal (an app registration) and set these environment variables. Sleet passes them to the Azure Identity library.
| Variable | Value |
|---|---|
AZURE_TENANT_ID |
The Entra ID tenant ID. |
AZURE_CLIENT_ID |
The app's client ID. |
AZURE_CLIENT_SECRET |
A client secret for the app. |
AZURE_CLIENT_CERTIFICATE_PATH |
Path to a certificate, instead of a client secret. |
AZURE_CLIENT_CERTIFICATE_PASSWORD |
Password for the certificate, if it has one. |
Store the secret in your CI secret store. A certificate or a federated credential is safer than a client secret. For the full list of variables, see the Azure Identity README.
Managed identity¶
When Sleet runs on an Azure host with a managed identity, such as a virtual machine or a self-hosted build agent, no secrets are needed. Assign the role to the managed identity.
For a user-assigned managed identity, set AZURE_CLIENT_ID to the identity's client ID so Sleet uses the right one.
CI systems¶
- GitHub Actions: sign in with
azure/loginand OpenID Connect, then run Sleet in a later step. See GitHub Actions to Azure with OIDC. - Azure Pipelines: run Sleet inside an
AzureCLI@2task with an Azure Resource Manager service connection. See Azure Pipelines.
Connection strings¶
A connection string with an account key also works. The key gives full access to the whole storage account, and it doesn't expire, so use it only when Entra ID isn't an option.
DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=<account-key>;EndpointSuffix=core.windows.net
Don't put the key in a file that is checked in. Use one of these instead:
- A token in
sleet.json, such as"connectionString": "$AZURE_STORAGE_CONNECTION_STRING$". - The
SLEET_FEED_CONNECTIONSTRINGenvironment variable with--config none.
Sleet logs a warning about connection strings at the detailed verbosity level. You can ignore it if you chose this option on purpose.
Sleet doesn't read a shared access signature (SAS) from path. Only the storage account URL in path is used.
Local testing with Azurite¶
Azurite is a local emulator for Azure Storage. Use the UseDevelopmentStorage=true connection string to point Sleet at it:
{
"sources": [
{
"name": "test",
"type": "azure",
"container": "feed",
"connectionString": "UseDevelopmentStorage=true"
}
]
}
Troubleshooting¶
| Error | Fix |
|---|---|
AuthorizationPermissionMismatch or This request is not authorized to perform this operation using this permission. |
The identity is missing Storage Blob Data Contributor, or the role assignment hasn't applied yet. |
DefaultAzureCredential failed to retrieve a token |
No credential in the chain could sign in. Run az login, or set the service principal variables. |
Missing connectionString for azure account. |
Set path, or remove the empty connectionString property. |
Invalid connectionString for azure account. |
The connection string is still the template value from createconfig. Remove it and use path, or fill it in. |
Invalid feed path. Azure container ... does not match the provided URI |
path must start with the container URL, for example https://myaccount.blob.core.windows.net/feed/. |
PublicAccessNotPermitted |
The storage account doesn't allow anonymous access. See allow anonymous read access. |
For other problems, see troubleshooting.