Skip to main content

octorules-azure

Azure WAF provider for octorules — manages Azure Web Application Firewall custom rules as YAML.

Supports both Azure Front Door WAF (Premium/Standard) and Application Gateway WAF (WAF_v2) through a unified interface. Users write the same YAML regardless of which WAF type is deployed.

Alpha — this provider has comprehensive offline test coverage (698 tests) but has not yet been tested against live Azure WAF APIs. Use with caution and report any issues.

Installation

pip install octorules-azure

This installs octorules (core) and octorules-azure. The provider is auto-discovered — no class: needed in config.

Configuration

# config.yaml
providers:
  azure:
    subscription_id: env/AZURE_SUBSCRIPTION_ID
    resource_group: rg-waf-production
    waf_type: front_door       # or "app_gateway"
    timeout: 30                # API timeout in seconds
    max_workers: 1             # parallel workers for multi-zone ops
  rules:
    directory: ./rules

zones:
  apiwafpolicy:
    sources:
      - rules
  websitewafpolicy:
    sources:
      - rules

Each zone name maps to an Azure WAF policy name. The provider resolves policy names at runtime. Front Door WAF policy names allow only alphanumerics and must start with a letter; Application Gateway policy names also allow hyphens, periods, and underscores. The env/ prefix resolves values from environment variables at runtime. All keys under the provider section are forwarded to the provider constructor as keyword arguments (octodns-style passthrough).

Provider settings

All settings below go under the provider section (e.g. providers.azure).

Key Default Description
subscription_id AZURE_SUBSCRIPTION_ID env var Azure subscription ID (required)
resource_group AZURE_RESOURCE_GROUP env var Resource group containing WAF policies (required)
waf_type front_door / AZURE_WAF_TYPE env var "front_door" or "app_gateway"
timeout 30 API timeout in seconds
max_workers 1 Parallel workers for multi-zone operations

Authentication

Uses DefaultAzureCredential — no token is needed in the config file. Common options:

  • Service principal (CI/CD): AZURE_TENANT_ID + AZURE_CLIENT_ID + AZURE_CLIENT_SECRET env vars
  • Managed identity (Azure VMs, ACI, App Service): assign identity to the resource, grant WAF Contributor role
  • Azure CLI (local development): run az login before octorules commands
  • Certificate (automated systems): AZURE_TENANT_ID + AZURE_CLIENT_ID + AZURE_CLIENT_CERTIFICATE_PATH env vars

The service principal or managed identity needs the Contributor or Network Contributor role on the resource group containing WAF policies.

Safety thresholds are configured under safety: (framework-owned, not forwarded to the provider):

Key Default Description
safety.delete_threshold 30.0 Max % of rules that can be deleted
safety.update_threshold 30.0 Max % of rules that can be updated
safety.min_existing 3 Min rules before thresholds apply

Examples

The examples/ directory contains a working single-provider config.yaml plus rules/examplewafpolicy.yaml demonstrating every supported phase and key. Copy it as a starting point.

Nested format (recommended)

All Azure WAF sections nest under a single azure: block:

# rules/examplewafpolicy.yaml
azure:
  waf_custom_rules:
    - ref: BlockBadIPs
      priority: 1
      action: Block
      matchConditions:
        - matchVariable: RemoteAddr
          operator: IPMatch
          matchValue:
            - 192.168.1.0/24

  waf_rate_rules:
    - ref: RateLimitAPI
      priority: 100
      action: Block
      ruleType: RateLimitRule
      rateLimitDurationInMinutes: 1
      rateLimitThreshold: 100
      groupBy:
        - variableName: SocketAddr
      matchConditions:
        - matchVariable: RequestUri
          operator: BeginsWith
          matchValue:
            - /api/

  waf_managed_rules:
    - ref: Microsoft_DefaultRuleSet
      ruleSetType: Microsoft_DefaultRuleSet
      ruleSetVersion: "2.1"
      ruleSetAction: Block

  waf_policy_settings:
    mode: Prevention
    requestBodyCheck: Enabled

  waf_managed_exclusions:
    - matchVariable: RequestArgNames
      selectorMatchOperator: Equals
      selector: q

