azr implements a credential chain for seamless OAuth 2.0 authentication to Azure services. It builds on httr2's OAuth framework to provide cache and automatic credential discovery, trying different authentication methods in sequence until one succeeds.
You can install azr from CRAN with:
install.packages("azr")
The package supports creating Credential chains for Authentication with:
az) loginDuring interactive development, azr allows browser-based login flows, while in batch/production mode it seamlessly falls back to non-interactive methods.
The simplest way to authenticate is using get_token(), which automatically tries different authentication methods until one succeeds:
library(azr)
# Get a token using the default credential chain
token <- get_token(
tenant_id = "your-tenant-id",
scope = "https://management.azure.com/.default"
)
# Use the token with httr2
library(httr2)
req <- request("https://management.azure.com/subscriptions?api-version=2020-01-01") |>
req_auth_bearer_token(token$access_token)
resp <- req_perform(req)
Alternatively, use get_request_authorizer() to get a function that adds authentication to requests:
library(azr)
library(httr2)
# Get a request authorizer for Microsoft Graph API
azr_req_auth <- get_request_authorizer(
tenant_id = "your-tenant-id",
scope = "https://graph.microsoft.com/.default"
)
# Use it to authenticate requests
resp <- request("https://graph.microsoft.com/v1.0/me") |>
azr_req_auth() |>
req_perform()
You can customize which authentication methods are tried and in what order:
# Define a custom credential chain: try a service principal first, then fall
# back to the developer's Azure CLI login ('az login')
custom_chain <- credential_chain(
client_secret = ClientSecretCredential,
azure_cli = AzureCLICredential
)
# Use the custom chain - scope, tenant_id, client_id, and client_secret are
# forwarded to whichever entry ends up succeeding
token <- get_token(
scope = "https://management.azure.com/.default",
tenant_id = "mycompany-tenant-id",
# the 'Application Id' and secret used in production/batch mode
client_id = Sys.getenv("APP_CLIENT_ID"),
client_secret = Sys.getenv("APP_CLIENT_SECRET"),
chain = custom_chain
)
You can use get_credential_auth() to create a chat connection to Azure OpenAI with the ellmer package:
library(ellmer)
# Create an authentication function for Azure OpenAI
credentials <- azr::get_credential_auth(
scope = "https://cognitiveservices.azure.com/.default"
)
# Create a chat interface to Azure OpenAI
chat <- chat_azure_openai(
endpoint = "https://your-resource.openai.azure.com",
model = "gpt-4o",
credentials = credentials
)
# Use the chat
chat$chat("What is the capital of France?")
azr also ships the pieces that usually come next once a token is in hand.
get_user_token() authenticates the person signed in on the machine rather
than the host's service identity, and az_config() reports the Azure
environment variables that credential discovery reads. azr_storage_client()
and azr_logs_client() wrap the Storage and Log Analytics REST APIs, and
azr_dataset() declares a storage dataset bound to one or more storage
accounts keyed by environment tier, so that every consumer resolves it the
same way.
vignette("credential-chains") on building credential chains.vignette("datasets") on declaring Azure Storage datasets.vignette("options") on configuring azr options.azr is inspired by Python's azure-identity, which introduced the credential chain pattern for automatic authentication method discovery.
The R package AzureAuth (based on httr) also handles Azure token acquisition, but does not offer explicit credential chains. azr fills that gap by letting you define custom chains with method-specific configurations, enabling seamless fallback between authentication approaches.
Please note that the azr project is released with a Contributor Code of Conduct. By contributing to this project, you agree to abide by its terms.