A modern, declarative DevSecOps web interface and REST management engine for F5 WAF for NGINX security policies, logging profiles, and user-defined custom signatures (Snort syntax).
Backed by a high-performance Redis key-value store with automatic in-memory fallback, and an integrated F5 WAF Compiler (apcompile) service to validate and test binary policy bundle compilation directly within the UI.
Tip
New to F5 WAF Policy Manager? Check out the ๐ Complete Step-by-Step Visual Walkthrough for in-depth guidance with real interface walkthroughs!
The interface provides an end-to-end declarative DevSecOps workflow from policy design to binary compilation and GitOps version control:
๐ Read the Full Visual Walkthrough Guide with Detailed Step-by-Step Instructions โ
- Theme Switcher: Instant switching between an eye-friendly Light theme and a dark cybersecurity theme with persistent
localStoragepreference and synchronized CodeMirror syntax styling. - Unified Navigation: Switch seamlessly across WAF Policies, Logging Profiles, and Compiler Diagnostics dashboards.
- Real-Time Storage Health: Live connection latency indicator with one-click Redis reconfiguration and resilient In-Memory fallback.
- Dual-Mode Editor (Visual Form Builder & CodeMirror JSON):
- Visual Form Builder: Interactive controls for general settings, enforcement mode (
blockingvstransparent), violation blocking/alarm toggles, server technologies, allowed HTTP methods, URL routing rules, and Data Guard (DLP). - CodeMirror Direct JSON Editor: Syntax highlighting, brace matching, code folding, beautify formatting, and live JSON schema validation.
- Live Bidirectional Synchronization: Switch between visual form and raw JSON at any time without losing edits.
- Visual Form Builder: Interactive controls for general settings, enforcement mode (
- 40+ Official F5 Violations Catalog: Categorized by HTTP protocol, Evasion techniques, Access violations, Request/Response inspection, Sub-violations, and Input anomalies.
- Server Technologies Tuning: Automatic signature selection for Linux, Apache, NGINX, PHP, Node.js, Python, MySQL, MongoDB, and more.
- Data Guard DLP: Sensitive data masking for Credit Cards (PAN) and US Social Security Numbers (SSN).
- Side-by-Side Diff Inspector: Visually compare uncommitted policy edits against the saved version.
- Declarative OpenAPI Import: Generate comprehensive WAF policies directly from OpenAPI 3.0 / Swagger specs (only URI
linkreferences are permitted). - BIG-IP ASM Policy Conversion: Ingest legacy BIG-IP ASM XML/JSON security policies and transform them into declarative JSON format for F5 WAF for NGINX.
- Snort-Compatible Rule Engine: Define, edit, and validate custom attack signatures using standard Snort rules syntax.
- Interactive Payload Simulator: Test Snort rules directly against custom HTTP request payloads with instant match inspection and alert visualization.
- Workflow Operations: One-click test launch, signature cloning with automatic deduplication, single delete confirmation modals, and multi-select mass deletion.
- IP Address Lists: Manage whitelists, blacklists, CIDRs (
10.0.0.0/24), IP ranges, and geolocation overrides (setGeolocation) with multi-select mass deletion. - Response Signatures & HTTP Inspection: Configure server response body inspection (
responseCheck), inspection byte length limits (responseCheckLength), and target HTTP status codes (allowedResponseCodes). - Evasion Techniques: Fine-tune all 8 official evasion defense techniques (Bad unescape, Directory traversals, Bare byte decoding, Apache whitespace, Multiple decoding, IIS Unicode codepoints, IIS backslashes, %u decoding) and configure maximum decoding passes.
- Batch Table Operations: Multi-select checkboxes and mass deletion available for Signature Sets, Allowed/Disallowed URLs, and Parameters.
- Declarative Logging Profile CRUD (F5 Documentation): Create, clone, export, and import logging profiles stored under the
log:<name>namespace. - Traffic Filters: Filter requests by
illegal(violations only),all(full audit trail), orblocked(actively dropped requests). - SIEM Presets & Formats: Built-in templates for
default,splunk,arcsight(CEF:0),grpc,bigiq, and customuser-definedkey-value formats. - 34+ Placeholder Tokens: Interactive token insertion for
%date_time%,%ip_client%,%attack_type%,%violations%,%support_id%,%request%,%response%, etc.
- Integrated containerized compiler based on official F5 compiler images (
private-registry.nginx.com/nap/waf-compiler:latest). - Validates policy and logging profile compilation directly from the Web UI to verify that policies compile into valid
.tgzruntime bundles before deployment. - Reports installed versions of attack signatures, bot signatures, threat campaigns, and compiler engines via
/v1/bundle/info.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Browser Client (Light / Dark UI) โ
โ โโโ WAF Security Policies (Visual Builder / CodeMirror / Diff) โ
โ โโโ User Custom Signatures (Snort Rule Builder & Payload Tester) โ
โ โโโ IP Lists / Evasions / Signature Sets / URLs / Parameters โ
โ โโโ Logging Profiles (Visual Builder / SIEM Presets / Tokens) โ
โโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโ
โ REST API โ Compilation Check
โโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโผโโโโโโโโโโโโโโโโ
โ F5 WAF Policy Manager (FastAPI) โ โ f5-waf-apcompile Service โ
โ โโโ Policy & Custom Sig Validators โ โ โโโ apcompile CLI โ
โ โโโ Logging Profile Validator โ โ โโโ Attack Signatures โ
โ โโโ GitOps Synchronization Engine โ โ โโโ Bot Signatures โ
โ โโโ OpenAPI & BIG-IP Converters โ โ โโโ Threat Campaigns โ
โ โโโ Storage Abstraction Layer โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Working Copy (Fast CRUD) โ GitOps Sync (Commit / Pull)
โผ โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Redis Store โ โ GitHub Repository โ
โ โข Active editing working โ โ โข Remote source-of-truth โ
โ copy (policies & logs) โ Startup โ โข Version-controlled JSON: โ
โ โข Instant save & diffs โ Auto-Pull โ โโโ /policies/*.json โ
โ โข Redis 7 persistent DB โ โโโโโโโโโโโ โ โโโ /log-profiles/*.json โ
โ โข Resilient In-Memory โ Explicit โ โโโ /custom-signatures/*.json
โ fallback if unavailable โ Commit โ โ
โ โ โโโโโโโโโโโบ โ โข Branch & commit history โ
โโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ Runtime Deployment / Export
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ NGINX Plus / F5 WAF for NGINX โ
โ app_protect_policy_file "/etc/waf/policies/api_security.json"; โ
โ app_protect_security_log "/etc/waf/logging/log_splunk.json" โ
โ syslog:server=10.0.0.10:514; โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
F5 WAF for NGINX Policy Manager provides an integrated GitOps hybrid architecture that marries the speed of a high-performance in-memory/Redis working copy with the auditing and version-control benefits of GitHub.
- Automatic Retrieval on Startup (GitHub โ Redis):
- When GitHub credentials (
GITHUB_OWNER,GITHUB_REPO,GITHUB_TOKEN) are configured, the application automatically queries the GitHub repository on startup. - All WAF policy, logging profile, and custom signature JSON files stored in the repository are pulled directly into Redis.
- The policies and logging profiles appear instantly in the web dashboard for editing, testing, and deployment.
- When GitHub credentials (
- Editing & Testing in Redis Working Copy:
- All interactive operationsโvisual form editing, raw CodeMirror JSON updates, syntax beautification, and side-by-side diff inspectionsโare performed against Redis.
- Edits are saved instantly to Redis with sub-millisecond response times.
- You can run the F5 WAF Compiler (
apcompile) directly against your Redis working copy to verify compilation into a binary.tgzbundle before committing changes to Git.
- Explicit Commit & Push (Redis โ GitHub):
- Every policy and logging profile row in the dashboard includes a "Commit & Push to GitHub" button (also available in the editor top toolbar).
- Smart Inactive State: The button is automatically disabled and grayed out if the policy or logging profile has not been modified since the last sync.
- Automated Diff Summarization: Clicking it computes a diff against GitHub and automatically prefills a verbose commit description highlighting exact changes (added/removed server technologies, violation toggles, URL/parameter updates, Data Guard rules).
- Commits the JSON document directly to GitHub via the GitHub REST API without requiring a local
gitbinary.
- Manual Sync & Interactive Conflict Resolution (Pull from GitHub):
- Click the "Pull from GitHub" button in the header to synchronize the local store with the latest remote repository state.
- Conflict Protection: If a local policy or profile is in a modified Draft state, an interactive prompt asks whether you want to Keep Local Draft or Overwrite with GitHub Copy.
Yes, GitHub configuration variables persist permanently across restarts when defined in an environment file (.env) or injected into the container/host environment.
The application uses pydantic-settings to automatically load environment variables from a .env file located in the project root directory.
To configure GitHub variables:
# 1. Copy the template to create your .env file
cp .env.example .env
# 2. Add your GitHub repository settings and Personal Access Token
nano .envAdd your configuration:
# Storage Backend: keep 'redis' for the GitOps hybrid workflow
STORAGE_BACKEND=redis
# GitHub Repository & Authentication
GITHUB_OWNER=my-org
GITHUB_REPO=f5-waf-policies
GITHUB_TOKEN=ghp_YourPersonalAccessTokenWithRepoScope
GITHUB_BRANCH=main
GITHUB_API_URL=https://api.github.com
# Target directories inside the repository
GITHUB_POLICIES_PATH=policies
GITHUB_LOG_PROFILES_PATH=log-profiles
GITHUB_CUSTOM_SIGS_PATH=custom-signaturesBecause .env is stored on the persistent host filesystem, these settings persist across container restarts, docker compose down / docker compose up cycles, and server reboots.
When using Docker Compose, variables in .env are automatically forwarded into the waf-editor container. Alternatively, you can declare them explicitly under the environment: section of docker-compose.yml:
services:
waf-editor:
environment:
- STORAGE_BACKEND=redis
- GITHUB_OWNER=my-org
- GITHUB_REPO=f5-waf-policies
- GITHUB_TOKEN=${GITHUB_TOKEN}
- GITHUB_BRANCH=main
- GITHUB_POLICIES_PATH=policies
- GITHUB_LOG_PROFILES_PATH=log-profiles
- GITHUB_CUSTOM_SIGS_PATH=custom-signaturesIn Kubernetes deployments, store the sensitive token in a Secret and repository configuration in a ConfigMap:
env:
- name: GITHUB_TOKEN
valueFrom:
secretKeyRef:
name: f5-waf-github-credentials
key: token
- name: GITHUB_OWNER
value: "my-org"
- name: GITHUB_REPO
value: "f5-waf-policies"
- name: GITHUB_BRANCH
value: "main"You can also view and test your GitHub connection directly in the web browser by clicking the Storage Health badge in the header and switching to the GitHub GitOps tab. Configuration entered in the UI updates the running application in-memory immediately. To ensure your credentials survive container recreation, save them in .env.
| Environment Variable | Required | Default | Description |
|---|---|---|---|
STORAGE_BACKEND |
No | redis |
Storage backend: redis (recommended for GitOps flow), github, or in_memory. |
GITHUB_OWNER |
Yes* | None | GitHub user or organization account owning the repository (e.g., my-org). |
GITHUB_REPO |
Yes* | None | Target GitHub repository name (e.g., f5-waf-policies). |
GITHUB_TOKEN |
Yes* | None | GitHub Personal Access Token (classic with repo scope, or fine-grained with Read/Write Contents permission). |
GITHUB_BRANCH |
No | main |
Target Git branch for pulling configurations and pushing commits. |
GITHUB_API_URL |
No | https://api.github.com |
Base API URL. Change for GitHub Enterprise Server (e.g., https://github.corp.internal/api/v3). |
GITHUB_POLICIES_PATH |
No | policies |
Subdirectory inside the repository where WAF policy JSON files are stored. |
GITHUB_LOG_PROFILES_PATH |
No | log-profiles |
Subdirectory inside the repository where logging profile JSON files are stored. |
GITHUB_CUSTOM_SIGS_PATH |
No | custom-signatures |
Subdirectory inside the repository where custom signature JSON files are stored. |
* Required when GitHub GitOps synchronization is enabled.
The stack comprises three orchestrated containers defined in docker-compose.yml:
waf-editor(f5-waf-policy-manager): The web UI and FastAPI backend (port8000).apcompile(f5-waf-apcompile): The policy compiler REST service running F5'sapcompile(port9000).redis(f5-waf-redis): Persistent Redis 7 key-value database (port6379).
The compiler image pulls from F5's private container registry (private-registry.nginx.com/nap/waf-compiler:latest), which requires Mutual TLS (mTLS) client certificate authentication.
Important
Docker Daemon vs. Build Secrets: Docker BuildKit secrets (--secret) only apply inside container RUN steps; they are not used by the Docker daemon when pulling base images (FROM ...).
The Docker daemon on your host must have the client certificates installed in /etc/docker/certs.d/private-registry.nginx.com/. Furthermore, Docker strictly requires the certificate file to end in .cert (not .crt โ Docker treats .crt files as server CA certificates!).
Run the following commands on your Docker host (or use the provided setup-registry-auth.sh):
# 1. Create Docker's registry certificate directory
sudo mkdir -p /etc/docker/certs.d/private-registry.nginx.com
# 2. Copy your valid MyF5 certificate as client.cert and key as client.key
sudo cp /etc/ssl/nginx/nginx-repo.crt /etc/docker/certs.d/private-registry.nginx.com/client.cert
sudo cp /etc/ssl/nginx/nginx-repo.key /etc/docker/certs.d/private-registry.nginx.com/client.key
# 3. Set secure permissions
sudo chmod 644 /etc/docker/certs.d/private-registry.nginx.com/client.cert
sudo chmod 600 /etc/docker/certs.d/private-registry.nginx.com/client.key
# 4. Verify that Docker can pull the base compiler image
docker pull private-registry.nginx.com/nap/waf-compiler:latestAutomated setup via script:
chmod +x setup-registry-auth.sh
./setup-registry-auth.sh /etc/ssl/nginx/nginx-repo.crt /etc/ssl/nginx/nginx-repo.keyYou can provide your NGINX certificate and key to docker compose build using any of the following approaches:
Specify the paths to your valid NGINX repository certificate and key directly on the command line:
NGINX_CERT=/etc/ssl/nginx/nginx-repo.crt NGINX_KEY=/etc/ssl/nginx/nginx-repo.key docker compose buildexport NGINX_CERT=/etc/ssl/nginx/nginx-repo.crt
export NGINX_KEY=/etc/ssl/nginx/nginx-repo.key
docker compose buildCopy the provided .env.example file and configure your paths:
cp .env.example .envEnsure .env contains:
NGINX_CERT=/etc/ssl/nginx/nginx-repo.crt
NGINX_KEY=/etc/ssl/nginx/nginx-repo.key
WAF_COMPILER_IMAGE=private-registry.nginx.com/nap/waf-compiler:latest
APP_PORT=8000
COMPILER_PORT=9000Then build simply with:
docker compose build# Build only the web manager
docker compose build waf-editor
# Build only the apcompile service
NGINX_CERT=/etc/ssl/nginx/nginx-repo.crt NGINX_KEY=/etc/ssl/nginx/nginx-repo.key docker compose build apcompile# Start all containers in the background
docker compose up -d
# Check service status and healthchecks
docker compose ps
# View live aggregate logs
docker compose logs -f
# View compiler service logs specifically
docker compose logs -f apcompileOnce running, access the services:
- Web Interface: http://localhost:8000
- Compiler REST API: http://localhost:9000/health
- Redis Database:
localhost:6379
To shut down:
# Stop containers
docker compose down
# Stop containers and wipe Redis data volume
docker compose down -v- Python 3.10+ (or uv)
- Optional: Local Redis server (falls back gracefully to memory store if unavailable)
# Install dependencies into virtual environment
uv sync
# Start the web manager
uv run python main.pypython -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
pip install -r requirements.txt
python main.pyA production-ready Helm chart is provided under helm/f5-waf-policy-manager.
# Install the Helm chart into namespace 'waf-system'
helm install f5-waf-editor ./helm/f5-waf-policy-manager \
--namespace waf-system \
--create-namespace
# Access via port-forward
kubectl --namespace waf-system port-forward svc/f5-waf-editor 8000:80Policies and logging profiles are cleanly isolated by key naming conventions:
| Resource Type | Redis Key Pattern | Document Schema | Example Key |
|---|---|---|---|
| WAF Policy | <policy_name> |
JSON conforming to F5 WAF Schema | prod_api_gateway_waf |
| Logging Profile | log:<profile_name> |
JSON conforming to F5 Logging Schema | log:log_splunk |
Interactive OpenAPI documentation is available at http://localhost:8000/docs.
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/policies |
List all WAF security policies |
POST |
/api/policies |
Create or upload a new policy |
GET |
/api/policies/{name} |
Fetch full JSON policy document |
PUT |
/api/policies/{name} |
Save modifications to policy |
DELETE |
/api/policies/{name} |
Delete policy from storage |
POST |
/api/policies/{name}/clone |
Duplicate policy with a new key |
GET |
/api/policies/{name}/export |
Download policy as .json |
POST |
/api/policies/import |
Import declarative JSON or OpenAPI spec |
POST |
/api/policies/convert-bigip |
Convert legacy BIG-IP ASM XML/JSON policy |
GET |
/api/log-profiles |
List all logging profiles |
POST |
/api/log-profiles |
Create or update a logging profile |
GET |
/api/custom-signatures |
List custom signatures (Snort syntax) |
POST |
/api/custom-signatures/test |
Test Snort rule against HTTP payload |
POST |
/api/policies/{name}/github-push |
(GitOps) Commit and push policy from Redis to GitHub |
POST |
/api/log-profiles/{name}/github-push |
(GitOps) Commit and push logging profile from Redis to GitHub |
POST |
/api/custom-signatures/{tag}/github-push |
(GitOps) Commit and push custom signatures from Redis to GitHub |
POST |
/api/github/pull |
(GitOps) Pull all policies and logging profiles from GitHub into Redis |
GET |
/api/github/status |
Check GitHub connectivity, repo, and branch status |
POST |
/api/github/connect |
Configure GitHub connection settings dynamically |
GET |
/api/redis/status |
Live Redis connectivity and latency check |
POST |
/v1/compile/policy |
(Compiler) Compile policy JSON into .tgz bundle |
POST |
/v1/compile/logprofile |
(Compiler) Compile logging profile into .tgz |
GET |
/v1/bundle/info |
(Compiler) Report signature & engine versions |
The test suite validates schema enforcement, Snort syntax parsing, IP list formats, evasion rules, storage layers, and REST endpoints:
# Run pytest with uv
uv run pytest tests/ -v============================= test session starts =============================
collected 171 items
tests/test_api.py ........................................ [ 23%]
tests/test_compiler.py ....... [ 27%]
tests/test_converter.py ...... [ 30%]
tests/test_custom_signatures_api.py ....... [ 35%]
tests/test_custom_signatures_compiler.py .. [ 36%]
tests/test_custom_signatures_storage.py .. [ 37%]
tests/test_custom_signatures_validator.py ....... [ 41%]
tests/test_deployments.py ........ [ 46%]
tests/test_github_storage.py ..... [ 49%]
tests/test_logging_api.py ...... [ 52%]
tests/test_logging_storage.py .. [ 53%]
tests/test_logging_validator.py ......... [ 59%]
tests/test_snort_validator.py .... [ 61%]
tests/test_storage.py .... [ 63%]
tests/test_templates.py .. [ 64%]
tests/test_url_parameters_and_sanitization.py ............ [ 71%]
tests/test_validator.py ................................................ [100%]
====================== 171 passed, 4 warnings in 10.91s =======================
This project is licensed under the Apache 2.0 License.




