Skip to main content

03 - Security

Comprehensive security patterns including OWASP protection, network isolation, and authentication

WAF Pillar


📋 WAF Workload Design Checklist

Based on Azure Well-Architected Framework - Security Checklist

#RecommendationStatus
(Service) Establish security baseline from API Management Security Baseline
(Service) Disable the direct management API (deprecated) - use Azure Resource Manager
(Service) Disable developer portal if not in use; if used, disable anonymous access
(Service) Limit gateway exposure to legitimate client sources using VNet/NSG
(Service) Set narrowest supported TLS versions (minimum 1.2, prefer 1.3)
(Service) Store custom certificates in Key Vault
(Service) Backends should only accept traffic from API gateways
(Service) Use workspaces for team isolation on shared instances
(API) Store secrets in Key Vault, expose through named values
(API) Use different managed identities for different APIs
(API) Require OAuth 2.0 over preshared keys where possible
(API) Suppress HTTP headers that expose implementation details
(API) Don't use API tracing in production
(API) Use Defender for APIs for security insights and threat detection
(API) Protect backends with validate-jwt, ip-filter, validate-headers, validate-content
(Service & API) Use managed identities for all service dependencies
(Service & API) Use private network connections for Key Vault, Event Hubs, backends
(Service & API) Use WAF and DDoS Protection for internet-exposed APIs

🔐 Critical WAF Security Configurations

Disable Direct Management API

resource apim 'Microsoft.ApiManagement/service@2023-05-01-preview' = {
name: apimName
location: location
properties: {
// Disable deprecated direct management API
disableGateway: false
apiVersionConstraint: {
minApiVersion: '2019-12-01' // Enforce minimum API version
}
}
}

Microsoft Defender for APIs

// Enable Defender for Cloud on the subscription
resource defenderForAPIs 'Microsoft.Security/pricings@2023-01-01' = {
name: 'Api'
properties: {
pricingTier: 'Standard'
}
}

Defender for APIs provides:

  • API security insights and recommendations
  • Threat detection for anomalous API usage
  • Integration with Microsoft Sentinel for SIEM

🎯 Security Goals

GoalImplementation
ConfidentialityTLS 1.2+, encryption at rest, private networks
IntegrityInput validation, content verification, signing
AvailabilityDDoS protection, rate limiting, WAF
AuthenticationOAuth 2.0, JWT validation, managed identities
AuthorizationRBAC, product subscriptions, policy enforcement

🏗️ Security Architecture


🔐 TLS & Protocol Hardening

Disable Insecure Protocols (Bicep)

resource apim 'Microsoft.ApiManagement/service@2023-05-01-preview' = {
name: apimName
location: location
properties: {
customProperties: {
// Disable legacy TLS versions
'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Protocols.Tls10': 'false'
'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Protocols.Tls11': 'false'
'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Protocols.Ssl30': 'false'

// Disable for backend connections too
'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Backend.Protocols.Tls10': 'false'
'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Backend.Protocols.Tls11': 'false'
'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Backend.Protocols.Ssl30': 'false'

// Disable weak ciphers
'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Ciphers.TripleDes168': 'false'
'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Ciphers.TLS_RSA_WITH_AES_128_CBC_SHA': 'false'
'Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Ciphers.TLS_RSA_WITH_AES_256_CBC_SHA': 'false'

// Enable HTTP/2
'Microsoft.WindowsAzure.ApiManagement.Gateway.Protocols.Server.Http2': 'true'
}
}
}

TLS Configuration Summary

SettingRecommendation
Minimum TLS1.2 (1.3 when clients support)
SSL 3.0❌ Disabled
TLS 1.0❌ Disabled
TLS 1.1❌ Disabled
3DES Cipher❌ Disabled
HTTP/2✅ Enabled

🛡️ OWASP API Security Top 10

Protection Matrix

OWASP ThreatAPIM MitigationPolicy
API1: Broken Object Level Authvalidate-jwt with claimsvalidate-jwt, validate-azure-ad-token
API2: Broken AuthenticationOAuth 2.0, Entra IDvalidate-azure-ad-token
API3: Broken Object Property Level AuthContent validationvalidate-content
API4: Unrestricted Resource ConsumptionRate limitingrate-limit, quota
API5: Broken Function Level AuthProduct/operation policiesvalidate-jwt with roles
API6: Unrestricted Access to Sensitive FlowsIP filtering, WAFip-filter, Application Gateway
API7: Server Side Request ForgeryURL validationPolicy expressions
API8: Security MisconfigurationTLS hardening, disable featuresCustom properties
API9: Improper Inventory ManagementAPI CenterGovernance
API10: Unsafe Consumption of APIsBackend validationvalidate-content

🔑 Authentication Patterns

JWT Validation (Microsoft Entra ID)

<validate-azure-ad-token tenant-id="{{tenant-id}}" output-token-variable-name="jwt">
<client-application-ids>
<application-id>{{client-app-id}}</application-id>
</client-application-ids>
<audiences>
<audience>api://{{api-app-id}}</audience>
</audiences>
<required-claims>
<claim name="roles" match="any">
<value>API.Read</value>
<value>API.Write</value>
</claim>
</required-claims>
</validate-azure-ad-token>