Supported features

Feature Status Azure concept
Phase rules (3 phases) Supported Custom rules, rate limit rules, managed rules
Policy settings Supported WAF mode, request body inspection, file upload limits
Custom rulesets Not supported Azure has no separate rule group concept
Lists (IP Sets) Not supported IPs are inline in matchConditions (up to 600 per condition)
Zone discovery (list_zones) Supported Lists WAF policies in resource group
ETag concurrency control Supported Retries on HTTP 412 (concurrent update conflict)

Phases

Phase Rule Type Description
azure.waf_custom_rules MatchRule Standard WAF rules (IP blocks, geo-blocks, header checks, etc.)
azure.waf_rate_rules RateLimitRule Rate limiting rules with threshold, duration, and grouping
azure.waf_managed_rules Managed OWASP DRS, Bot Protection rule sets with overrides and exclusions

Rule format

The same YAML format works for both Front Door and Application Gateway. The adapter translates API-level differences (field naming, SDK models) transparently.

Custom rules

# rules/examplewafpolicy.yaml
azure:
  waf_custom_rules:
    # Block specific IP ranges
    - ref: BlockBadIPs
      priority: 1
      action: Block
      matchConditions:
        - matchVariable: RemoteAddr
          operator: IPMatch
          matchValue:
            - 192.168.1.0/24
            - 10.0.0.0/8

    # Block requests with suspicious user-agent
    - ref: BlockBadUserAgents
      priority: 2
      action: Block
      matchConditions:
        - matchVariable: RequestHeader
          selector: User-Agent
          operator: Contains
          matchValue:
            - evilbot
            - scanner
          transforms:
            - Lowercase

    # Geo-block: allow only US and CA
    - ref: GeoBlock
      priority: 3
      action: Block
      matchConditions:
        - matchVariable: RemoteAddr
          operator: GeoMatch
          negateCondition: true
          matchValue:
            - US
            - CA

    # Block requests matching a regex pattern
    - ref: BlockAdminPaths
      priority: 4
      action: Block
      matchConditions:
        - matchVariable: RequestUri
          operator: RegEx
          matchValue:
            - "^/admin/.*\\.php$"
          transforms:
            - Lowercase

Rate-limit rules

azure:
  waf_rate_rules:
    # Rate limit API endpoints to 100 requests per minute per client IP
    - ref: RateLimitAPI
      priority: 100
      action: Block
      ruleType: RateLimitRule
      rateLimitDurationInMinutes: 1
      rateLimitThreshold: 100
      groupBy:
        - variableName: SocketAddr
      matchConditions:
        - matchVariable: RequestUri
          operator: BeginsWith
          matchValue:
            - /api/

Rule fields reference

Field Type Required Description
ref string Yes Rule name (letters, digits, underscores; max 128 chars)
priority int Yes Evaluation order (positive int, lower = first; must be unique across all rules)
action string Yes Allow, Block, Log, Redirect, or JSChallenge
enabledState string No Enabled (default) or Disabled
ruleType string No MatchRule (default) or RateLimitRule
matchConditions list Yes One or more conditions (ANDed); max 10 per rule
rateLimitDurationInMinutes int RateLimitRule 1 or 5 (time window)
rateLimitThreshold int RateLimitRule Requests per client in the window (>= 0; Azure documents no maximum)
groupBy list No Rate limit grouping: SocketAddr, GeoLocation, or None

Match condition fields

Field Type Description
matchVariable string What to match: RemoteAddr, SocketAddr, RequestMethod, QueryString, PostArgs, RequestUri, RequestHeader, RequestBody, Cookies
selector string Header/cookie/post-arg name (required for RequestHeader, Cookies, PostArgs)
operator string Any, IPMatch, GeoMatch, Equal, Contains, BeginsWith, EndsWith, RegEx, LessThan, GreaterThan, LessThanOrEqual, GreaterThanOrEqual, ServiceTagMatch
negateCondition bool Invert the match (default: false)
matchValue list Values to match against (max 600 for IPMatch, 10 for string operators)
transforms list Pre-processing: Lowercase, Uppercase, Trim, UrlDecode, UrlEncode, RemoveNulls, HtmlEntityDecode

