@takodotid/azure-rest
Version:
Minimal Azure REST client with Entra ID (formerly AAD) authentication. Zero external dependencies.
408 lines (400 loc) • 15.3 kB
text/typescript
/**
* Represents an Azure access token and its expiration.
*/
type Credential = {
accessToken: string;
clientId?: string;
expiresAt: Date;
tokenType: string;
};
/**
* Abstract credential class for acquiring Azure tokens.
* Implement this to provide custom authentication logic.
*/
declare abstract class AzureCredential {
/**
* Gets an Azure access token for the given scope.
* @param scope The resource or scope for which the token is requested
* @returns A promise resolving to an AzureToken
*/
abstract getToken(scope: string): Promise<Credential>;
}
/**
* Options for configuring the AzureClient instance.
*
* @property baseUrl - The base URL for Azure REST API endpoints (e.g. https://management.azure.com)
* @property credential - Credential configuration for authenticating requests
* @property helper - An AzureCredential implementation for acquiring tokens
* @property scope - The Azure resource scope for the token (e.g. https://management.azure.com/.default)
* @property builder - (Optional) Function to build request headers from a token. If not provided, an Authorization header is set by default.
*/
type AzureClientOptions = {
baseUrl: string;
credential: {
helper: AzureCredential;
scope: string;
builder?: (token: Credential) => Record<string, string>;
};
};
/**
* Azure REST API client with credential refresh and HTTP verb helpers.
*/
declare class AzureClient {
options: AzureClientOptions;
private static readonly MAX_TOKEN_RETRIES;
private token;
/**
* @param options Azure client configuration (baseUrl, credential, etc)
*/
constructor(options: AzureClientOptions);
/**
* Sends a GET request to the Azure REST API.
* @param path The API path
* @param options Fetch options, including headers
* @returns The fetch Response object
*/
get(path: string, options?: Exclude<RequestInit, "method">): Promise<Response>;
/**
* Sends a POST request with a JSON body to the Azure REST API.
* @param path The API path
* @param options Fetch options, including body and headers
* @returns The fetch Response object
*/
post(path: string, options?: Exclude<RequestInit, "method">): Promise<Response>;
/**
* Sends a PUT request with a JSON body to the Azure REST API.
* @param path The API path
* @param options Fetch options, including body and headers
* @returns The fetch Response object
*/
put(path: string, options?: Exclude<RequestInit, "method">): Promise<Response>;
/**
* Sends a PATCH request with a JSON body to the Azure REST API.
* @param path The API path
* @param options Fetch options, including body and headers
* @returns The fetch Response object
*/
patch(path: string, options?: Exclude<RequestInit, "method">): Promise<Response>;
/**
* Sends a DELETE request to the Azure REST API.
* @param path The API path
* @param options Fetch options, including body and headers
* @returns The fetch Response object
*/
delete(path: string, options?: Exclude<RequestInit, "method">): Promise<Response>;
/**
* Sends a request to the Azure REST API, handling token refresh and retries.
* @param path The API path (relative to baseUrl)
* @param options Optional fetch options
* @returns The fetch Response object
* @throws If token refresh fails after max retries
*/
request(path: string, options?: RequestInit): Promise<Response>;
/**
* Refreshes the Azure access token using the provided credential helper.
* @private
*/
private refreshToken;
}
/**
* The raw response returned by Azure CLI when requesting an access token.
*
* @property accessToken - The access token string
* @property expiresOn - Expiry date in RFC3339 format (legacy)
* @property expires_on - Expiry as seconds since epoch (preferred)
* @property subscription - (Optional) Subscription ID, may not be present
* @property tenant - Tenant ID
* @property tokenType - Token type (usually 'Bearer')
*/
type CLITokenResponse = {
accessToken: string;
expiresOn: string;
expires_on: string;
subscription?: string;
tenant: string;
tokenType: string;
};
/**
* Options for AzureCliCredential.
*
* @property tenantId - (Optional) The Azure tenant ID to use for authentication. If not provided, will use the current Azure CLI context.
*/
type AzureCLICredentialOptions = {
tenantId?: string;
};
/**
* AzureCliCredential authenticates using the Azure CLI (`az`).
*
* - If `tenantId` is provided, uses it for token requests.
* - If not, will try `AZURE_TENANT_ID` env var, then fall back to the current Azure CLI context.
*
* Throws clear errors if the CLI is not installed or not logged in.
*/
declare class AzureCliCredential implements AzureCredential {
options: AzureCLICredentialOptions;
constructor(options: AzureCLICredentialOptions);
/**
* Instantiates AzureCliCredential using the AZURE_TENANT_ID environment variable (if set),
* or falls back to the current Azure CLI context.
* @returns AzureCliCredential instance
*/
static fromEnv(): AzureCliCredential;
/**
* Gets an Azure access token using the Azure CLI.
* @param scope The resource scope for the token (e.g. 'https://management.azure.com/.default')
* @returns An object with accessToken, expiresAt, and tokenType
* @throws If CLI is not installed or not logged in
*/
getToken(scope: string): Promise<{
accessToken: string;
expiresAt: Date;
tokenType: string;
}>;
/**
* Runs the Azure CLI to get an access token for the given scope and tenant.
* @param scope The resource scope
* @param tenantId The Azure tenant ID
* @returns Promise resolving to CLI stdout and stderr
* @private
*/
private getCliToken;
/**
* Gets the current tenant ID from Azure CLI context.
* @returns Promise resolving to the current tenant ID string
* @throws If CLI is not installed or not logged in
*/
private static getCurrentTenantId;
/**
* Parses the raw CLI output and returns a token + expiry object.
* @param output The stdout from Azure CLI
* @returns An object with accessToken, expiresAt, and tokenType
* @private
*/
private parseRawOutput;
/**
* Checks stderr for common Azure CLI login errors.
* @param stderr The stderr string from CLI
* @returns Object with isLoginError and isNotInstallError booleans
* @private
*/
private static parseCliLoginError;
}
declare global {
namespace NodeJS {
interface ProcessEnv {
AZURE_TENANT_ID: string;
}
}
}
/**
* ChainedCredential tries multiple credential providers in order until one succeeds.
*
* The chain is: WorkloadIdentityCredential → ManagedIdentityCredential → ServicePrincipalCredential → AzureCliCredential.
* Useful for local dev, CI, and cloud environments with minimal config.
*/
declare class ChainedCredential implements AzureCredential {
/**
* Attempts to get an Azure access token using the first available credential in the chain.
* @param scope The resource scope for the token
* @returns An object with token and expiresAt
* @throws If all credential providers fail
*/
getToken(scope: string): Promise<{
accessToken: string;
expiresAt: Date;
tokenType: string;
}>;
}
/**
* Options for configuring ManagedIdentityCredential.
*
* @property clientId - (Optional) The user-assigned managed identity client ID.
* @property timeoutMs - (Optional) Timeout in milliseconds for metadata endpoint fetch. Default: 300ms.
*/
type ManagedIdentityCredentialOptions = {
identityEndpoint?: string;
clientId?: string;
timeoutMs?: number;
};
/**
* AzureCredential implementation for Azure Managed Identity (MSI).
*
* Supports both system-assigned and user-assigned managed identities.
* Works on Azure VM, App Service, Container Apps, etc.
*/
declare class ManagedIdentityCredential implements AzureCredential {
options: ManagedIdentityCredentialOptions;
/**
* @param options Managed identity credential options
*/
constructor(options?: ManagedIdentityCredentialOptions);
/**
* Gets an Azure access token using the managed identity endpoint.
* @param scope The resource scope for the token
* @returns An object with token and expiresAt
* @throws If the endpoint is unavailable or token request fails
*/
getToken(scope: string): Promise<{
accessToken: string;
clientId: string | undefined;
expiresAt: Date;
tokenType: string;
}>;
/**
* Instantiates ManagedIdentityCredential using environment variables.
* This expects the following environment variables to be set:
* - AZURE_CLIENT_ID: The user-assigned managed identity client ID. This is optional for system-assigned identities.
* - AZURE_MANAGED_IDENTITY_ENDPOINT or IDENTITY_ENDPOINT: The managed identity endpoint (optional, defaults to http://169.254.169.254/metadata/identity/oauth2/token)
* - AZURE_MANAGED_IDENTITY_TIMEOUT_MS: Custom timeout for metadata endpoint fetch in milliseconds (optional).
* @returns ManagedIdentityCredential instance
*/
static fromEnv(): ManagedIdentityCredential;
}
declare global {
namespace NodeJS {
interface ProcessEnv {
AZURE_MANAGED_IDENTITY_ENDPOINT?: string;
AZURE_MANAGED_IDENTITY_TIMEOUT_MS?: string;
IDENTITY_ENDPOINT?: string;
}
}
}
/**
* The OAuth2 token response returned by Azure AD and Managed Identity endpoints.
*
* @property access_token - The access token string
* @property client_id - The client/application ID (optional, present in MSI)
* @property expires_in - Seconds until token expiry
* @property expires_on - Expiry time (epoch seconds, as string)
* @property ext_expires_in - Extended expiry in seconds
* @property not_before - Not before time (epoch seconds, as string)
* @property resource - The resource for which the token is issued
* @property token_type - The type of token (usually 'Bearer')
*/
type OAuth2TokenResponse = {
access_token: string;
client_id?: string;
expires_in: number;
expires_on: string;
ext_expires_in: number;
not_before: string;
resource: string;
token_type: string;
};
/**
* Options for configuring ServicePrincipalCredential.
*
* @property clientId - The Azure AD application (client) ID.
* @property clientSecret - The client secret or JWT assertion (for federated).
* @property tenantId - The Azure AD tenant ID.
* @property authorityHost - (Optional) The Azure AD authority host. Defaults to "https://login.microsoftonline.com".
* @property federated - Whether to use federated (JWT) auth. If true, clientSecret is treated as a JWT assertion.
*/
type ServicePrincipalCredentialOption = {
clientId: string;
clientSecret?: string;
tenantId: string;
authorityHost?: string;
federated: boolean;
};
/**
* AzureCredential implementation for authenticating with a Service Principal (client secret or federated/JWT).
*/
declare class ServicePrincipalCredential implements AzureCredential {
options: ServicePrincipalCredentialOption;
/**
* @param options Service principal credential options
*/
constructor(options: ServicePrincipalCredentialOption);
/**
* Gets an Azure access token using the service principal credentials.
* @param scope The resource scope for the token
* @returns An object with token and expiresAt
* @throws If client secret is missing or token request fails
*/
getToken(scope: string): Promise<{
accessToken: string;
clientId: string;
expiresAt: Date;
tokenType: string;
}>;
/**
* Instantiates ServicePrincipalCredential using environment variables.
* This expects the following environment variables to be set:
* - AZURE_CLIENT_ID: The Azure AD application (client) ID
* - AZURE_CLIENT_SECRET: The client secret
* - AZURE_TENANT_ID: The Azure AD tenant ID
* - AZURE_USE_FEDERATED_AUTH: Optional, if set to "true", uses federated authentication (JWT assertion).
* @returns ServicePrincipalCredential instance
*/
static fromEnv(): ServicePrincipalCredential;
}
declare global {
namespace NodeJS {
interface ProcessEnv {
AZURE_CLIENT_ID: string;
AZURE_CLIENT_SECRET: string;
AZURE_TENANT_ID: string;
AZURE_USE_FEDERATED_AUTH: "true" | "false";
}
}
}
/**
* Options for configuring WorkloadIdentityCredential.
*
* @property clientId - The Azure AD application (client) ID
* @property federatedTokenFile - Path to the federated token file (OIDC/JWT)
* @property tenantId - The Azure AD tenant ID
* @property authorityHost - (Optional) The Azure AD authority host
*/
type WorkloadIdentityCredentialOption = {
clientId: string;
federatedTokenFile: string;
tenantId: string;
authorityHost?: string;
};
/**
* AzureCredential implementation for Azure Workload Identity (OIDC federated token).
*
* Reads a federated token from file and authenticates as a service principal using JWT assertion.
*/
declare class WorkloadIdentityCredential implements AzureCredential {
options: WorkloadIdentityCredentialOption;
/**
* @param options Workload identity credential options
*/
constructor(options: WorkloadIdentityCredentialOption);
/**
* Gets an Azure access token using the federated token file.
* @param scope The resource scope for the token
* @returns An object with token and expiresAt
* @throws If the federated token file does not exist
*/
getToken(scope: string): Promise<{
accessToken: string;
clientId: string;
expiresAt: Date;
tokenType: string;
}>;
/**
* Instantiates WorkloadIdentityCredential using environment variables.
* This expects the following environment variables to be set:
* - AZURE_AUTHORITY_HOST: The Azure AD authority host (optional)
* - AZURE_CLIENT_ID: The Azure AD application (client) ID
* - AZURE_FEDERATED_TOKEN_FILE: Path to the federated token file
* - AZURE_TENANT_ID: The Azure AD tenant ID
* @returns WorkloadIdentityCredential instance
*/
static fromEnv(): WorkloadIdentityCredential;
}
declare global {
namespace NodeJS {
interface ProcessEnv {
AZURE_AUTHORITY_HOST: string;
AZURE_CLIENT_ID: string;
AZURE_FEDERATED_TOKEN_FILE: string;
AZURE_TENANT_ID: string;
}
}
}
export { type AzureCLICredentialOptions, AzureCliCredential, AzureClient, type AzureClientOptions, AzureCredential, type CLITokenResponse, ChainedCredential, type Credential, ManagedIdentityCredential, type ManagedIdentityCredentialOptions, type OAuth2TokenResponse, ServicePrincipalCredential, type ServicePrincipalCredentialOption, WorkloadIdentityCredential, type WorkloadIdentityCredentialOption };