Generic JWT Validation

<validate-jwt header-name="Authorization" 
failed-validation-httpcode="401"
failed-validation-error-message="Unauthorized"
require-expiration-time="true"
require-signed-tokens="true"
clock-skew="60">
<openid-config url="https://login.microsoftonline.com/{{tenant-id}}/v2.0/.well-known/openid-configuration"/>
<issuers>
<issuer>https://login.microsoftonline.com/{{tenant-id}}/v2.0</issuer>
</issuers>
<required-claims>
<claim name="aud" match="all">
<value>{{api-audience}}</value>
</claim>
</required-claims>
</validate-jwt>

Client Certificate Authentication

<validate-client-certificate 
validate-revocation="true"
validate-trust="true"
validate-not-before="true"
validate-not-after="true"
ignore-error="false">
<identities>
<identity thumbprint="{{cert-thumbprint}}" />
</identities>
</validate-client-certificate>

🌐 Network Isolation

VNet Integration Modes

Internal VNet Configuration (Bicep)

resource apim 'Microsoft.ApiManagement/service@2023-05-01-preview' = {
name: apimName
location: location
sku: {
name: 'Premium'
capacity: 2
}
properties: {
virtualNetworkType: 'Internal'
publicIpAddressId: publicIP.id
virtualNetworkConfiguration: {
subnetResourceId: apimSubnet.id
}
publicNetworkAccess: 'Disabled'
}
}

NSG Rules for APIM Subnet

PriorityNameDirectionSourceDestinationPortAction
100AllowAppGatewayInboundAppGW SubnetAPIM Subnet443Allow
110AllowManagementInboundApiManagementVirtualNetwork3443Allow
120AllowAzureLBInboundAzureLoadBalancerVirtualNetwork6390Allow
1000DenyAllInboundInboundAnyAnyAnyDeny

🔥 WAF Integration

Application Gateway + WAF Policy

resource wafPolicy 'Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies@2023-05-01' = {
name: 'waf-apim-policy'
location: location
properties: {
policySettings: {
mode: 'Prevention'
state: 'Enabled'
requestBodyCheck: true
maxRequestBodySizeInKb: 128
fileUploadLimitInMb: 100
}
managedRules: {
managedRuleSets: [
{
ruleSetType: 'OWASP'
ruleSetVersion: '3.2'
}
{
ruleSetType: 'Microsoft_BotManagerRuleSet'
ruleSetVersion: '1.0'
}
]
}
customRules: [
{
name: 'BlockBadBots'
priority: 1
ruleType: 'MatchRule'
action: 'Block'
matchConditions: [
{
matchVariables: [{ variableName: 'RequestHeaders', selector: 'User-Agent' }]
operator: 'Contains'
matchValues: ['scanner', 'bot', 'crawler']
transforms: ['Lowercase']
}
]
}
]
}
}

🔐 Secrets Management

Key Vault Integration

Named Value with Key Vault Reference (Bicep)

resource namedValue 'Microsoft.ApiManagement/service/namedValues@2023-05-01-preview' = {
parent: apim
name: 'backend-api-key'
properties: {
displayName: 'backend-api-key'
secret: true
keyVault: {
secretIdentifier: 'https://${keyVaultName}${environment().suffixes.keyvaultDns}/secrets/backend-api-key'
}
}
}

Using Named Values in Policies

<set-header name="X-API-Key" exists-action="override">
<value>{{backend-api-key}}</value>
</set-header>

🛡️ IP Filtering

Allow Specific IPs

<ip-filter action="allow">
<!-- Office IP ranges -->
<address-range from="203.0.113.0" to="203.0.113.255"/>
<!-- Partner network -->
<address>198.51.100.42</address>
<!-- Azure services -->
<address-range from="10.0.0.0" to="10.255.255.255"/>
</ip-filter>

Dynamic IP Filtering

<choose>
<when condition="@(context.Request.IpAddress.StartsWith("10."))">
<!-- Internal traffic - allow -->
</when>
<otherwise>
<!-- External traffic - require additional auth -->
<validate-jwt header-name="Authorization" ... />
</otherwise>
</choose>

✅ Security Checklist

Network Security

  • Internal VNet mode enabled
  • NSG rules configured
  • Private endpoints for dependencies
  • WAF in front of APIM
  • DDoS Protection enabled
  • Public network access disabled

Protocol Security

  • TLS 1.2+ enforced
  • Legacy protocols disabled
  • Weak ciphers disabled
  • HTTP/2 enabled

Authentication

  • OAuth 2.0 / JWT validation configured
  • Subscription keys as fallback only
  • Managed identities for backend auth
  • Client certificates where required

Secret Management

  • Secrets stored in Key Vault
  • Named values reference Key Vault
  • Certificate rotation automated
  • No secrets in policy code

Monitoring

  • Defender for APIs enabled
  • Diagnostic logs enabled
  • Security alerts configured
  • Failed auth monitoring

DocumentDescription
04-PoliciesDetailed policy patterns
06-MonitoringSecurity monitoring
10-Repository-ExamplesImplementation from repository

Next: 04-Policies - Rate limiting, caching, and transformation policies

📖Learn