Free Ebook cover Serverless on Azure: Building with Azure Functions and Event Triggers

Serverless on Azure: Building with Azure Functions and Event Triggers

New course

10 pages

Configuration and Secrets: App Settings, Key Vault, and Managed Identity

Capítulo 5

Estimated reading time: 9 minutes

+ Exercise

Configuration sources: local vs cloud

In Azure Functions, configuration should be portable (works across environments) and secure (secrets are not stored in code or developer machines longer than necessary). The key idea is to treat configuration as external inputs and to separate non-secret settings (feature flags, endpoints) from secrets (keys, passwords, tokens).

Local development: local.settings.json (local only)

local.settings.json is intended for local execution only. It is not deployed to Azure and should not be used as a long-term secret store. Keep it out of source control (typically via .gitignore).

{  "IsEncrypted": false,  "Values": {    "AzureWebJobsStorage": "UseDevelopmentStorage=true",    "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",    "MyApp__Environment": "dev",    "ServiceBus__FullyQualifiedNamespace": "mybus.servicebus.windows.net",    "ServiceBus__QueueName": "orders"  }}

Use it to provide developer-friendly defaults and to point to local emulators or non-production resources. If you must use secrets locally, prefer short-lived credentials (for example, developer sign-in) rather than copying production secrets.

Cloud: Function App Application Settings (App Settings)

In Azure, configuration is typically stored in the Function App’s Application Settings. These are injected into the runtime as environment variables. They can be set per environment (dev/test/prod) and updated without redeploying code.

  • Non-secret settings: safe to store as App Settings.
  • Secrets: store as Key Vault secrets and reference them from App Settings (so the Function App never contains the secret value directly).

How settings map to environment variables

Azure Functions reads configuration from environment variables. Both local.settings.json (when running locally) and App Settings (in Azure) are surfaced as environment variables at runtime.

Continue in our app.

You can listen to the audiobook with the screen off, receive a free certificate for this course, and also have access to 5,000 other free online courses.

Or continue reading below...
Download App

Download the app

Naming conventions and nested configuration

Many frameworks support hierarchical configuration via double underscores (__). For example, ServiceBus__QueueName maps to ServiceBus:QueueName in hierarchical configuration providers.

// Example (C#) reading environment variables directlyvar queueName = Environment.GetEnvironmentVariable("ServiceBus__QueueName");if (string.IsNullOrWhiteSpace(queueName)) {    throw new InvalidOperationException("Missing configuration: ServiceBus__QueueName");}

Keep names consistent across local and cloud. A common pattern is to define a small set of prefixes (for example, ServiceBus__, Storage__, ExternalApi__) to make configuration discoverable and to reduce collisions.

Key Vault references: keeping secrets out of App Settings

Azure Key Vault is designed to store secrets, keys, and certificates with auditing and access control. Instead of placing secret values in App Settings, you store a Key Vault reference in App Settings. At runtime, the platform resolves the reference and injects the secret value as an environment variable.

Pattern: App Setting points to a Key Vault secret

In the Function App configuration, set an App Setting value to a Key Vault reference (format varies by platform features, but the intent is: “this setting’s value comes from Key Vault”). The application code continues to read the setting by name, without knowing it came from Key Vault.

// Code reads the same setting name regardless of sourcevar apiKey = Environment.GetEnvironmentVariable("ExternalApi__ApiKey");

Operationally, this gives you:

  • Centralized secret storage with access policies/RBAC.
  • Audit logs for secret access.
  • Secret rotation without code changes.
  • Reduced risk of accidental exposure in deployment pipelines.

Managed Identity: secretless access to Azure resources

Managed Identity lets your Function App authenticate to Azure services without storing credentials. Instead of connection strings with keys/passwords, the Function App obtains an Azure AD token automatically and uses it to access resources that grant it permissions.

When to use Managed Identity

  • Accessing Key Vault to resolve secrets or read certificates.
  • Connecting to Azure Storage, Service Bus, Event Hubs, Cosmos DB, SQL (where supported) using Azure AD authentication.
  • Calling other Azure services protected by Azure AD.

Step-by-step: enable and use Managed Identity with Key Vault

  • Enable a Managed Identity on the Function App (system-assigned is simplest; user-assigned is useful for sharing identity across apps or for controlled lifecycle).
  • Grant that identity least-privilege access in Key Vault (prefer RBAC roles like “Key Vault Secrets User” scoped to the vault, or narrower if available).
  • Create Key Vault secrets (for example, ExternalApi--ApiKey, Db--ConnectionString).
  • In Function App App Settings, set ExternalApi__ApiKey to a Key Vault reference pointing to the secret.
  • In code, read ExternalApi__ApiKey normally; do not embed Key Vault logic unless you have a specific need (for example, multi-vault routing).

This approach keeps the Function App “secretless”: it holds only references and an identity, not secret values.

Rotation patterns: changing secrets safely

Rotation should be routine, low-risk, and ideally not require code changes. Choose a rotation pattern based on whether clients can tolerate brief overlap and whether the downstream system supports multiple active credentials.

Pattern A: versioned secrets with controlled cutover

  • Create a new version of the secret in Key Vault (same secret name, new version).
  • Update the Key Vault reference (if you pin to a version) or keep it unpinned (if you want “latest”).
  • Deploy configuration change (no code deployment needed).
  • Monitor errors and latency; roll back by pointing to the previous version if needed.

Recommendation: for critical systems, pin to a specific version so you control cutover and rollback explicitly.