WAF Type Differences

The adapter pattern handles all API differences transparently. Users write identical YAML regardless of waf_type:

Feature Front Door Application Gateway
Scope Global (edge CDN) Regional (reverse proxy)
Propagation Up to 45 minutes Seconds to minutes
SDK azure-mgmt-frontdoor azure-mgmt-network
Update model Async LRO (begin_create_or_update) Synchronous (create_or_update)
Extra actions Redirect --
Extra transforms -- HtmlEntityDecode
Extra operators ServiceTagMatch --
Match variable names RequestHeader, Cookies RequestHeaders, RequestCookies (adapter maps)
Negation field negateCondition negationConditon (API typo; adapter maps)

Linting

79 lint rules with AZ prefix covering structure, priority, action, match conditions, rate limits, cross-rule analysis, best practices, and managed rule sets. See docs/lint.md for the full reference with examples.

octorules lint --config config.yaml

Known limitations

  • Front Door propagation delay: Configuration changes can take up to 45 minutes to propagate to all edge nodes globally. Plan accordingly for production deployments.
  • No PATCH API: Azure WAF uses full-policy PUT. octorules always fetches the current policy first and merges changes, but concurrent external modifications during sync could conflict (mitigated by ETag retry).
  • No custom rulesets or lists: Azure WAF has no equivalent of AWS Rule Groups or IP Sets. IP addresses are inline in matchConditions (max 600 per condition, 60,000 across all rules).
  • Regex limit: Maximum 5 custom rules using the RegEx operator per policy.
  • Priority must be globally unique: Rule priorities must be unique across ALL custom rules in a policy (both MatchRule and RateLimitRule combined), not just within a phase.

Development

python -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/pytest tests/ -v
.venv/bin/ruff check octorules_azure/ tests/
.venv/bin/ruff format --check octorules_azure/ tests/

Pre-commit hook:

pre-commit install

License

octorules-azure is licensed under the Apache License 2.0.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

octorules_azure-0.4.0.tar.gz (80.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

octorules_azure-0.4.0-py3-none-any.whl (46.9 kB view details)

Uploaded Python 3

File details

Details for the file octorules_azure-0.4.0.tar.gz.

File metadata

  • Download URL: octorules_azure-0.4.0.tar.gz
  • Upload date:
  • Size: 80.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for octorules_azure-0.4.0.tar.gz
Algorithm Hash digest
SHA256 11a3112e4e3bcf3ed1227929a2f999483941c1199639a354892d408bb2ffc270
MD5 51a819876a59490895419f303362c5a6
BLAKE2b-256 6dca19f5a1486992039462f4069f1138c51b8456d3021252a660106c2e933191

See more details on using hashes here.

Provenance

The following attestation bundles were made for octorules_azure-0.4.0.tar.gz:

Publisher: release.yaml on doctena-org/octorules-azure

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file octorules_azure-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: octorules_azure-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 46.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for octorules_azure-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e6736290b134bb5689f4bf743bbcfa263a7e513661c7f3aea00023fcabe00454
MD5 dba811aecc934f01e363250a596ba86d
BLAKE2b-256 c4a61f44f0286a1255ecb52028f42a046d3f0aa56edd19880fd5b3d8c9712bdc

See more details on using hashes here.

Provenance

The following attestation bundles were made for octorules_azure-0.4.0-py3-none-any.whl:

Publisher: release.yaml on doctena-org/octorules-azure

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.6.0

2 files

0.5.0

2 files

This release

0.4.0 This release

2 files

0.3.0

2 files

0.2.1

2 files

0.2.0

2 files

0.1.10

2 files

0.1.9

2 files

0.1.8

2 files

0.1.7

2 files

0.1.6

2 files

0.1.5

2 files

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page