Scenario: Globomantics is a cloud solution delivery company facing a lack of knowledge on securely configuring Azure Functions. Joe, a principal engineer, organized comprehensive training to strengthen the security posture of all Azure Functions solutions.
Table of Contents
- Azure Functions Security Fundamentals
- Managed Identities and RBAC
- Securing HTTP Endpoints
- Access Keys and Authorization
- Microsoft Entra ID and OAuth2
- Network and Isolation
- Key Vault and Secret Management
- TLS, HTTPS and Encryption
- Security Monitoring
- Complete Security Architecture
- Best Practices and Checklist
- Glossary
Module 1 – Azure Functions Security Fundamentals {#module-1}
Shared Responsibility Model in Azure Functions
The security of Azure Functions is a shared responsibility between Microsoft Azure and you as developer/architect:
flowchart TD
subgraph "Microsoft Azure Responsibility"
M1[Physical infrastructure]
M2[Hypervisor / VM Isolation]
M3[Physical network]
M4[Azure Functions Runtime platform security]
M5[Host OS patches]
end
subgraph "Your Responsibility (Developer)"
D1[Secure application code]
D2[Authentication and authorization]
D3[Secret management]
D4[HTTPS/TLS configuration]
D5[RBAC access management]
D6[Security monitoring and intrusion detection]
end
style D1 fill:#D83B01,color:#fff
style D2 fill:#D83B01,color:#fff
style D3 fill:#D83B01,color:#fff
Layered Security Architecture (Defense in Depth)
flowchart TD
Internet[Internet] --> L1
subgraph L1["Layer 1: Network"]
WAF[Azure WAF\nDDoS Protection]
FD[Azure Front Door\nGeo-filtering]
end
L1 --> L2
subgraph L2["Layer 2: Perimeter"]
APIM[Azure API Management\nRate limiting, IP filtering]
NSG[Network Security Groups]
end
L2 --> L3
subgraph L3["Layer 3: Application"]
AUTH[Authentication\nEntra ID / EasyAuth]
KEYS[Function Keys\nAuthorization Levels]
end
L3 --> L4
subgraph L4["Layer 4: Data"]
RBAC[RBAC + Managed Identity]
KV[Azure Key Vault]
ENC[Encryption at rest\nStorage/SQL/CosmosDB]
end
style L1 fill:#0078D4,color:#fff
style L2 fill:#00BCF2,color:#000
style L3 fill:#68217A,color:#fff
style L4 fill:#107C10,color:#fff
OWASP Top 10 Applied to Azure Functions
| OWASP Risk | Description | Azure Functions Mitigation |
|---|---|---|
| A01: Broken Access Control | Unauthorized resource access | RBAC, Managed Identity, Function Keys |
| A02: Cryptographic Failures | Exposed sensitive data | HTTPS only, TLS 1.2+, Azure Key Vault |
| A03: Injection | SQL, command injection | Parameterized queries, input validation |
| A05: Security Misconfiguration | Insecure default configuration | Verified Bicep templates, Azure Policy |
| A07: Authentication Failures | Poorly implemented auth | Entra ID, don’t reinvent auth |
| A09: Security Logging | Insufficient logs | Application Insights, Log Analytics |
| A10: SSRF | Server-Side Request Forgery | Validate URLs, Private Endpoints |
Module 2 – Managed Identities and RBAC {#module-2}
What is a Managed Identity?
Managed Identities allow Azure services (like Function Apps) to access other Azure resources without any secrets or connection strings. Azure fully manages the identity and token lifecycle.
Why this is revolutionary:
- ❌ Before:
Server=tcp:sql-server.database.windows.net;Password=S3cur3P@ss!;(exposable secret) - ✅ After: The Function App connects via its Azure AD identity — no secret!
Types of Managed Identities
| Type | Description | Lifecycle | Use Case |
|---|---|---|---|
| System-Assigned | Auto-created for the Function App, tied to it | Deleted with the Function App | Simple apps, unique identity |
| User-Assigned | Created independently, shareable | Persists after app deletion | Shared identity between multiple resources |
flowchart LR
subgraph "System-Assigned Managed Identity"
FA1[Function App A] -->|has an identity| MSI1[Managed Identity A]
MSI1 --> AAD1[Microsoft Entra ID]
MSI1 --> R1[Storage Blob\nData Contributor Role]
R1 --> Storage1[Azure Storage]
end
subgraph "User-Assigned Managed Identity"
UMI[User Managed Identity\n'mi-shared-storage'] --> AAD2[Microsoft Entra ID]
UMI --> R2[Assigned Role]
FA2[Function App B] --> UMI
FA3[Function App C] --> UMI
FA4[Logic App D] --> UMI
R2 --> Storage2[Azure Storage]
end
style MSI1 fill:#68217A,color:#fff
style UMI fill:#0078D4,color:#fff
Complete Managed Identity Configuration
Enable via Azure CLI
# Enable System-Assigned Managed Identity
az functionapp identity assign \
--name func-globomantics-prod \
--resource-group rg-globomantics
# Get the Principal ID
PRINCIPAL_ID=$(az functionapp identity show \
--name func-globomantics-prod \
--resource-group rg-globomantics \
--query principalId -o tsv)
# Assign required RBAC roles
# 1. Key Vault access (secret reading)
KV_RESOURCE_ID=$(az keyvault show --name kv-globomantics --query id -o tsv)
az role assignment create \
--assignee $PRINCIPAL_ID \
--role "Key Vault Secrets User" \
--scope $KV_RESOURCE_ID
# 2. Storage Blob access (read/write)
STORAGE_RESOURCE_ID=$(az storage account show \
--name stglobomantics \
--resource-group rg-globomantics \
--query id -o tsv)
az role assignment create \
--assignee $PRINCIPAL_ID \
--role "Storage Blob Data Contributor" \
--scope $STORAGE_RESOURCE_ID
# 3. Service Bus access (send/receive)
SB_RESOURCE_ID=$(az servicebus namespace show \
--name sb-globomantics \
--resource-group rg-globomantics \
--query id -o tsv)
az role assignment create \
--assignee $PRINCIPAL_ID \
--role "Azure Service Bus Data Owner" \
--scope $SB_RESOURCE_ID
Enable via Bicep
resource functionApp 'Microsoft.Web/sites@2023-01-01' = {
name: functionAppName
location: location
kind: 'functionapp'
identity: {
type: 'SystemAssigned' // ← Enables Managed Identity
}
properties: {
// ... other properties
}
}
// Assign Key Vault Secrets User role
resource keyVaultRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(keyVault.id, functionApp.id, 'KeyVaultSecretsUser')
scope: keyVault
properties: {
roleDefinitionId: subscriptionResourceId(
'Microsoft.Authorization/roleDefinitions',
'4633458b-17de-408a-b874-0445c86b69e6') // Key Vault Secrets User
principalId: functionApp.identity.principalId
principalType: 'ServicePrincipal'
}
}
Using DefaultAzureCredential in Code
using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
using Azure.Storage.Blobs;
using Azure.Messaging.ServiceBus;
public class SecureDataService
{
private readonly SecretClient _secretClient;
private readonly BlobServiceClient _blobClient;
private readonly ILogger<SecureDataService> _logger;
public SecureDataService(ILogger<SecureDataService> logger)
{
_logger = logger;
// DefaultAzureCredential automatically uses:
// 1. In production: System-Assigned Managed Identity
// 2. Locally: Azure CLI credentials (az login)
// 3. Fallback: Visual Studio credentials
var credential = new DefaultAzureCredential();
// Key Vault: NO connection string with secret!
_secretClient = new SecretClient(
new Uri(Environment.GetEnvironmentVariable("KeyVaultUri")!),
credential);
// Blob Storage: NO connection string with AccountKey!
_blobClient = new BlobServiceClient(
new Uri(Environment.GetEnvironmentVariable("BlobStorageUri")!),
credential);
}
public async Task<string> GetSecretAsync(string secretName)
{
var secret = await _secretClient.GetSecretAsync(secretName);
return secret.Value.Value;
}
}
Identity-based App Settings
# Configuration without secrets (identity-based connections)
az functionapp config appsettings set \
--name func-globomantics-prod \
--resource-group rg-globomantics \
--settings \
"KeyVaultUri=https://kv-globomantics.vault.azure.net/" \
"BlobStorageUri=https://stglobomantics.blob.core.windows.net/" \
"ServiceBusNamespace=sb-globomantics.servicebus.windows.net" \
"AzureWebJobsStorage__blobServiceUri=https://stglobomantics.blob.core.windows.net/" \
"AzureWebJobsStorage__queueServiceUri=https://stglobomantics.queue.core.windows.net/"
Important RBAC Roles for Azure Functions
| Service | Role | Permissions |
|---|---|---|
| Azure Storage | Storage Blob Data Contributor | Read, write, delete blobs |
| Azure Storage | Storage Queue Data Contributor | Read, send, delete queue messages |
| Azure Key Vault | Key Vault Secrets User | Read secrets (recommended) |
| Azure Service Bus | Azure Service Bus Data Receiver | Receive messages |
| Azure Service Bus | Azure Service Bus Data Sender | Send messages |
| Azure Cosmos DB | Cosmos DB Built-in Data Reader | Read documents |
| Azure SQL | db_datareader / db_datawriter | Via SQL CREATE USER ... FROM EXTERNAL PROVIDER |
Module 3 – Securing HTTP Endpoints {#module-3}
Azure Functions Access Key Types
flowchart TD
Request[HTTP Request] --> Validate{Access Key\nValidation}
Validate -->|Valid code| Function[Execute Function]
Validate -->|Invalid code| Reject[401 Unauthorized]
subgraph "Key types"
AnonKey[Anonymous\nNo key required]
FuncKey[Function Key\nAccess to one function]
HostKey[Host Key\nAccess to all functions]
MasterKey[Master Key\nAdmin + runtime API access]
SystemKey[System Key\nInternal extension usage]
end
| Key Type | Scope | Revocable | Appropriate Usage |
|---|---|---|---|
| Anonymous | No auth required | N/A | Health checks, public endpoints |
| Function Key | Single function | ✅ | Specific B2B integrations |
| Host Key | All functions in the app | ✅ | Multiple trusted clients |
| Master Key | Admin + all functions | ❌ (immutable) | NEVER in production! |
| System Key | Internal extensions | Partial | Event Grid, Durable Functions |
public class SecureEndpoints
{
// ❌ DANGEROUS for endpoints with sensitive data
[Function("PublicEndpoint")]
public HttpResponseData PublicEndpoint(
[HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequestData req)
{
// Only use for: health checks, truly public endpoints
var response = req.CreateResponse(System.Net.HttpStatusCode.OK);
response.WriteString("Public endpoint");
return response;
}
// ✅ Appropriate for specific service integrations
[Function("WebhookEndpoint")]
public async Task<HttpResponseData> WebhookEndpoint(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = "webhooks/payment")]
HttpRequestData req)
{
// Requires the specific key for this function
// Ideal for B2B webhooks (Stripe, GitHub, etc.)
var payload = await req.ReadFromJsonAsync<PaymentWebhookPayload>();
return req.CreateResponse(System.Net.HttpStatusCode.OK);
}
}
Secure Key Storage
By default, keys are stored in Azure Blob Storage. For increased security, store them in Azure Key Vault:
# Configure key storage in Key Vault
az functionapp config appsettings set \
--name func-globomantics-prod \
--resource-group rg-globomantics \
--settings "AzureWebJobsSecretStorageType=keyvault" \
"AzureWebJobsSecretStorageKeyVaultUri=https://kv-globomantics.vault.azure.net/"
Module 4 – Access Keys and Authorization {#module-4}
Passing the Key in the Request
# Option 1: Query string parameter (simple but visible in URL logs)
curl "https://func-globomantics.azurewebsites.net/api/myfunction?code=YOUR_KEY_HERE"
# Option 2: x-functions-key header (recommended - not visible in URL)
curl "https://func-globomantics.azurewebsites.net/api/myfunction" \
-H "x-functions-key: YOUR_KEY_HERE"
Module 5 – Microsoft Entra ID and OAuth2 {#module-5}
EasyAuth (App Service Authentication)
EasyAuth is the built-in authentication middleware of Azure App Service / Azure Functions. It fully manages OAuth2/OIDC token validation before your code is executed.
sequenceDiagram
participant Client
participant EasyAuth as EasyAuth\n(App Service Auth Middleware)
participant Entra as Microsoft Entra ID
participant Function as Your Code
Client->>EasyAuth: HTTP Request\n(without token)
EasyAuth-->>Client: 401 + Redirect URL to Entra
Client->>Entra: User authentication
Entra-->>Client: JWT Token (id_token + access_token)
Client->>EasyAuth: Request with Bearer Token
EasyAuth->>Entra: Validate token
Entra-->>EasyAuth: Token valid
EasyAuth->>Function: Request + Injected Headers\n(X-MS-CLIENT-PRINCIPAL, etc.)
Function-->>EasyAuth: Response
EasyAuth-->>Client: Response
EasyAuth configuration via CLI:
az webapp auth microsoft update \
--name func-globomantics-prod \
--resource-group rg-globomantics \
--client-id "your-app-registration-client-id" \
--client-secret "your-client-secret" \
--issuer "https://login.microsoftonline.com/{tenant-id}/v2.0"
az webapp auth update \
--name func-globomantics-prod \
--resource-group rg-globomantics \
--enabled true \
--action LoginWithAzureActiveDirectory
Reading Identity Information from EasyAuth Headers
[Function("ProfileFunction")]
public HttpResponseData Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequestData req)
{
string? principalHeader = req.Headers
.GetValues("x-ms-client-principal")
?.FirstOrDefault();
if (principalHeader == null)
return req.CreateResponse(HttpStatusCode.Unauthorized);
byte[] decoded = Convert.FromBase64String(principalHeader);
var principal = JsonSerializer.Deserialize<ClientPrincipal>(
Encoding.UTF8.GetString(decoded));
string userName = req.Headers
.GetValues("x-ms-client-principal-name")
?.FirstOrDefault() ?? "unknown";
var response = req.CreateResponse(HttpStatusCode.OK);
await response.WriteStringAsync($"Hello, {userName}!");
return response;
}
public record ClientPrincipal(
string auth_type,
string name_type,
string role_type,
List<ClaimRecord> claims);
public record ClaimRecord(string typ, string val);
Module 6 – Network and Isolation {#module-6}
Secure Network Configuration
flowchart TB
Internet[Internet] --> WAF[Azure WAF / Front Door]
WAF --> APIM[Azure API Management\nSubnet: snet-apim]
subgraph VNet["Virtual Network: vnet-globomantics"]
subgraph SnetAPIM["Subnet: snet-apim"]
APIM
end
subgraph SnetFunc["Subnet: snet-functions"]
FA[Function App\nVNet Integration]
end
subgraph SnetData["Subnet: snet-data"]
SQL["Azure SQL\nPrivate Endpoint"]
COSMOS["Cosmos DB\nPrivate Endpoint"]
end
end
APIM -->|Private Endpoint| FA
FA -->|Private Endpoint| SQL
FA -->|Private Endpoint| COSMOS
style FA fill:#68217A,color:#fff
style WAF fill:#0078D4,color:#fff
# Complete network configuration
# 1. Create the VNet and subnets
az network vnet create \
--name vnet-globomantics \
--resource-group rg-globomantics \
--address-prefix 10.0.0.0/16
az network vnet subnet create \
--vnet-name vnet-globomantics \
--resource-group rg-globomantics \
--name snet-functions \
--address-prefix 10.0.2.0/24 \
--delegations Microsoft.Web/serverFarms
# 2. VNet Integration for the Function App (Premium required)
az functionapp vnet-integration add \
--name func-globomantics-prod \
--resource-group rg-globomantics \
--vnet vnet-globomantics \
--subnet snet-functions
# 3. Restrict inbound access (IP allowlist)
az functionapp config access-restriction add \
--name func-globomantics-prod \
--resource-group rg-globomantics \
--rule-name "AllowAPIMOnly" \
--action Allow \
--ip-address "10.0.1.0/24" \
--priority 100
# 4. Create Private Endpoint for SQL Database
az network private-endpoint create \
--name pe-sql-globomantics \
--resource-group rg-globomantics \
--vnet-name vnet-globomantics \
--subnet snet-data \
--private-connection-resource-id $(az sql server show \
--name sql-globomantics \
--resource-group rg-globomantics \
--query id -o tsv) \
--group-id sqlServer \
--connection-name "sql-connection"
Module 7 – Key Vault and Secret Management {#module-7}
Key Vault References in App Settings
Key Vault References allow referencing Key Vault secrets directly in App Settings, without ever copying the secret value.
sequenceDiagram
participant Admin as Administrator
participant KV as Azure Key Vault
participant FA as Function App
participant Code as Your Code
Admin->>KV: Create secret "sql-connection-string"
Admin->>FA: Configure App Setting:\n@Microsoft.KeyVault(SecretUri=...)
Note over FA,KV: On Function App startup
FA->>KV: Request the secret (via Managed Identity)
KV-->>FA: Secret value
FA->>Code: Inject as environment variable
Code-->>FA: Use as normal string
# 1. Create Key Vault and secrets
az keyvault create \
--name kv-globomantics \
--resource-group rg-globomantics \
--location eastus \
--enable-rbac-authorization true \
--enable-soft-delete true \
--soft-delete-retention-days 90
# 2. Add secrets
az keyvault secret set \
--vault-name kv-globomantics \
--name "sql-connection-string" \
--value "Server=tcp:sql-globomantics.database.windows.net;..."
# 3. Configure App Settings with Key Vault references
SQL_SECRET_URI=$(az keyvault secret show \
--vault-name kv-globomantics \
--name "sql-connection-string" \
--query id -o tsv)
az functionapp config appsettings set \
--name func-globomantics-prod \
--resource-group rg-globomantics \
--settings \
"SqlConnectionString=@Microsoft.KeyVault(SecretUri=$SQL_SECRET_URI)"
Transparent access in code:
// Azure Functions automatically resolves the Key Vault reference
// No Key Vault SDK needed here!
public class PaymentFunction
{
private readonly string _stripeSecretKey;
public PaymentFunction()
{
_stripeSecretKey = Environment.GetEnvironmentVariable("StripeSecretKey")
?? throw new InvalidOperationException("Stripe secret key not configured");
}
}
Module 8 – TLS, HTTPS and Encryption {#module-8}
HTTPS and TLS Configuration
# Force HTTPS only
az functionapp update \
--name func-globomantics-prod \
--resource-group rg-globomantics \
--set httpsOnly=true
# Configure minimum TLS version (TLS 1.2 minimum)
az functionapp config set \
--name func-globomantics-prod \
--resource-group rg-globomantics \
--min-tls-version 1.2
# Disable FTP (FTPS)
az functionapp config set \
--name func-globomantics-prod \
--resource-group rg-globomantics \
--ftps-state Disabled
Configuration via Bicep:
resource functionApp 'Microsoft.Web/sites@2023-01-01' = {
properties: {
httpsOnly: true
siteConfig: {
ftpsState: 'Disabled'
minTlsVersion: '1.2'
http20Enabled: true
}
}
}
Module 9 – Security Monitoring {#module-9}
KQL Queries for Security Audit
// Detect unauthorized access attempts (HTTP 401/403)
requests
| where timestamp > ago(24h)
| where resultCode in ("401", "403")
| summarize Count = count() by bin(timestamp, 1h), name, client_IP
| where Count > 10 // Alert threshold
| order by Count desc
// Audit configuration changes
AzureActivity
| where OperationNameValue contains "Microsoft.Web/sites"
| where ActivityStatusValue == "Success"
| where OperationNameValue contains "write"
| project TimeGenerated, Caller, OperationNameValue, ResourceGroup, Resource
| order by TimeGenerated desc
// Detect connections from unknown IPs
SigninLogs
| where AppDisplayName contains "Globomantics"
| where RiskState != "none" // Risky connections
| project TimeGenerated, UserPrincipalName, IPAddress, RiskLevelAggregated, Location
| order by TimeGenerated desc
Module 10 – Complete Security Architecture {#module-10}
flowchart TB
subgraph "Internet"
Client[External Client]
end
subgraph "DMZ Zone"
WAF[Azure WAF\n+ DDoS Protection]
AFD[Azure Front Door\nGeo-filtering, SSL termination]
end
subgraph "API Management Zone"
APIM[Azure API Management\nRate limiting, OAuth2 validation\nIP filtering, Logging]
end
subgraph "Functions Zone (VNet)"
FA[Function App\nManaged Identity\nHTTPS only, TLS 1.2+]
end
subgraph "Data Zone (VNet - Private)"
SQL["Azure SQL\nPrivate Endpoint\nTDE, Always Encrypted"]
COSMOS["Cosmos DB\nPrivate Endpoint\nEncryption at rest"]
KV[Azure Key Vault\nPremium tier\nHSM backed]
end
subgraph "Cross-cutting Security"
ENTRA[Microsoft Entra ID\nConditional Access\nMFA]
ASC[Defender for Cloud\nSecurity recommendations]
SENT[Microsoft Sentinel\nSIEM, threat detection]
LOG[Log Analytics\nAudit logs, KQL queries]
end
Client --> WAF --> AFD --> APIM
APIM -->|Private Endpoint| FA
FA -->|Private Endpoint + MSI| SQL
FA -->|Private Endpoint + MSI| COSMOS
FA -->|MSI| KV
ENTRA -.->|Authentication| APIM & FA
ASC -.->|Monitoring| FA & SQL & COSMOS
LOG -.->|Logs| FA & APIM
SENT -.->|Analysis| LOG
style FA fill:#68217A,color:#fff
style KV fill:#FFB900,color:#000
style ENTRA fill:#0078D4,color:#fff
Module 11 – Best Practices and Checklist {#module-11}
Azure Functions Security Checklist
| Category | Check | Priority |
|---|---|---|
| Identity | Managed Identity enabled (System-Assigned minimum) | 🔴 Critical |
| Identity | No connection strings with keys in App Settings | 🔴 Critical |
| Identity | Identity-based connections for Storage, Service Bus, Cosmos DB | 🔴 Critical |
| Secrets | Key Vault References for all secrets | 🔴 Critical |
| Secrets | No secrets in source code or Git commits | 🔴 Critical |
| Network | HTTPS Only enabled | 🔴 Critical |
| Network | TLS 1.2 minimum configured | 🔴 Critical |
| Network | FTP/FTPS disabled | 🟡 Important |
| Network | CORS explicitly configured (not * in prod) | 🟡 Important |
| HTTP Auth | AuthLevel.Anonymous only for health checks | 🟡 Important |
| HTTP Auth | Master Key NEVER used in client applications | 🔴 Critical |
| HTTP Auth | EasyAuth or APIM for public APIs | 🟡 Important |
| Advanced Network | VNet Integration (Premium plan) | 🟢 Recommended |
| Advanced Network | Private Endpoints for data services | 🟢 Recommended |
| Monitoring | Application Insights configured | 🟡 Important |
| Monitoring | Alerts on 401/403 errors | 🟡 Important |
| Compliance | Defender for App Service enabled | 🟡 Important |
| RBAC | Least privilege principle for all roles | 🔴 Critical |
Security Scenario Reference (Globomantics)
| Target Service | Secure Access Method |
|---|---|
| Azure Key Vault | Managed Identity + RBAC role “Key Vault Secrets User” |
| Storage Account | Managed Identity + RBAC role “Storage Blob Data Contributor” |
| Azure SQL Database | Managed Identity + access via Entra ID (no SQL password) |
| Public HTTP Endpoints | EasyAuth (Entra ID) or APIM with OAuth |
Module 7 – Managed Identity: Deep Dive {#module-7-deep-dive}
DefaultAzureCredential: Authentication Chain
DefaultAzureCredential from the Azure.Identity library tries identity sources in this order:
flowchart TD
A[DefaultAzureCredential] --> B{Environment variable\nAZURE_CLIENT_ID?}
B -- Yes --> C[EnvironmentCredential\nClient ID + Secret/Cert]
B -- No --> D{Workload Identity\nin Kubernetes?}
D -- Yes --> E[WorkloadIdentityCredential]
D -- No --> F{Managed Identity\navailable?}
F -- Yes --> G[ManagedIdentityCredential\n✅ Azure Production]
F -- No --> H{Visual Studio\nconfigured?}
H -- Yes --> I[VisualStudioCredential\n✅ Local development]
H -- No --> J{Azure CLI\nconnected?}
J -- Yes --> K[AzureCliCredential\n✅ Local CLI dev]
Managed Identity for Azure SQL Database
// SQL connection with Managed Identity (no password!)
using Microsoft.Data.SqlClient;
var connectionString =
"Server=myserver.database.windows.net;" +
"Database=mydb;" +
"Authentication=Active Directory Managed Identity;";
using var connection = new SqlConnection(connectionString);
await connection.OpenAsync();
// Entra ID manages authentication automatically
-- In Azure SQL: create user for the Managed Identity
CREATE USER [myFunctionApp] FROM EXTERNAL PROVIDER;
ALTER ROLE db_datareader ADD MEMBER [myFunctionApp];
ALTER ROLE db_datawriter ADD MEMBER [myFunctionApp];
Glossary {#glossary}
| Term | Definition |
|---|---|
| APIM | Azure API Management - gateway for securing and managing APIs |
| CORS | Cross-Origin Resource Sharing - cross-domain request control |
| DefaultAzureCredential | Azure SDK class that automatically detects available credentials |
| EasyAuth | App Service Authentication - built-in authentication middleware |
| Entra ID | Microsoft Entra ID (formerly Azure Active Directory) - identity service |
| FTPS | FTP over SSL - secure transfer protocol (disable if unused) |
| HSM | Hardware Security Module - physical chip for storing cryptographic keys |
| JWT | JSON Web Token - standard format for authentication tokens |
| Key Vault Reference | @Microsoft.KeyVault(...) in App Settings - automatic secret resolution |
| Managed Identity | Azure AD identity automatically managed by Azure for a resource |
| OAuth 2.0 | Authorization protocol for APIs |
| OIDC | OpenID Connect - extension of OAuth 2.0 for authentication |
| OWASP | Open Web Application Security Project - organization defining web risks |
| Private Endpoint | Private network connection to an Azure service via VNet |
| RBAC | Role-Based Access Control - Azure role-based access control |
| System-Assigned MSI | Managed Identity tied to the lifecycle of an Azure resource |
| TDE | Transparent Data Encryption - automatic encryption of SQL data at rest |
| TLS | Transport Layer Security - encryption protocol for HTTPS communications |
| User-Assigned MSI | Independent Managed Identity, shareable between multiple resources |
| VNet | Virtual Network - virtual private network in Azure |
| VNet Integration | Connecting a Function App to a VNet to access private resources |
| WAF | Web Application Firewall - application firewall against web attacks |
| Zero Trust | Security model: never trust, always verify |
Search Terms
securing · azure · functions · serverless · microsoft · security · managed · identity · app · configuration · access · architecture · authentication · checklist · defaultazurecredential · easyauth · enable · https · identities · network · rbac · secure · settings · tls