Pattern B: dual credentials (blue/green) for zero-downtime rotation

If the downstream system supports two valid keys at once (common for API keys), rotate with overlap:

  • Store ExternalApi__ApiKeyPrimary and ExternalApi__ApiKeySecondary in Key Vault.
  • Application tries primary; if unauthorized, tries secondary (or uses a feature flag to select which is active).
  • Rotate the inactive key first, validate, then switch active key, then rotate the other.
// Pseudocode: fallback to secondary on auth failurevar primary = Get("ExternalApi__ApiKeyPrimary");var secondary = Get("ExternalApi__ApiKeySecondary");try {    CallApi(primary);} catch (UnauthorizedException) {    CallApi(secondary);}

Pattern C: move away from secrets entirely

Where possible, replace secrets with identity-based access:

  • Use Managed Identity + RBAC for Azure resources (Storage, Service Bus, etc.).
  • Use Azure AD app roles/scopes for internal APIs.
  • Use certificates (stored in Key Vault) instead of client secrets for Azure AD app authentication when required.

Handling missing or invalid configuration

Functions often fail in confusing ways when configuration is missing. Make failures explicit and early, but avoid leaking sensitive values in error messages.

Step-by-step: validate configuration at startup

  • Define a list of required setting names (secrets and non-secrets).
  • On startup, check presence and basic format (for example, URI parse, non-empty strings).
  • Fail fast with a clear message that names the missing key, not its value.
  • For optional settings, provide safe defaults (for example, disabled features) rather than guessing.
// Example validation helper (C#)static string RequireSetting(string name) {    var value = Environment.GetEnvironmentVariable(name);    if (string.IsNullOrWhiteSpace(value)) {        throw new InvalidOperationException($"Missing required configuration: {name}");    }    return value;}

Operational tip: distinguish “missing” vs “access denied”

With Key Vault references and Managed Identity, a missing value can mean:

  • The App Setting key is not defined.
  • The Key Vault reference is malformed.
  • The identity lacks permission to read the secret.
  • Network restrictions prevent access to Key Vault.

Log the setting name and a high-level category (missing/forbidden/unreachable), but never log the secret or the full reference URI if it contains identifying details you consider sensitive.

Avoiding accidental secret leaks (logs, exceptions, and tooling)

Secret leaks commonly happen through logs, exception messages, and “helpful” debugging output. Adopt defensive patterns so secrets are never printed, even during failures.

Rules of thumb

  • Never log entire configuration objects.
  • Never log connection strings, SAS tokens, API keys, JWTs, or Authorization headers.
  • When logging configuration, log only presence/absence and non-sensitive metadata (for example, hostnames, not credentials).
  • Use structured logging and explicit allowlists of fields to log.

Step-by-step: safe logging pattern for connection info

  • Parse the value and extract non-secret parts (for example, endpoint host).
  • Log only the extracted non-secret parts.
  • If parsing fails, log a generic message and the setting name.
// Pseudocode: log only host, not full connection stringvar cs = RequireSetting("Storage__ConnectionString");var host = ExtractHost(cs);logger.LogInformation("Storage configured for host {Host}", host);

Preventing leaks in local workflows

  • Keep local.settings.json out of source control.
  • Avoid copying production secrets into local files; prefer developer identity or dedicated dev resources.
  • Use separate dev Key Vault and dev resources with limited blast radius.
  • Review CI/CD logs: ensure tasks do not echo secrets; mark secret variables as secret in pipeline tooling.

Checklist: secure configuration and secret handling

Configuration hygiene

  • Settings names are consistent across environments (same keys locally and in Azure).
  • Non-secret configuration is stored in App Settings; secrets are stored in Key Vault.
  • local.settings.json is excluded from source control and contains only dev-safe values.
  • Required settings are validated at startup with clear “missing key” errors.

Key Vault and identity

  • Function App uses Managed Identity (system- or user-assigned) for Azure access.
  • Key Vault access is granted via least-privilege RBAC/permissions (only secrets needed, scoped appropriately).
  • Key Vault references are used in App Settings so secret values are not stored in the Function App configuration.
  • Network access to Key Vault is controlled (private endpoints/firewall rules) consistent with your environment needs.

Connection strings and credentials

  • Prefer Azure AD/Managed Identity authentication over key-based connection strings when supported.
  • If connection strings are required, store them in Key Vault and reference them; do not hardcode them.
  • Use separate resources and credentials per environment (dev/test/prod), never shared production secrets.
  • Rotation plan exists (versioned or dual-key) and rollback is documented.

Logging and diagnostics

  • Logs never include secrets, tokens, Authorization headers, or full connection strings.
  • Error messages identify missing setting names, not values.
  • Any “dump config” debug utilities are removed or gated behind safe development-only switches that still redact secrets.

Safe local developer experience

  • Developers can run locally using emulators or dev resources without needing production secrets.
  • Dev Key Vault (if used) contains only dev secrets; access is time-bound and audited.
  • Documentation includes a minimal set of required local settings and how to obtain them securely.

Now answer the exercise about the content:

Which approach best keeps secrets out of an Azure Function App while still allowing the function code to read configuration by name?

You are right! Congratulations, now go to the next page

You missed! Try again.

Secrets should live in Key Vault, with App Settings holding only references. Managed Identity enables access without stored credentials, and the code reads the same setting name as an environment variable.

Next chapter

Deployment Options: From Local to Azure with Repeatable Releases

Arrow Right Icon
Download the app to earn free Certification and listen to the courses in the background, even with the screen off.