Skip to main content

Azure WAF provider for octorules

Project description

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 (650 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:
  api-gateway-waf-policy:
    sources:
      - rules
  corporate-site-waf-policy:
    sources:
      - rules

Each zone name maps to an Azure WAF policy name. The provider resolves policy names at runtime. 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

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/api-gateway-waf-policy.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, AnomalyScoring, 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 (10 — 1,000,000)
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, AnomalyScoring --
Extra transforms -- HtmlEntityDecode
Extra operators ServiceTagMatch --
Match variable names RequestHeader, Cookies RequestHeaders, RequestCookies (adapter maps)
Negation field negateCondition negationConditon (API typo; adapter maps)

Linting

73 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:

ln -sf ../../scripts/hooks/pre-commit .git/hooks/pre-commit

License

Apache-2.0

Project details


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.1.6.tar.gz (75.4 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.1.6-py3-none-any.whl (81.5 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for octorules_azure-0.1.6.tar.gz
Algorithm Hash digest
SHA256 2adf6d91b58017a7f96f477e87429da3018701ef31e7565279f7f3aa0094b02d
MD5 fecfb581af12f3dc1795a4760c107204
BLAKE2b-256 3a3f3ee35febda6d92eb2f771e0523be29b6b32518992c81fd16afa03171f80a

See more details on using hashes here.

Provenance

The following attestation bundles were made for octorules_azure-0.1.6.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.1.6-py3-none-any.whl.

File metadata

File hashes

Hashes for octorules_azure-0.1.6-py3-none-any.whl
Algorithm Hash digest
SHA256 6609115961d39ada02c45fe597276acf9cb98165a178fa551b67ec1e41d78b6c
MD5 73e3cbbc82b4176cf7bb8d3ae8d6270b
BLAKE2b-256 ac9048b1c799802cc95fb8feb63a2aa1e1afe1132d8874028ba05b8202b50e88

See more details on using hashes here.

Provenance

The following attestation bundles were made for octorules_azure-0.1.6-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.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page