diff --git a/R/get_auth_token.R b/R/get_auth_token.R index 3a0e7a5..7184fd2 100644 --- a/R/get_auth_token.R +++ b/R/get_auth_token.R @@ -52,8 +52,8 @@ #' #' # Get a token for a specific resource and tenant #' token <- get_auth_token( -#' resource = "https://graph.microsoft.com", -#' tenant = "my-tenant-id" +#' resource = "https://graph.microsoft.com", +#' tenant = "my-tenant-id" #' ) #' #' # Get a token using a specific app ID @@ -93,7 +93,7 @@ get_auth_token <- function( token_error <- token_resp[["error"]] # 2. Try to get a managed token (for example on Azure VM, App Service) - if (is.null(token)) { + if (is.null(token) && imds_available()) { token <- rlang::inject(possibly_get_mtk(resource, !!!dots)) } @@ -273,3 +273,45 @@ generate_resource <- function( #' @returns An Azure authentication token #' @export refresh_token <- \(token) token$refresh() + +#' Check if Azure Instance Metadata Service (IMDS) is Available +#' +#' This function checks if the Azure Instance Metadata Service (IMDS) is +#' available by attempting to make a request to the IMDS endpoint. The result is +#' cached in an environment variable for future use, saving the need for +#' repeated checks. +#' +#' You can also set the `IMDS_AVAILABLE` environment variable manually to +#' "TRUE" or "FALSE" to override the automatic check, which can be useful for +#' testing or in environments where the check may not work correctly. +imds_available <- function() { + available <- Sys.getenv("IMDS_AVAILABLE") + + if (available == "") { + available <- tryCatch( + { + Sys.getenv( + "MSI_ENDPOINT", + "http://169.254.169.254/metadata/identity/oauth2" + ) |> + httr2::request() |> + httr2::req_headers(Metadata = "true") |> + httr2::req_timeout(0.2) |> + httr2::req_perform() + + TRUE + }, + error = function(e) FALSE + ) + Sys.setenv(IMDS_AVAILABLE = available) + } + + switch(toupper(available), "TRUE" = TRUE, "FALSE" = FALSE, { + warning( + "Invalid value for IMDS_AVAILABLE environment variable: ", + available, + ". Expected 'true' or 'false'. Defaulting to FALSE." + ) + FALSE + }) +} diff --git a/man/get_auth_token.Rd b/man/get_auth_token.Rd index a966358..68d2e10 100644 --- a/man/get_auth_token.Rd +++ b/man/get_auth_token.Rd @@ -77,8 +77,8 @@ token <- get_auth_token(force_refresh = TRUE) # Get a token for a specific resource and tenant token <- get_auth_token( - resource = "https://graph.microsoft.com", - tenant = "my-tenant-id" + resource = "https://graph.microsoft.com", + tenant = "my-tenant-id" ) # Get a token using a specific app ID diff --git a/man/imds_available.Rd b/man/imds_available.Rd new file mode 100644 index 0000000..22abcc6 --- /dev/null +++ b/man/imds_available.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/get_auth_token.R +\name{imds_available} +\alias{imds_available} +\title{Check if Azure Instance Metadata Service (IMDS) is Available} +\usage{ +imds_available() +} +\description{ +This function checks if the Azure Instance Metadata Service (IMDS) is +available by attempting to make a request to the IMDS endpoint. The result is +cached in an environment variable for future use, saving the need for +repeated checks. +} +\details{ +You can also set the \code{IMDS_AVAILABLE} environment variable manually to +"TRUE" or "FALSE" to override the automatic check, which can be useful for +testing or in environments where the check may not work correctly. +}