From 294eed4e70513792bd51cee5f5c10446bc7407a8 Mon Sep 17 00:00:00 2001 From: Ciara Stacke Date: Thu, 22 May 2025 18:30:40 +0100 Subject: [PATCH 1/8] Add enhancement proposal for NAP WAF integration --- docs/proposals/nap-waf.md | 753 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 753 insertions(+) create mode 100644 docs/proposals/nap-waf.md diff --git a/docs/proposals/nap-waf.md b/docs/proposals/nap-waf.md new file mode 100644 index 0000000000..76bc27844a --- /dev/null +++ b/docs/proposals/nap-waf.md @@ -0,0 +1,753 @@ +# Enhancement Proposal-3341: NGINX App Protect WAF Integration + +- Issue: https://github.com/nginx/nginx-gateway-fabric/issues/3341 +- Status: Provisional + +## Summary + +This proposal describes the integration of NGINX App Protect (NAP) WAF v5 into NGINX Gateway Fabric (NGF) to provide comprehensive WAF protection at Gateway and Route levels while working within NAP v5's architectural constraints of multi-container deployment and pre-compiled policy requirements. + +## Goals + +- Extend NginxProxy resource to enable NAP WAF for GatewayClass/Gateway with multi-container orchestration +- Design WafPolicy custom resource for Route-level WAF configuration that references pre-compiled policy bundles +- Define deployment workflows that accommodate NAP v5's external policy compilation requirements +- Provide secure and automated policy distribution mechanisms from external sources +- Deliver enterprise-grade WAF capabilities through Kubernetes-native APIs +- Maintain alignment with NGF's existing security and operational patterns +- Support configurable security logging for WAF events and policy violations + +## Non-Goals + +- Compiling or updating NAP WAF policies (handled by external NAP v5 tooling) +- Providing inline policy definition (not supported by NAP v5 architecture) +- Supporting NGINX OSS (NAP v5 does not require NGINX Plus, but OSS support is out of scope at this time) +- Real-time policy editing interfaces +- Policy version management system +- Persistent storage management for policy files + +## Introduction + +### NAP v5 Architectural Constraints + +NGINX App Protect WAF v5 imposes specific architectural requirements that fundamentally shape this integration design: + +- **Multi-container deployment**: Requires separate `waf-enforcer` and `waf-config-mgr` containers alongside the main NGINX container +- **Pre-compiled policies**: WAF policies must be compiled externally using NAP tooling before deployment (cannot be defined inline in Kubernetes resources) +- **Shared volume architecture**: Containers communicate through shared filesystem volumes rather than direct API calls +- **External policy management**: Policy compilation and distribution must be handled outside the Kubernetes cluster + +### Design Philosophy + +This proposal provides the best possible Kubernetes-native experience while respecting NAP v5 constraints, abstracting complexity from end users where possible while maintaining operational flexibility for enterprise environments. + +### Storage Architecture + +The integration uses ephemeral volumes (emptyDir) for NAP v5's required shared storage, consistent with NGF's existing ReadOnlyRootFilesystem security pattern. This approach provides: + +- **Security alignment**: No persistent state that could be compromised +- **Operational simplicity**: No persistent volume lifecycle management +- **Clean failure recovery**: Fresh volumes on pod restart with current policies +- **Immutable infrastructure**: Policy files cannot be modified at runtime + +### Overall System Architecture + +```mermaid +graph TB + %% External Policy Management + subgraph "External Policy Management" + SecTeam[Security Team] + Compiler[NAP v5 Compiler] + Store[Policy Store
S3/HTTP/MinIO] + end + + %% Kubernetes Cluster + subgraph "Kubernetes Cluster" + + %% Control Plane + subgraph "nginx-gateway namespace" + NGFPod[NGF Pod
Controllers + Policy Fetcher] + NGFServiceAccount[NGF Service Account
Native Cloud Auth Annotations] + end + + %% Application Namespace + subgraph "applications namespace" + + %% Gateway Resources + Gateway[Gateway
*.example.com] + HTTPRoute[HTTPRoute
Protected Route] + Application[Application
Backend Service] + + %% Custom Resources (all in app namespace) + NginxProxy[NginxProxy
waf.enabled=true] + WafPolicy[WafPolicy
Policy Reference] + Secret[Secret
Store Credentials
Optional - Fallback Auth Only] + + %% NGINX Data Plane (WAF Enabled) + subgraph "NGINX Pod (Multi-Container when WAF enabled)" + direction TB + NGINXContainer[NGINX Container
+ NAP Module] + WafEnforcer[WAF Enforcer
Container] + WafConfigMgr[WAF Config Manager
Container] + + subgraph "Shared Volumes (Ephemeral)" + PolicyVol[Policy Volume
emptyDir] + ConfigVol[Config Volume
emptyDir] + end + end + end + end + + %% External Access + PublicEndpoint[Public Endpoint
Load Balancer] + Client[Client Traffic] + + %% Policy Development Flow + SecTeam -->|Develop & Compile| Compiler + Compiler -->|Publish Bundle| Store + + %% Configuration Flow + Store -.->|Policy Location| WafPolicy + NginxProxy -.->|Enables WAF| Gateway + WafPolicy -.->|Protects| HTTPRoute + + %% Control Plane Operations + NGFPod -->|Watches Resources| NginxProxy + NGFPod -->|Watches Resources| WafPolicy + NGFPod -->|Fetches Policy
Native Cloud Auth| Store + NGFPod -.->|Fallback: Uses Credentials| Secret + NGFServiceAccount -.->|Cloud Provider
Authentication| Store + NGFPod ===|gRPC Config| NGINXContainer + NGFPod -->|Deploy Policy| PolicyVol + + %% NAP v5 Inter-Container Communication + NGINXContainer <-->|Shared FS| PolicyVol + WafEnforcer <-->|Shared FS| PolicyVol + WafConfigMgr <-->|Shared FS| PolicyVol + WafConfigMgr <-->|Shared FS| ConfigVol + NGINXContainer <-->|Shared FS| ConfigVol + + %% Traffic Flow + Client ==>|HTTP/HTTPS| PublicEndpoint + PublicEndpoint ==>|WAF Protected| NGINXContainer + NGINXContainer ==>|Filtered Traffic| Application + + %% Resource Relationships + HTTPRoute -->|Attached to| Gateway + + %% Styling + classDef external fill:#e1f5fe,stroke:#01579b,stroke-width:2px + classDef control fill:#f3e5f5,stroke:#4a148c,stroke-width:2px + classDef gateway fill:#66CDAA,stroke:#333,stroke-width:2px + classDef wafRequired fill:#ffebee,stroke:#c62828,stroke-width:3px + classDef app fill:#fce4ec,stroke:#880e4f,stroke-width:2px + classDef volume fill:#f1f8e9,stroke:#33691e,stroke-width:2px + classDef endpoint fill:#FFD700,stroke:#333,stroke-width:2px + classDef optional fill:#f0f8ff,stroke:#4169e1,stroke-width:2px,stroke-dasharray: 5 5 + classDef cloudAuth fill:#e8f5e8,stroke:#228b22,stroke-width:2px + + class SecTeam,Compiler,Store external + class NGFPod control + class NGFServiceAccount cloudAuth + class Gateway,HTTPRoute gateway + class WafEnforcer,WafConfigMgr,PolicyVol,NginxProxy,WafPolicy wafRequired + class Application app + class PolicyVol,ConfigVol volume + class PublicEndpoint endpoint + class Secret optional + + %% Notes about the architecture + classDef note fill:#fffacd,stroke:#daa520,stroke-width:1px,stroke-dasharray: 5 5 + Note1[📝 Note: Architecture supports multiple Gateways
with selective WAF enablement per Gateway] + Note2[📝 Note: Secret only required for fallback authentication
Native cloud auth uses NGF Service Account annotations] + class Note1,Note2 note +``` + +This architecture diagram illustrates the complete NAP v5 WAF integration within NGINX Gateway Fabric, showing the flow from policy development to traffic protection: + +**External Policy Management (Blue):** Security teams develop WAF policies using NAP v5 JSON schema, compile them using NAP v5 compiler tools, and publish the compiled policy bundles to accessible storage locations (S3, HTTP servers, or MinIO). + +**Control Plane (Purple):** The NGF Pod in the `nginx-gateway` namespace acts as the centralized control plane, watching for NginxProxy and WafPolicy resources across application namespaces, fetching compiled policies from external storage using appropriate authentication, and distributing policy configurations to NGINX Pods via secure gRPC connections. + +**Data Plane (Green/Red):** When WAF is enabled through NginxProxy configuration, each Gateway deploys as a multi-container NGINX Pod containing the main NGINX container with NAP module, plus the required WAF Enforcer and WAF Config Manager containers. These containers communicate through shared ephemeral volumes rather than network calls, maintaining NAP v5's architectural requirements. + +**Application Namespace Resources:** All user-facing resources (Gateway, HTTPRoute, WafPolicy, NginxProxy, and optional authentication Secret) reside in application namespaces for proper isolation and RBAC management. The Secret is only required when using fallback authentication methods - native cloud authentication uses annotations on the NGF service account in the nginx-gateway namespace. + +**Traffic Flow (Yellow/Gold):** Client traffic flows through the public load balancer endpoint to the WAF-protected NGINX container, where NAP v5 applies security policies before forwarding clean traffic to backend applications. + +**Resource Relationships:** WafPolicy resources attach to HTTPRoutes via Gateway API ExtensionRef filters, while NginxProxy resources enable WAF functionality at the Gateway level. This design supports selective WAF deployment where some Gateways have WAF protection while others remain standard, all managed by a single NGF control plane. + +The architecture demonstrates separation of concerns: external policy compilation and storage, centralized policy distribution, and distributed policy enforcement, while maintaining security through ephemeral storage and immutable infrastructure principles. + +### Network Access Requirements + +NGF requires outbound network access to fetch WAF policies from remote locations: + +- **HTTPS/HTTP access** to policy storage endpoints (S3, Azure Blob, HTTP servers, etc.) +- **DNS resolution** for policy storage hostnames +- **Standard HTTP client behavior** including proxy environment variable support + +**Operator Responsibilities:** + +- Configure appropriate NetworkPolicies for NGF pod egress access +- Set up corporate proxy configuration via standard environment variables (`HTTP_PROXY`, `HTTPS_PROXY`, `NO_PROXY`) +- Ensure DNS resolution for policy storage endpoints +- Mount custom CA certificates if using private certificate authorities +- Configure service mesh policies for external traffic (if applicable) + +**Note**: Network access configuration is environment-specific and handled through standard Kubernetes networking patterns rather than NGF-specific configuration options. + +### Policy Development Workflow + +Given NAP v5 constraints, users must follow this workflow: + +1. **Policy Development**: Write WAF policies using NAP v5 JSON schema +2. **Log Profile Development**: Create custom logging profiles or use built-in profiles (log_all, log_blocked, etc.) +3. **Compilation**: Use NAP v5 compiler tools to create policy and logging profile bundles +4. **Distribution**: Publish compiled policies and log profiles to accessible storage (S3, HTTP) +5. **Configuration**: Create WafPolicy CR referencing the policy location and configuring security logging +6. **Manual Deployment**: NGF fetches and applies policies when WafPolicy is created or updated + +**Note**: Policy enforcement mode and behavior are defined within the compiled NAP policy itself. Security logging profiles can be either built-in names or custom compiled bundles. + +Example CI/CD integration for manual updates: + +```bash +# Compile policy using NAP v5 tools (policy defines enforcement mode) +docker run --rm -v $(pwd):/policies nginx/nap-compiler:5.6.0 \ + compile --input /policies/app-policy.json --output /policies/compiled-policy.tgz + +# Compile custom logging profile (optional - can use built-in profiles) +docker run --rm -v $(pwd):/policies nginx/nap-compiler:5.6.0 \ + compile --input /policies/custom-log-profile.json --output /policies/log-profile.tgz + +# Generate checksums for integrity verification +sha256sum compiled-policy.tgz > compiled-policy.tgz.sha256 +sha256sum log-profile.tgz > log-profile.tgz.sha256 + +# Publish to storage +aws s3 cp compiled-policy.tgz s3://company-policies/prod-policy-v$(date +%Y%m%d).tgz +aws s3 cp compiled-policy.tgz.sha256 s3://company-policies/prod-policy-v$(date +%Y%m%d).tgz.sha256 +aws s3 cp log-profile.tgz s3://company-policies/logging/custom-log-profile.tgz +aws s3 cp log-profile.tgz.sha256 s3://company-policies/logging/custom-log-profile.tgz.sha256 + +# Manual update: Modify WafPolicy resource to reference new policy and logging +kubectl patch wafpolicy app-policy \ + --patch '{"spec":{"policySource":{"fileLocation":"s3://company-policies/prod-policy-v'$(date +%Y%m%d)'.tgz"}}}' +``` + +### Security Logging Configuration + +The securityLogs section supports multiple logging configurations, each generating an `app_protect_security_log` directive: + +**Built-in Log Profiles:** + +- `log_all`: Log all requests (blocked and passed) +- `log_blocked`: Log only blocked requests +- `log_grpc_all`: Log all gRPC requests +- `log_grpc_blocked`: Log blocked gRPC requests +- `log_grpc_illegal`: Log illegal gRPC requests +- `log_illegal`: Log illegal requests + +**Custom Log Profiles:** + +- Reference compiled logging profile bundles from remote sources +- Same fetch and validation mechanisms as policy bundles +- Support for checksums and retry policies + +**Destination Types:** + +- `stderr`: Output to container stderr +- `file`: Write to specified file path (must be mounted to host for waf-enforcer container access) +- `syslog`: Send to syslog server via TCP (recommend local proxy for secure forwarding) + +**Generated NGINX Configuration Examples:** + +```nginx +# Built-in profile to stderr +app_protect_security_log log_all stderr; + +# Custom profile to file +app_protect_security_log /shared_volume/custom-log-profile.tgz /var/log/app_protect/security.log; + +# Built-in profile to syslog +app_protect_security_log log_blocked syslog:server=syslog-svc.default:514; +``` + +### Policy Fetch Failure Handling + +In the cases where there are policy fetch failures: + +**First-Time Policy Fetch Failure:** + +- Route configuration is **not applied** - no WAF protection enabled +- Route remains unprotected until policy becomes available + +**Policy Update Failure:** + +- **Existing policy remains in effect** - no disruption to current protection +- WAF protection continues with the last successfully deployed policy + +**Retry Behavior:** + +- Configurable retry policy with exponential backoff +- No service disruption during retry attempts +- Detailed error messages for troubleshooting + +### NGF Integration Architecture + +The integration leverages NGF's existing architecture: + +- **Single NGF Pod**: Centralized control plane in `nginx-gateway` namespace manages all WAF operations +- **Per-Gateway Deployment**: Each Gateway with WAF enabled gets a dedicated multi-container NGINX Pod +- **Selective WAF Enablement**: Only Gateways configured with WAF-enabled NginxProxy resources deploy NAP v5 containers +- **Centralized Policy Management**: NGF controllers fetch policies and distribute them to appropriate NGINX Pods via the existing Agent gRPC connection + +## API, Customer Driven Interfaces, and User Experience + +### NginxProxy Resource Extension + +Users enable WAF through the NginxProxy resource, + +```yaml +apiVersion: gateway.nginx.org/v1alpha2 +kind: NginxProxy +metadata: + name: nginx-proxy-waf + namespace: nginx-gateway +spec: + # Simple WAF enablement (hides multi-container complexity) + waf: + enabled: true + # configuration tweaks optional, e.g.: +# kubernetes: +# deployment: +# # NGINX container with NAP module (will set to default if waf enabled is true but these values are not configured) +# container: +# image: +# repository: private-registry.nginx.com/nginx-gateway-fabric/nginx-plus-waf +# tag: "2.1.0" + +# # NAP v5 required containers (will set to defaults if waf enabled is true but these values are not configured) +# wafContainers: +# enforcer: +# image: +# repository: private-registry.nginx.com/nap/waf-enforcer +# tag: "5.6.0" + +# configManager: +# image: +# repository: private-registry.nginx.com/nap/waf-config-mgr +# tag: "5.6.0" +``` + +### WafPolicy Custom Resource + +Due to NAP v5's pre-compilation requirement, policies must be referenced from external sources: + +```yaml +apiVersion: gateway.nginx.org/v1alpha1 +kind: WafPolicy +metadata: + name: production-waf-policy + namespace: applications +spec: + # Policy source (required due to NAP v5 pre-compilation) + policySource: + fileLocation: "s3://ngf-waf-policies/production/policy-v1.2.3.tgz" + authSecret: + name: "policy-store-credentials" + validation: + checksumVerification: true + # Note: Policy content validation handled by NAP v5 components + + # Retry configuration for policy fetch failures + retryPolicy: + attempts: 3 + backoff: "exponential" + maxDelay: "5m" + + # Timeout for policy downloads + timeout: "30s" + + # Security logging configuration for app_protect_security_log directives + # Multiple log configurations are supported + securityLogs: + - name: "stderr-logging" + # Built-in logging profile (validated against allowed values) + logProfile: "log_all" # log_all, log_blocked, log_grpc_all, log_grpc_blocked, log_grpc_illegal, log_illegal + destination: + stderr: true + + - name: "file-logging" + # Custom logging profile bundle (similar to policy bundle) + # logProfile and logProfileBundle are mutually exclusive per security log configuration entry + logProfileBundle: + fileLocation: "s3://ngf-waf-policies/logging/custom-log-profile.tgz" + authSecret: + name: "policy-store-credentials" + validation: + checksumVerification: true + retryPolicy: + attempts: 3 + backoff: "exponential" + maxDelay: "5m" + timeout: "30s" + destination: + file: + path: "/var/log/app_protect/security.log" + # Note: check this folder is actually writeable. + # Path must be on shared volume accessible to waf-enforcer container + + - name: "syslog-logging" + logProfile: "log_blocked" + destination: + syslog: + server: "syslog-svc.default:514" + # Note: TCP transport, unsecured. Use local syslog proxy for secure forwarding + +--- +# Status examples showing WafPolicy Conditions +# TODO - Need to design Conditions +``` + +### HTTPRoute Integration + +```yaml +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: protected-application +spec: + parentRefs: + - name: nginx-gateway + rules: + - matches: + - path: + type: PathPrefix + value: "/api" + filters: + - type: ExtensionRef + extensionRef: + group: gateway.nginx.org + kind: WafPolicy + name: production-waf-policy + backendRefs: + - name: api-service + port: 8080 +``` + +### Authentication Methods + +The policy fetcher supports multiple authentication methods with preference for cloud-native approaches: + +**Priority Order:** + +1. **Native Cloud Authentication (Recommended)** +2. **Kubernetes Secrets (Fallback)** +3. **No Authentication (Public endpoints)** + +#### Native Cloud Authentication + +For cloud-hosted policy storage, NGF automatically detects and uses native cloud authentication when available. Supported methods: + +- AWS S3 with IAM Roles for Service Accounts +- Azure Workload Identity Implementation +- GCP Workload Identity Implementation + +**AWS S3 with IAM Roles for Service Accounts (IRSA):** + +```yaml +# Cluster operator configures service account (no WafPolicy changes needed) +apiVersion: v1 +kind: ServiceAccount +metadata: + name: nginx-gateway-fabric + namespace: nginx-gateway + annotations: + eks.amazonaws.com/role-arn: "arn:aws:iam::123456789012:role/NGFPolicyAccessRole" + +# WafPolicy uses S3 without explicit credentials +# NGF service account in nginx-gateway namespace provides IRSA authentication +spec: + policySource: + fileLocation: "s3://company-waf-policies/policy.tgz" + # No authSecret needed - uses IRSA automatically +``` + +##### Benefits of Native Cloud Authentication + +- No long-lived credentials stored in Kubernetes secrets +- Automatic credential rotation handled by cloud provider +- Fine-grained permissions managed through cloud IAM +- Reduced operational overhead for credential management + +#### Kubernetes Secrets (Fallback) + +For environments without native cloud integration or non-cloud storage: + +##### Secret Structure Design + +To begin with, we will likely only support a limited number of HTTP authentication methods, such as HTTP Basic Auth and HTTP Bearer Token. + +```yaml +# HTTP Basic Auth +apiVersion: v1 +kind: Secret +type: Opaque +data: + type: aHR0cC1iYXNpYw== # base64("http-basic") + username: + password: + +--- +# HTTP Bearer Token +apiVersion: v1 +kind: Secret +type: Opaque +data: + type: aHR0cC1iZWFyZXI= # base64("http-bearer") + token: +``` + +## Use Cases + +### Enterprise Security Operations + +- **SecOps teams** compile and manage WAF policies using existing NAP v5 tooling +- **CI/CD pipelines** automate policy compilation, testing, and distribution +- **Platform teams** deploy WAF-enabled gateways without managing policy complexity +- **Development teams** attach WAF protection to routes through simple Kubernetes resources + +### Multi-Environment Deployment + +- **Development**: Monitoring mode with detailed logging for policy tuning +- **Staging**: WAF-enabled Gateway for comprehensive policy testing alongside standard Gateways +- **Production**: Full enforcement with performance-optimized policy bundles across multiple Gateways + +### Selective WAF Deployment + +- **Mixed Environment**: Some Gateways with WAF protection, others without, all managed by single NGF control plane +- **Resource Optimization**: WAF containers only deployed where needed, reducing resource consumption +- **Independent Scaling**: Each Gateway's NGINX Pod scales independently based on traffic requirements + +### Air-Gapped Environments + +- **In-cluster policy storage**: Deploy MinIO or HTTP server within cluster boundaries +- **Offline compilation**: Use NAP v5 tools in secure environments, upload bundles manually +- **No external dependencies**: Complete WAF functionality without internet access + +Example air-gapped configuration: + +```yaml +spec: + policySource: + fileLocation: "http://policy-server.nginx-system.svc.cluster.local/policies/prod-policy.tgz" +``` + +### Regulatory Compliance + +- **Audit trails**: Complete policy version history and deployment tracking +- **Change control**: Formal approval processes for policy compilation and deployment +- **Immutable policies**: Compiled policy bundles provide tamper-proof security configurations + +## Testing + +### Unit Testing + +- **NginxProxy Extensions**: WAF enablement configuration parsing and validation +- **WafPolicy Controller**: CRUD operations, status management, and policy fetching logic +- **Multi-container Orchestration**: Container startup sequences and ephemeral volume management +- **Policy Validation**: Compiled policy bundle checksum integrity checking + +### Integration Testing + +- **End-to-End Workflows**: Complete policy compilation, distribution, and enforcement across multiple Gateway scenarios +- **NGF Control Plane**: Single NGF Pod managing multiple WAF-enabled and standard NGINX Pods +- **Policy Distribution**: Centralized policy fetching with distribution to appropriate NGINX Pods via gRPC +- **Multi-Container Pod**: NAP v5 container interaction via shared volumes in Gateway-specific NGINX Pods +- **Authentication**: Various credential types and failure handling for policy sources +- **Network Scenarios**: Policy fetching from different source types (S3, HTTP, in-cluster) +- **Selective Deployment**: Testing WAF enablement on subset of Gateways while others remain standard + +### Performance Testing + +- **Latency Impact**: Request processing overhead with NAP v5 enabled +- **Throughput Analysis**: Concurrent request handling capacity with WAF protection +- **Resource Utilization**: Memory and CPU consumption of multi-container pods +- **Policy Size Impact**: Large compiled policy bundle handling and distribution timing +- **Scale Testing**: Multiple WafPolicy resources and policy updates under load +- **Ephemeral Volume Performance**: Volume I/O performance and sizing validation + +### Conformance Testing + +- **Gateway API Compatibility**: Ensure proper integration with Gateway API specifications +- **Kubernetes Resource Validation**: CRD schema validation +- **Security Policy Enforcement**: Verify attack blocking with known threat patterns + +## Security Considerations + +### Policy Security + +- **Integrity Verification**: Checksum validation of compiled policy bundles prevents tampering +- **Secure Transport**: TLS encryption for all policy downloads from external sources +- **Access Control**: RBAC restrictions on WafPolicy resource creation and modification + +### Credential Management + +- **Native Cloud Authentication**: Preferred method using cloud provider's Kubernetes integration (IRSA, Workload Identity, etc.) +- **Kubernetes Secrets**: Fallback method for environments without native cloud integration +- **Automatic Detection**: NGF automatically detects and uses the most appropriate authentication method +- **Credential Rotation**: Native cloud authentication provides automatic rotation; secret-based authentication supports manual rotation without service disruption +- **Least Privilege**: Minimal access requirements for policy fetching operations +- **No Long-Lived Credentials**: Native cloud authentication eliminates the need for storing long-lived credentials in cluster + +### Runtime Security + +- **Container Isolation**: Proper security contexts and resource boundaries for NAP v5 containers +- **Multi-Container Security**: Expanded attack surface managed through container privilege boundaries +- **Resource Limits**: Prevention of resource exhaustion through container resource constraints + +### Storage Security + +- **Ephemeral Storage**: Policy and configuration volumes use ephemeral storage, ensuring no persistent state that could be compromised and alignment with immutable infrastructure principles +- **ReadOnlyRootFilesystem**: Maintains existing NGF security pattern with no writable root filesystem +- **Volume Permissions**: Proper file permissions and access controls on shared volumes + +### Policy Distribution Security + +- **Transport Security**: TLS encryption and certificate validation for HTTPS policy sources +- **Policy Integrity**: Checksum verification prevents corrupted or tampered policy deployment +- **Authentication**: Support for cloud-native and secret-based authentication to policy sources + +### Operator Security Requirements + +- **Network Segmentation**: Operators must configure NetworkPolicies for controlled egress access +- **Source Authorization**: Operators responsible for ensuring policy sources are legitimate and approved +- **Access Logging**: Standard Kubernetes audit logging captures WafPolicy resource operations; policy fetch operations logged via NGF's existing logging mechanisms + +## Alternatives + +### Alternative 1: Inline Policy Definition + +**Approach**: Allow users to define WAF policies directly in Kubernetes YAML +**Rejected Reason**: NAP v5 requires pre-compiled policy bundles; inline definition not supported by underlying technology + +### Alternative 2: NGF-Managed Policy Compilation + +**Approach**: Build policy compilation capabilities into NGF controller +**Rejected Reason**: Would require embedding NAP v5 compiler toolchain in NGF, significantly increasing complexity and licensing requirements + +### Alternative 3: Persistent Volume Storage + +**Approach**: Use PersistentVolumeClaims for NAP v5 shared storage +**Rejected Reason**: Conflicts with NGF's existing ReadOnlyRootFilesystem pattern; ephemeral storage provides better security posture and operational simplicity + +### Alternative 4: NGINX Direct Policy Fetching + +**Approach**: Have NGINX containers fetch policies directly using njs +**Rejected Reason**: Creates distributed system complexity, inconsistent state issues, and violates NGF's centralized control plane pattern + +## Future Enhancements + +- **Policy signature verification**: Cryptographic validation of policy bundle authenticity using public key infrastructure + +## References + +### Technical Documentation + +- [NGINX App Protect WAF v5 Documentation](https://docs.nginx.com/nginx-app-protect-waf/v5/) +- [NGINX App Protect Configuration Guide](https://docs.nginx.com/nginx-app-protect-waf/v5/configuration-guide/configuration/) +- [NGINX App Protect Compiler Guide](https://docs.nginx.com/nginx-app-protect-waf/v5/admin-guide/compiler/) + +### Implementation Examples + +```yaml +# Complete example configuration showing all components working together + +# 1. Secret for policy source authentication +apiVersion: v1 +kind: Secret +metadata: + name: policy-store-credentials + namespace: applications +type: Opaque +data: + type: aHR0cC1iZWFyZXI= # base64("http-bearer") + token: + +--- +# 2. NginxProxy with WAF enabled +apiVersion: gateway.nginx.org/v1alpha2 +kind: NginxProxy +metadata: + name: waf-enabled-proxy + namespace: nginx-gateway +spec: + waf: + enabled: true + +--- +# 3. Gateway using WAF-enabled proxy +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: secure-gateway + namespace: applications +spec: + gatewayClassName: nginx + infrastructure: + parametersRef: + name: waf-enabled-proxy + group: gateway.nginx.org + kind: NginxProxy + listeners: + - name: http + port: 80 + protocol: HTTP + +--- +# 4. WafPolicy referencing compiled policy +apiVersion: gateway.nginx.org/v1alpha1 +kind: WafPolicy +metadata: + name: app-security-policy + namespace: applications +spec: + policySource: + fileLocation: "https://company-waf-policies/production/app-policy-v2.1.0.tgz" + authSecret: + name: "policy-store-credentials" + securityLogs: + - name: "default-logging" + logProfile: "log_blocked" + destination: + syslog: + server: "syslog-svc.default:514" + +--- +# 5. HTTPRoute with WAF protection +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: protected-app-route + namespace: applications +spec: + parentRefs: + - name: secure-gateway + namespace: applications + rules: + - matches: + - path: + type: PathPrefix + value: "/app" + filters: + - type: ExtensionRef + extensionRef: + group: gateway.nginx.org + kind: WafPolicy + name: app-security-policy + backendRefs: + - name: application-service + port: 8080 +``` From 825005ae86030c9bfdd5d6907ea3d1127c74d4eb Mon Sep 17 00:00:00 2001 From: Ciara Stacke Date: Mon, 26 May 2025 12:25:44 +0100 Subject: [PATCH 2/8] Change proposal to use inherited policies --- docs/proposals/nap-waf.md | 473 +++++++++++++++++++++++++++++++------- 1 file changed, 396 insertions(+), 77 deletions(-) diff --git a/docs/proposals/nap-waf.md b/docs/proposals/nap-waf.md index 76bc27844a..cbec539d32 100644 --- a/docs/proposals/nap-waf.md +++ b/docs/proposals/nap-waf.md @@ -5,17 +5,18 @@ ## Summary -This proposal describes the integration of NGINX App Protect (NAP) WAF v5 into NGINX Gateway Fabric (NGF) to provide comprehensive WAF protection at Gateway and Route levels while working within NAP v5's architectural constraints of multi-container deployment and pre-compiled policy requirements. +This proposal describes the integration of NGINX App Protect (NAP) WAF v5 into NGINX Gateway Fabric (NGF) to provide comprehensive WAF protection at Gateway and Route levels while working within NAP v5's architectural constraints of multi-container deployment and pre-compiled policy requirements. The design uses Gateway API inherited policy attachment to provide flexible, hierarchical WAF protection. ## Goals - Extend NginxProxy resource to enable NAP WAF for GatewayClass/Gateway with multi-container orchestration -- Design WafPolicy custom resource for Route-level WAF configuration that references pre-compiled policy bundles +- Design WafPolicy custom resource using inherited policy attachment for hierarchical WAF configuration - Define deployment workflows that accommodate NAP v5's external policy compilation requirements - Provide secure and automated policy distribution mechanisms from external sources -- Deliver enterprise-grade WAF capabilities through Kubernetes-native APIs +- Deliver enterprise-grade WAF capabilities through Kubernetes-native APIs with intuitive policy inheritance - Maintain alignment with NGF's existing security and operational patterns - Support configurable security logging for WAF events and policy violations +- Support both HTTPRoute and GRPCRoute protection ## Non-Goals @@ -35,11 +36,20 @@ NGINX App Protect WAF v5 imposes specific architectural requirements that fundam - **Multi-container deployment**: Requires separate `waf-enforcer` and `waf-config-mgr` containers alongside the main NGINX container - **Pre-compiled policies**: WAF policies must be compiled externally using NAP tooling before deployment (cannot be defined inline in Kubernetes resources) - **Shared volume architecture**: Containers communicate through shared filesystem volumes rather than direct API calls -- **External policy management**: Policy compilation and distribution must be handled outside the Kubernetes cluster +- **External storage requirement**: Compiled policy bundles must be distributed via external storage systems (S3, HTTP, MinIO) ### Design Philosophy -This proposal provides the best possible Kubernetes-native experience while respecting NAP v5 constraints, abstracting complexity from end users where possible while maintaining operational flexibility for enterprise environments. +This proposal provides the best possible Kubernetes-native experience while respecting NAP v5 constraints, abstracting complexity from end users where possible while maintaining operational flexibility for enterprise environments. The design uses Gateway API's inherited policy attachment pattern to provide intuitive hierarchical security with the ability to override policies at more specific levels. + +### Policy Attachment Strategy + +The design uses **inherited policy attachment** following Gateway API best practices: + +- **Gateway-level policies** provide default protection for all routes attached to the Gateway +- **Route-level policies** can override Gateway-level policies for specific routes requiring different protection +- **Policy precedence**: More specific policies (Route-level) override less specific policies (Gateway-level) +- **Automatic inheritance**: New routes automatically receive Gateway-level protection without explicit configuration ### Storage Architecture @@ -76,11 +86,13 @@ graph TB %% Gateway Resources Gateway[Gateway
*.example.com] HTTPRoute[HTTPRoute
Protected Route] + GRPCRoute[GRPCRoute
Protected gRPC Service] Application[Application
Backend Service] %% Custom Resources (all in app namespace) NginxProxy[NginxProxy
waf.enabled=true] - WafPolicy[WafPolicy
Policy Reference] + GatewayWafPolicy[WafPolicy
Gateway-level Protection] + RouteWafPolicy[WafPolicy
Route-level Override] Secret[Secret
Store Credentials
Optional - Fallback Auth Only] %% NGINX Data Plane (WAF Enabled) @@ -106,17 +118,24 @@ graph TB SecTeam -->|Develop & Compile| Compiler Compiler -->|Publish Bundle| Store + %% Policy Attachment Flow + GatewayWafPolicy -.->|Targets & Protects| Gateway + RouteWafPolicy -.->|Targets & Overrides| HTTPRoute + Gateway -->|Inherits Protection| HTTPRoute + Gateway -->|Inherits Protection| GRPCRoute + %% Configuration Flow - Store -.->|Policy Location| WafPolicy + Store -.->|Policy Location| GatewayWafPolicy + Store -.->|Policy Location| RouteWafPolicy NginxProxy -.->|Enables WAF| Gateway - WafPolicy -.->|Protects| HTTPRoute %% Control Plane Operations NGFPod -->|Watches Resources| NginxProxy - NGFPod -->|Watches Resources| WafPolicy + NGFPod -->|Watches Resources| GatewayWafPolicy + NGFPod -->|Watches Resources| RouteWafPolicy NGFPod -->|Fetches Policy
Native Cloud Auth| Store - NGFPod -.->|Fallback: Uses Credentials| Secret NGFServiceAccount -.->|Cloud Provider
Authentication| Store + NGFPod -.->|Fallback: Uses Credentials| Secret NGFPod ===|gRPC Config| NGINXContainer NGFPod -->|Deploy Policy| PolicyVol @@ -128,12 +147,13 @@ graph TB NGINXContainer <-->|Shared FS| ConfigVol %% Traffic Flow - Client ==>|HTTP/HTTPS| PublicEndpoint + Client ==>|HTTP/HTTPS/gRPC| PublicEndpoint PublicEndpoint ==>|WAF Protected| NGINXContainer NGINXContainer ==>|Filtered Traffic| Application %% Resource Relationships HTTPRoute -->|Attached to| Gateway + GRPCRoute -->|Attached to| Gateway %% Styling classDef external fill:#e1f5fe,stroke:#01579b,stroke-width:2px @@ -145,12 +165,14 @@ graph TB classDef endpoint fill:#FFD700,stroke:#333,stroke-width:2px classDef optional fill:#f0f8ff,stroke:#4169e1,stroke-width:2px,stroke-dasharray: 5 5 classDef cloudAuth fill:#e8f5e8,stroke:#228b22,stroke-width:2px + classDef policy fill:#fff0e6,stroke:#d2691e,stroke-width:2px class SecTeam,Compiler,Store external class NGFPod control class NGFServiceAccount cloudAuth - class Gateway,HTTPRoute gateway - class WafEnforcer,WafConfigMgr,PolicyVol,NginxProxy,WafPolicy wafRequired + class Gateway,HTTPRoute,GRPCRoute gateway + class WafEnforcer,WafConfigMgr,PolicyVol,NginxProxy wafRequired + class GatewayWafPolicy,RouteWafPolicy policy class Application app class PolicyVol,ConfigVol volume class PublicEndpoint endpoint @@ -158,12 +180,12 @@ graph TB %% Notes about the architecture classDef note fill:#fffacd,stroke:#daa520,stroke-width:1px,stroke-dasharray: 5 5 - Note1[📝 Note: Architecture supports multiple Gateways
with selective WAF enablement per Gateway] + Note1[📝 Note: Gateway-level WafPolicy provides inherited protection
Route-level WafPolicy can override for specific routes] Note2[📝 Note: Secret only required for fallback authentication
Native cloud auth uses NGF Service Account annotations] class Note1,Note2 note ``` -This architecture diagram illustrates the complete NAP v5 WAF integration within NGINX Gateway Fabric, showing the flow from policy development to traffic protection: +This architecture demonstrates the hierarchical policy attachment system where Gateway-level WafPolicies provide default protection that can be overridden by Route-level policies for granular control: **External Policy Management (Blue):** Security teams develop WAF policies using NAP v5 JSON schema, compile them using NAP v5 compiler tools, and publish the compiled policy bundles to accessible storage locations (S3, HTTP servers, or MinIO). @@ -171,13 +193,15 @@ This architecture diagram illustrates the complete NAP v5 WAF integration within **Data Plane (Green/Red):** When WAF is enabled through NginxProxy configuration, each Gateway deploys as a multi-container NGINX Pod containing the main NGINX container with NAP module, plus the required WAF Enforcer and WAF Config Manager containers. These containers communicate through shared ephemeral volumes rather than network calls, maintaining NAP v5's architectural requirements. -**Application Namespace Resources:** All user-facing resources (Gateway, HTTPRoute, WafPolicy, NginxProxy, and optional authentication Secret) reside in application namespaces for proper isolation and RBAC management. The Secret is only required when using fallback authentication methods - native cloud authentication uses annotations on the NGF service account in the nginx-gateway namespace. +**Application Namespace Resources:** All user-facing resources (Gateway, HTTPRoute, GRPCRoute, WafPolicy, NginxProxy, and optional authentication Secret) reside in application namespaces for proper isolation and RBAC management. The Secret is only required when using fallback authentication methods for accessing external policy storage - native cloud authentication for accessing external policy storage (S3, Azure Blob, etc.) uses annotations on the NGF service account in the nginx-gateway namespace. -**Traffic Flow (Yellow/Gold):** Client traffic flows through the public load balancer endpoint to the WAF-protected NGINX container, where NAP v5 applies security policies before forwarding clean traffic to backend applications. +**Policy Attachment Flow (Orange):** WafPolicy resources use targetRefs to attach to Gateways or Routes. Gateway-level policies provide inherited protection for all attached HTTPRoutes and GRPCRoutes. Route-level policies can override Gateway-level policies for specific routes requiring different protection levels. -**Resource Relationships:** WafPolicy resources attach to HTTPRoutes via Gateway API ExtensionRef filters, while NginxProxy resources enable WAF functionality at the Gateway level. This design supports selective WAF deployment where some Gateways have WAF protection while others remain standard, all managed by a single NGF control plane. +**Traffic Flow (Yellow/Gold):** Client traffic (HTTP, HTTPS, and gRPC) flows through the public load balancer endpoint to the WAF-protected NGINX container, where NAP v5 applies security policies before forwarding filtered traffic to backend applications. -The architecture demonstrates separation of concerns: external policy compilation and storage, centralized policy distribution, and distributed policy enforcement, while maintaining security through ephemeral storage and immutable infrastructure principles. +**Policy Inheritance:** Gateway-level WafPolicies automatically protect all routes attached to the Gateway. Route-level WafPolicies can override Gateway policies with more specific protection. This design supports both broad default protection and granular security controls while maintaining operational simplicity. + +The architecture demonstrates separation of concerns: external policy compilation and storage, centralized policy distribution with inheritance hierarchy, and distributed policy enforcement, while maintaining security through ephemeral storage and immutable infrastructure principles. ### Network Access Requirements @@ -205,8 +229,8 @@ Given NAP v5 constraints, users must follow this workflow: 2. **Log Profile Development**: Create custom logging profiles or use built-in profiles (log_all, log_blocked, etc.) 3. **Compilation**: Use NAP v5 compiler tools to create policy and logging profile bundles 4. **Distribution**: Publish compiled policies and log profiles to accessible storage (S3, HTTP) -5. **Configuration**: Create WafPolicy CR referencing the policy location and configuring security logging -6. **Manual Deployment**: NGF fetches and applies policies when WafPolicy is created or updated +5. **Configuration**: Create WafPolicy CR with targetRefs referencing Gateway or Routes and configuring security logging +6. **Automatic Application**: NGF fetches and applies policies when WafPolicy is created or updated, with automatic inheritance **Note**: Policy enforcement mode and behavior are defined within the compiled NAP policy itself. Security logging profiles can be either built-in names or custom compiled bundles. @@ -232,7 +256,7 @@ aws s3 cp log-profile.tgz s3://company-policies/logging/custom-log-profile.tgz aws s3 cp log-profile.tgz.sha256 s3://company-policies/logging/custom-log-profile.tgz.sha256 # Manual update: Modify WafPolicy resource to reference new policy and logging -kubectl patch wafpolicy app-policy \ +kubectl patch wafpolicy gateway-protection \ --patch '{"spec":{"policySource":{"fileLocation":"s3://company-policies/prod-policy-v'$(date +%Y%m%d)'.tgz"}}}' ``` @@ -257,9 +281,9 @@ The securityLogs section supports multiple logging configurations, each generati **Destination Types:** -- `stderr`: Output to container stderr -- `file`: Write to specified file path (must be mounted to host for waf-enforcer container access) -- `syslog`: Send to syslog server via TCP (recommend local proxy for secure forwarding) +- `type: "Stderr"`: Output to container stderr +- `type: "File"`: Write to specified file path (must be mounted to host for waf-enforcer container access) +- `type: "Syslog"`: Send to syslog server via TCP (recommend local proxy for secure forwarding) **Generated NGINX Configuration Examples:** @@ -294,6 +318,25 @@ In the cases where there are policy fetch failures: - No service disruption during retry attempts - Detailed error messages for troubleshooting +### Policy Inheritance and Precedence + +The design supports hierarchical policy application with clear precedence rules: + +**Inheritance Hierarchy:** + +- Gateway-level WafPolicy → HTTPRoute (inherited) +- Gateway-level WafPolicy → GRPCRoute (inherited) + +**Override Precedence (most specific wins):** + +- Route-level WafPolicy > Gateway-level WafPolicy + +**Conflict Resolution:** + +- Multiple policies targeting the same resource at the same level = error/rejected +- More specific policy completely overrides less specific policy +- Clear status reporting indicates which policy is active for each route + ### NGF Integration Architecture The integration leverages NGF's existing architecture: @@ -307,7 +350,7 @@ The integration leverages NGF's existing architecture: ### NginxProxy Resource Extension -Users enable WAF through the NginxProxy resource, +Users enable WAF through the NginxProxy resource: ```yaml apiVersion: gateway.nginx.org/v1alpha2 @@ -316,19 +359,19 @@ metadata: name: nginx-proxy-waf namespace: nginx-gateway spec: - # Simple WAF enablement (hides multi-container complexity) + # WAF policy configuration (extensible design) waf: - enabled: true + policy: "Enabled" # "Enabled" | "Disabled" # configuration tweaks optional, e.g.: # kubernetes: # deployment: -# # NGINX container with NAP module (will set to default if waf enabled is true but these values are not configured) +# # NGINX container with NAP module (will set to default if waf policy is "Enabled" but these values are not configured) # container: # image: # repository: private-registry.nginx.com/nginx-gateway-fabric/nginx-plus-waf # tag: "2.1.0" -# # NAP v5 required containers (will set to defaults if waf enabled is true but these values are not configured) +# # NAP v5 required containers (will set to defaults if waf policy is "Enabled" but these values are not configured) # wafContainers: # enforcer: # image: @@ -341,25 +384,33 @@ spec: # tag: "5.6.0" ``` -### WafPolicy Custom Resource +### WafPolicy Custom Resource with Policy Attachment -Due to NAP v5's pre-compilation requirement, policies must be referenced from external sources: +Due to NAP v5's pre-compilation requirement, policies must be referenced from external sources and use targetRefs for policy attachment: ```yaml apiVersion: gateway.nginx.org/v1alpha1 kind: WafPolicy metadata: - name: production-waf-policy + name: gateway-protection-policy namespace: applications spec: + # Policy attachment - targets Gateway for inherited protection + targetRefs: + - group: gateway.networking.k8s.io + kind: Gateway + name: secure-gateway + namespace: applications + # Policy source (required due to NAP v5 pre-compilation) policySource: - fileLocation: "s3://ngf-waf-policies/production/policy-v1.2.3.tgz" + fileLocation: "s3://ngf-waf-policies/production/gateway-policy-v1.2.3.tgz" authSecret: name: "policy-store-credentials" validation: - checksumVerification: true + methods: ["Checksum"] # Note: Policy content validation handled by NAP v5 components + # We will support signature verification in the future # Retry configuration for policy fetch failures retryPolicy: @@ -377,7 +428,7 @@ spec: # Built-in logging profile (validated against allowed values) logProfile: "log_all" # log_all, log_blocked, log_grpc_all, log_grpc_blocked, log_grpc_illegal, log_illegal destination: - stderr: true + type: "Stderr" - name: "file-logging" # Custom logging profile bundle (similar to policy bundle) @@ -387,13 +438,14 @@ spec: authSecret: name: "policy-store-credentials" validation: - checksumVerification: true + methods: ["Checksum"] retryPolicy: attempts: 3 backoff: "exponential" maxDelay: "5m" timeout: "30s" destination: + type: "File" file: path: "/var/log/app_protect/security.log" # Note: check this folder is actually writeable. @@ -402,39 +454,130 @@ spec: - name: "syslog-logging" logProfile: "log_blocked" destination: + type: "Syslog" syslog: server: "syslog-svc.default:514" # Note: TCP transport, unsecured. Use local syslog proxy for secure forwarding +--- +# Route-level override example +apiVersion: gateway.nginx.org/v1alpha1 +kind: WafPolicy +metadata: + name: admin-strict-policy + namespace: applications +spec: + # Policy attachment - targets specific HTTPRoute to override Gateway policy + targetRefs: + - group: gateway.networking.k8s.io + kind: HTTPRoute + name: admin-route + namespace: applications + + # Stricter policy for admin endpoints + policySource: + fileLocation: "s3://ngf-waf-policies/production/admin-strict-policy-v1.0.0.tgz" + authSecret: + name: "policy-store-credentials" + securityLogs: + - name: "admin-logging" + logProfile: "log_all" # Log everything for admin routes + destination: + type: "Stderr" + --- # Status examples showing WafPolicy Conditions # TODO - Need to design Conditions ``` -### HTTPRoute Integration +### Gateway and Route Resources + +#### Gateway Configuration + +```yaml +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: secure-gateway + namespace: applications +spec: + gatewayClassName: nginx + infrastructure: + parametersRef: + name: nginx-proxy-waf + group: gateway.nginx.org + kind: NginxProxy + listeners: + - name: http + port: 80 + protocol: HTTP + - name: grpc + port: 9090 + protocol: HTTP + hostname: "grpc.example.com" +``` + +#### HTTPRoute Integration ```yaml apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: protected-application + namespace: applications spec: parentRefs: - - name: nginx-gateway + - name: secure-gateway rules: - matches: - path: type: PathPrefix value: "/api" - filters: - - type: ExtensionRef - extensionRef: - group: gateway.nginx.org - kind: WafPolicy - name: production-waf-policy backendRefs: - name: api-service port: 8080 + +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: admin-route + namespace: applications +spec: + parentRefs: + - name: secure-gateway + rules: + - matches: + - path: + type: PathPrefix + value: "/admin" + backendRefs: + - name: admin-service + port: 8080 + # Uses admin-strict-policy WafPolicy override via targetRefs +``` + +#### GRPCRoute Integration + +```yaml +apiVersion: gateway.networking.k8s.io/v1alpha2 +kind: GRPCRoute +metadata: + name: protected-grpc-service + namespace: applications +spec: + parentRefs: + - name: secure-gateway + hostnames: + - "grpc.example.com" + rules: + - matches: + - method: + service: "user.UserService" + backendRefs: + - name: grpc-service + port: 9000 + # WAF protection inherited from Gateway-level WafPolicy ``` ### Authentication Methods @@ -512,24 +655,68 @@ data: ## Use Cases +### Hierarchical WAF Protection + +#### Gateway-Level Default Protection + +```yaml +# Provides base WAF protection for all routes +apiVersion: gateway.nginx.org/v1alpha1 +kind: WafPolicy +metadata: + name: gateway-base-protection + namespace: applications +spec: + targetRefs: + - group: gateway.networking.k8s.io + kind: Gateway + name: main-gateway + policySource: + fileLocation: "s3://policies/base-protection.tgz" +``` + +**Result**: All HTTPRoutes and GRPCRoutes attached to `main-gateway` automatically inherit WAF protection. + +#### Route-Level Override + +```yaml +# Stricter protection for sensitive endpoints +apiVersion: gateway.nginx.org/v1alpha1 +kind: WafPolicy +metadata: + name: admin-strict-protection + namespace: applications +spec: + targetRefs: + - group: gateway.networking.k8s.io + kind: HTTPRoute + name: admin-routes + policySource: + fileLocation: "s3://policies/strict-admin-protection.tgz" +``` + +**Result**: Admin routes get stricter protection while other routes continue using base protection. + ### Enterprise Security Operations - **SecOps teams** compile and manage WAF policies using existing NAP v5 tooling - **CI/CD pipelines** automate policy compilation, testing, and distribution -- **Platform teams** deploy WAF-enabled gateways without managing policy complexity -- **Development teams** attach WAF protection to routes through simple Kubernetes resources +- **Platform teams** deploy WAF-enabled gateways with inherited protection for all applications +- **Development teams** can override Gateway policies for specific routes when needed +- **Operations teams** benefit from simplified policy management with automatic inheritance ### Multi-Environment Deployment -- **Development**: Monitoring mode with detailed logging for policy tuning -- **Staging**: WAF-enabled Gateway for comprehensive policy testing alongside standard Gateways -- **Production**: Full enforcement with performance-optimized policy bundles across multiple Gateways +- **Development**: Gateway-level monitoring mode with detailed logging for policy tuning +- **Staging**: WAF-enabled Gateway for comprehensive policy testing with route-specific overrides +- **Production**: Full enforcement with performance-optimized policy bundles and granular route policies ### Selective WAF Deployment - **Mixed Environment**: Some Gateways with WAF protection, others without, all managed by single NGF control plane - **Resource Optimization**: WAF containers only deployed where needed, reducing resource consumption - **Independent Scaling**: Each Gateway's NGINX Pod scales independently based on traffic requirements +- **Flexible Protection**: Default Gateway protection with route-specific overrides as needed ### Air-Gapped Environments @@ -550,6 +737,7 @@ spec: - **Audit trails**: Complete policy version history and deployment tracking - **Change control**: Formal approval processes for policy compilation and deployment - **Immutable policies**: Compiled policy bundles provide tamper-proof security configurations +- **Policy inheritance tracking**: Clear visibility into which policies apply to which routes ## Testing @@ -557,11 +745,14 @@ spec: - **NginxProxy Extensions**: WAF enablement configuration parsing and validation - **WafPolicy Controller**: CRUD operations, status management, and policy fetching logic +- **Policy Attachment Logic**: targetRefs validation and inheritance resolution - **Multi-container Orchestration**: Container startup sequences and ephemeral volume management - **Policy Validation**: Compiled policy bundle checksum integrity checking ### Integration Testing +- **Policy Inheritance**: Gateway-level policies applying to HTTPRoutes and GRPCRoutes +- **Policy Override**: Route-level policies overriding Gateway-level policies - **End-to-End Workflows**: Complete policy compilation, distribution, and enforcement across multiple Gateway scenarios - **NGF Control Plane**: Single NGF Pod managing multiple WAF-enabled and standard NGINX Pods - **Policy Distribution**: Centralized policy fetching with distribution to appropriate NGINX Pods via gRPC @@ -572,18 +763,21 @@ spec: ### Performance Testing -- **Latency Impact**: Request processing overhead with NAP v5 enabled +- **Latency Impact**: Request processing overhead with NAP v5 enabled for HTTP and gRPC traffic - **Throughput Analysis**: Concurrent request handling capacity with WAF protection - **Resource Utilization**: Memory and CPU consumption of multi-container pods - **Policy Size Impact**: Large compiled policy bundle handling and distribution timing - **Scale Testing**: Multiple WafPolicy resources and policy updates under load - **Ephemeral Volume Performance**: Volume I/O performance and sizing validation +- **Policy Inheritance Performance**: Impact of policy resolution on request processing +- Note: current NFR testing likely covers all of these scenarios, but we may want to add a separate NGINX Plus WAF run ### Conformance Testing - **Gateway API Compatibility**: Ensure proper integration with Gateway API specifications +- **Policy Attachment Compliance**: Verify adherence to Gateway API policy attachment patterns - **Kubernetes Resource Validation**: CRD schema validation -- **Security Policy Enforcement**: Verify attack blocking with known threat patterns +- **Security Policy Enforcement**: Verify attack blocking with known threat patterns for HTTP and gRPC (high level, we don't need to test granular WAF functionality, just that the integration works as expected) ## Security Considerations @@ -628,22 +822,32 @@ spec: ## Alternatives -### Alternative 1: Inline Policy Definition +### Alternative 1: Filter-Based Attachment + +**Approach**: Use Gateway API filters instead of policy attachment +**Rejected Reason**: WAF is a cross-cutting security concern better suited to policy attachment; filters would require explicit configuration on every route and lack inheritance capabilities + +### Alternative 2: Direct Policy Attachment Only + +**Approach**: Support only direct policy attachment without inheritance +**Rejected Reason**: Would require explicit policy attachment to every route; inheritance provides better operational experience and matches typical WAF deployment patterns + +### Alternative 3: Inline Policy Definition **Approach**: Allow users to define WAF policies directly in Kubernetes YAML **Rejected Reason**: NAP v5 requires pre-compiled policy bundles; inline definition not supported by underlying technology -### Alternative 2: NGF-Managed Policy Compilation +### Alternative 4: NGF-Managed Policy Compilation **Approach**: Build policy compilation capabilities into NGF controller **Rejected Reason**: Would require embedding NAP v5 compiler toolchain in NGF, significantly increasing complexity and licensing requirements -### Alternative 3: Persistent Volume Storage +### Alternative 5: Persistent Volume Storage **Approach**: Use PersistentVolumeClaims for NAP v5 shared storage **Rejected Reason**: Conflicts with NGF's existing ReadOnlyRootFilesystem pattern; ephemeral storage provides better security posture and operational simplicity -### Alternative 4: NGINX Direct Policy Fetching +### Alternative 6: NGINX Direct Policy Fetching **Approach**: Have NGINX containers fetch policies directly using njs **Rejected Reason**: Creates distributed system complexity, inconsistent state issues, and violates NGF's centralized control plane pattern @@ -651,6 +855,7 @@ spec: ## Future Enhancements - **Policy signature verification**: Cryptographic validation of policy bundle authenticity using public key infrastructure +- **Advanced policy inheritance**: Support for policy merging and composition rather than simple override ## References @@ -659,13 +864,14 @@ spec: - [NGINX App Protect WAF v5 Documentation](https://docs.nginx.com/nginx-app-protect-waf/v5/) - [NGINX App Protect Configuration Guide](https://docs.nginx.com/nginx-app-protect-waf/v5/configuration-guide/configuration/) - [NGINX App Protect Compiler Guide](https://docs.nginx.com/nginx-app-protect-waf/v5/admin-guide/compiler/) +- [Gateway API Policy Attachment](https://gateway-api.sigs.k8s.io/reference/policy-attachment/) ### Implementation Examples ```yaml -# Complete example configuration showing all components working together +# Complete example configuration showing hierarchical policy attachment -# 1. Secret for policy source authentication +# 1. Optional Secret for policy source authentication (fallback only) apiVersion: v1 kind: Secret metadata: @@ -674,7 +880,7 @@ metadata: type: Opaque data: type: aHR0cC1iZWFyZXI= # base64("http-bearer") - token: + token: --- # 2. NginxProxy with WAF enabled @@ -685,7 +891,7 @@ metadata: namespace: nginx-gateway spec: waf: - enabled: true + policy: "Enabled" --- # 3. Gateway using WAF-enabled proxy @@ -705,49 +911,162 @@ spec: - name: http port: 80 protocol: HTTP + - name: grpc + port: 9090 + protocol: HTTP + hostname: "grpc.example.com" --- -# 4. WafPolicy referencing compiled policy +# 4. Gateway-level WafPolicy (inherited by all routes) apiVersion: gateway.nginx.org/v1alpha1 kind: WafPolicy metadata: - name: app-security-policy + name: gateway-base-protection namespace: applications spec: + # Policy attachment - protects entire Gateway and inherits to all routes + targetRefs: + - group: gateway.networking.k8s.io + kind: Gateway + name: secure-gateway + namespace: applications + policySource: - fileLocation: "https://company-waf-policies/production/app-policy-v2.1.0.tgz" + fileLocation: "s3://company-waf-policies/production/base-policy-v2.1.0.tgz" + # Secret referenced for fallback - NGF will use IRSA if available, secret if not authSecret: name: "policy-store-credentials" securityLogs: - - name: "default-logging" + - name: "gateway-logging" logProfile: "log_blocked" destination: - syslog: - server: "syslog-svc.default:514" + type: "Stderr" + +--- +# 5. Route-level WafPolicy override for admin endpoints +apiVersion: gateway.nginx.org/v1alpha1 +kind: WafPolicy +metadata: + name: admin-strict-protection + namespace: applications +spec: + # Policy attachment - overrides Gateway policy for specific route + targetRefs: + - group: gateway.networking.k8s.io + kind: HTTPRoute + name: admin-route + namespace: applications + + policySource: + fileLocation: "s3://company-waf-policies/production/admin-strict-policy-v1.0.0.tgz" + securityLogs: + - name: "admin-logging" + logProfile: "log_all" # More verbose logging for admin routes + destination: + type: "File" + file: + path: "/var/log/app_protect/admin-security.log" --- -# 5. HTTPRoute with WAF protection +# 6. HTTPRoute inheriting Gateway protection apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: - name: protected-app-route + name: api-route namespace: applications spec: parentRefs: - name: secure-gateway - namespace: applications rules: - matches: - path: type: PathPrefix - value: "/app" - filters: - - type: ExtensionRef - extensionRef: - group: gateway.nginx.org - kind: WafPolicy - name: app-security-policy + value: "/api" backendRefs: - - name: application-service + - name: api-service port: 8080 + # Inherits gateway-base-protection WafPolicy automatically + +--- +# 7. HTTPRoute with policy override +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: admin-route + namespace: applications +spec: + parentRefs: + - name: secure-gateway + rules: + - matches: + - path: + type: PathPrefix + value: "/admin" + backendRefs: + - name: admin-service + port: 8080 + # Uses admin-strict-protection WafPolicy override via targetRefs + +--- +# 8. GRPCRoute inheriting Gateway protection +apiVersion: gateway.networking.k8s.io/v1alpha2 +kind: GRPCRoute +metadata: + name: user-grpc-service + namespace: applications +spec: + parentRefs: + - name: secure-gateway + hostnames: + - "grpc.example.com" + rules: + - matches: + - method: + service: "user.UserService" + backendRefs: + - name: user-grpc-service + port: 9000 + # Inherits gateway-base-protection WafPolicy automatically + +--- +# 9. Example showing multiple route targeting +apiVersion: gateway.nginx.org/v1alpha1 +kind: WafPolicy +metadata: + name: api-routes-protection + namespace: applications +spec: + # Policy attachment - targets multiple routes with same policy + targetRefs: + - group: gateway.networking.k8s.io + kind: HTTPRoute + name: public-api-route + namespace: applications + - group: gateway.networking.k8s.io + kind: HTTPRoute + name: partner-api-route + namespace: applications + - group: gateway.networking.k8s.io + kind: GRPCRoute + name: api-grpc-service + namespace: applications + + policySource: + fileLocation: "s3://company-waf-policies/production/api-specific-policy-v1.5.0.tgz" + securityLogs: + - name: "api-logging" + logProfile: "log_blocked" + destination: + type: "Syslog" + syslog: + server: "syslog-svc.default:514" ``` + +This complete example demonstrates: + +- **Gateway-level inherited protection** for all routes by default +- **Route-level policy overrides** for specific security requirements +- **Multi-route targeting** for applying the same policy to multiple routes +- **HTTP and gRPC route support** with seamless policy inheritance +- **Native cloud authentication** with fallback secret support +- **Flexible logging configuration** per policy level From 0e1622d189264efb1ab7daba9ce3b754934559be Mon Sep 17 00:00:00 2001 From: Ciara Stacke Date: Tue, 27 May 2025 10:37:00 +0100 Subject: [PATCH 3/8] Add status conditions section --- docs/proposals/nap-waf.md | 157 ++++++++++++++++---------------------- 1 file changed, 65 insertions(+), 92 deletions(-) diff --git a/docs/proposals/nap-waf.md b/docs/proposals/nap-waf.md index cbec539d32..c469f532ea 100644 --- a/docs/proposals/nap-waf.md +++ b/docs/proposals/nap-waf.md @@ -36,7 +36,6 @@ NGINX App Protect WAF v5 imposes specific architectural requirements that fundam - **Multi-container deployment**: Requires separate `waf-enforcer` and `waf-config-mgr` containers alongside the main NGINX container - **Pre-compiled policies**: WAF policies must be compiled externally using NAP tooling before deployment (cannot be defined inline in Kubernetes resources) - **Shared volume architecture**: Containers communicate through shared filesystem volumes rather than direct API calls -- **External storage requirement**: Compiled policy bundles must be distributed via external storage systems (S3, HTTP, MinIO) ### Design Philosophy @@ -205,7 +204,7 @@ The architecture demonstrates separation of concerns: external policy compilatio ### Network Access Requirements -NGF requires outbound network access to fetch WAF policies from remote locations: +NGF requires outbound network access to fetch WAF policies from _remote_ locations: - **HTTPS/HTTP access** to policy storage endpoints (S3, Azure Blob, HTTP servers, etc.) - **DNS resolution** for policy storage hostnames @@ -221,6 +220,20 @@ NGF requires outbound network access to fetch WAF policies from remote locations **Note**: Network access configuration is environment-specific and handled through standard Kubernetes networking patterns rather than NGF-specific configuration options. +#### Air-Gapped Environments + +- **In-cluster policy storage**: Deploy MinIO or HTTP server within cluster boundaries +- **Offline compilation**: Use NAP v5 tools in secure environments & upload bundles manually, or do this step within cluster boundaries +- **No external dependencies**: Complete WAF functionality without internet access + +Example air-gapped configuration: + +```yaml +spec: + policySource: + fileLocation: "http://policy-server.nginx-system.svc.cluster.local/policies/prod-policy.tgz" +``` + ### Policy Development Workflow Given NAP v5 constraints, users must follow this workflow: @@ -241,21 +254,14 @@ Example CI/CD integration for manual updates: docker run --rm -v $(pwd):/policies nginx/nap-compiler:5.6.0 \ compile --input /policies/app-policy.json --output /policies/compiled-policy.tgz -# Compile custom logging profile (optional - can use built-in profiles) -docker run --rm -v $(pwd):/policies nginx/nap-compiler:5.6.0 \ - compile --input /policies/custom-log-profile.json --output /policies/log-profile.tgz - -# Generate checksums for integrity verification +# Generate checksum for integrity verification sha256sum compiled-policy.tgz > compiled-policy.tgz.sha256 -sha256sum log-profile.tgz > log-profile.tgz.sha256 # Publish to storage aws s3 cp compiled-policy.tgz s3://company-policies/prod-policy-v$(date +%Y%m%d).tgz aws s3 cp compiled-policy.tgz.sha256 s3://company-policies/prod-policy-v$(date +%Y%m%d).tgz.sha256 -aws s3 cp log-profile.tgz s3://company-policies/logging/custom-log-profile.tgz -aws s3 cp log-profile.tgz.sha256 s3://company-policies/logging/custom-log-profile.tgz.sha256 -# Manual update: Modify WafPolicy resource to reference new policy and logging +# Manual update: Modify WafPolicy resource to reference new policy kubectl patch wafpolicy gateway-protection \ --patch '{"spec":{"policySource":{"fileLocation":"s3://company-policies/prod-policy-v'$(date +%Y%m%d)'.tgz"}}}' ``` @@ -360,18 +366,17 @@ metadata: namespace: nginx-gateway spec: # WAF policy configuration (extensible design) - waf: - policy: "Enabled" # "Enabled" | "Disabled" - # configuration tweaks optional, e.g.: + waf: "Enabled" # "Enabled" | "Disabled" +# configuration tweaks optional, e.g.: # kubernetes: # deployment: -# # NGINX container with NAP module (will set to default if waf policy is "Enabled" but these values are not configured) +# # NGINX container with NAP module (will set to default if waf is "Enabled" but these values are not configured) # container: # image: # repository: private-registry.nginx.com/nginx-gateway-fabric/nginx-plus-waf # tag: "2.1.0" -# # NAP v5 required containers (will set to defaults if waf policy is "Enabled" but these values are not configured) +# # NAP v5 required containers (will set to defaults if waf is "Enabled" but these values are not configured) # wafContainers: # enforcer: # image: @@ -386,8 +391,6 @@ spec: ### WafPolicy Custom Resource with Policy Attachment -Due to NAP v5's pre-compilation requirement, policies must be referenced from external sources and use targetRefs for policy attachment: - ```yaml apiVersion: gateway.nginx.org/v1alpha1 kind: WafPolicy @@ -402,7 +405,6 @@ spec: name: secure-gateway namespace: applications - # Policy source (required due to NAP v5 pre-compilation) policySource: fileLocation: "s3://ngf-waf-policies/production/gateway-policy-v1.2.3.tgz" authSecret: @@ -486,10 +488,6 @@ spec: type: "Stderr" --- -# Status examples showing WafPolicy Conditions -# TODO - Need to design Conditions -``` - ### Gateway and Route Resources #### Gateway Configuration @@ -653,91 +651,61 @@ data: token: ``` -## Use Cases +### Status -### Hierarchical WAF Protection +#### CRD Label -#### Gateway-Level Default Protection +According to the [Policy and Metaresources GEP](https://gateway-api.sigs.k8s.io/geps/gep-713/), the `WafPolicy` CRD must have the `gateway.networking.k8s.io/policy: inherited` label to specify that it is an inherited policy. +This label will help with discoverability and will be used by the planned Gateway API Policy [kubectl plugin](https://gateway-api.sigs.k8s.io/geps/gep-713/#kubectl-plugin-or-command-line-tool). -```yaml -# Provides base WAF protection for all routes -apiVersion: gateway.nginx.org/v1alpha1 -kind: WafPolicy -metadata: - name: gateway-base-protection - namespace: applications -spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: Gateway - name: main-gateway - policySource: - fileLocation: "s3://policies/base-protection.tgz" -``` +#### Conditions -**Result**: All HTTPRoutes and GRPCRoutes attached to `main-gateway` automatically inherit WAF protection. +According to the [Policy and Metaresources GEP](https://gateway-api.sigs.k8s.io/geps/gep-713/), the `WafPolicy` CRD must include a `status` stanza with a slice of Conditions. -#### Route-Level Override +The `Accepted` Condition must be populated on the `WafPolicy` CRD using the reasons defined in the [PolicyCondition API](https://github.com/kubernetes-sigs/gateway-api/blob/main/apis/v1alpha2/policy_types.go). If these reasons are not sufficient, we can add implementation-specific reasons. -```yaml -# Stricter protection for sensitive endpoints -apiVersion: gateway.nginx.org/v1alpha1 -kind: WafPolicy -metadata: - name: admin-strict-protection - namespace: applications -spec: - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: admin-routes - policySource: - fileLocation: "s3://policies/strict-admin-protection.tgz" -``` +#### Setting Status on Objects Affected by a Policy -**Result**: Admin routes get stricter protection while other routes continue using base protection. +In the Policy and Metaresources GEP, there's a [provisional status described here](https://gateway-api.sigs.k8s.io/geps/gep-713/#standard-status-condition-on-policy-affected-objects) that involves adding a Condition or annotation to all objects affected by a Policy. -### Enterprise Security Operations +This solution gives the object owners some knowledge that their object is affected by a policy but minimizes status updates by limiting them to when the affected object starts or stops being affected by a policy. +Even though this status is provisional, implementing it now will help with discoverability and allow us to give feedback on the solution. -- **SecOps teams** compile and manage WAF policies using existing NAP v5 tooling -- **CI/CD pipelines** automate policy compilation, testing, and distribution -- **Platform teams** deploy WAF-enabled gateways with inherited protection for all applications -- **Development teams** can override Gateway policies for specific routes when needed -- **Operations teams** benefit from simplified policy management with automatic inheritance +Implementing this involves defining a new Condition type and reason: -### Multi-Environment Deployment +```go +package conditions -- **Development**: Gateway-level monitoring mode with detailed logging for policy tuning -- **Staging**: WAF-enabled Gateway for comprehensive policy testing with route-specific overrides -- **Production**: Full enforcement with performance-optimized policy bundles and granular route policies +import ( + gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" +) -### Selective WAF Deployment -- **Mixed Environment**: Some Gateways with WAF protection, others without, all managed by single NGF control plane -- **Resource Optimization**: WAF containers only deployed where needed, reducing resource consumption -- **Independent Scaling**: Each Gateway's NGINX Pod scales independently based on traffic requirements -- **Flexible Protection**: Default Gateway protection with route-specific overrides as needed +const ( + WafPolicyAffected gatewayv1alpha2.PolicyConditionType = "gateway.nginx.org/WafPolicyAffected" + PolicyAffectedReason gatewayv1alpha2.PolicyConditionReason = "PolicyAffected" +) -### Air-Gapped Environments - -- **In-cluster policy storage**: Deploy MinIO or HTTP server within cluster boundaries -- **Offline compilation**: Use NAP v5 tools in secure environments, upload bundles manually -- **No external dependencies**: Complete WAF functionality without internet access +``` -Example air-gapped configuration: +NGINX Gateway Fabric must set this Condition on all HTTPRoutes and Gateways affected by a `WafPolicy`. +Below is an example of what this Condition may look like: ```yaml -spec: - policySource: - fileLocation: "http://policy-server.nginx-system.svc.cluster.local/policies/prod-policy.tgz" +Conditions: + Type: gateway.nginx.org/WafPolicyAffected + Message: Object affected by a WafPolicy. + Observed Generation: 1 + Reason: PolicyAffected + Status: True ``` -### Regulatory Compliance +Some additional rules: -- **Audit trails**: Complete policy version history and deployment tracking -- **Change control**: Formal approval processes for policy compilation and deployment -- **Immutable policies**: Compiled policy bundles provide tamper-proof security configurations -- **Policy inheritance tracking**: Clear visibility into which policies apply to which routes +- This Condition should be added when the affected object starts being affected by a `WafPolicy`. +- If an object is affected by multiple `WafPolicy`, only one Condition should exist. +- When the last `WafPolicy` affecting that object is removed, the Condition should be removed. +- The Observed Generation is the generation of the affected object, not the generation of the `WafPolicy`. ## Testing @@ -756,7 +724,6 @@ spec: - **End-to-End Workflows**: Complete policy compilation, distribution, and enforcement across multiple Gateway scenarios - **NGF Control Plane**: Single NGF Pod managing multiple WAF-enabled and standard NGINX Pods - **Policy Distribution**: Centralized policy fetching with distribution to appropriate NGINX Pods via gRPC -- **Multi-Container Pod**: NAP v5 container interaction via shared volumes in Gateway-specific NGINX Pods - **Authentication**: Various credential types and failure handling for policy sources - **Network Scenarios**: Policy fetching from different source types (S3, HTTP, in-cluster) - **Selective Deployment**: Testing WAF enablement on subset of Gateways while others remain standard @@ -770,7 +737,7 @@ spec: - **Scale Testing**: Multiple WafPolicy resources and policy updates under load - **Ephemeral Volume Performance**: Volume I/O performance and sizing validation - **Policy Inheritance Performance**: Impact of policy resolution on request processing -- Note: current NFR testing likely covers all of these scenarios, but we may want to add a separate NGINX Plus WAF run +- Note: current NFR testing likely covers all of these scenarios, but we may want to add a separate NGINX Plus with WAF run ### Conformance Testing @@ -820,6 +787,13 @@ spec: - **Source Authorization**: Operators responsible for ensuring policy sources are legitimate and approved - **Access Logging**: Standard Kubernetes audit logging captures WafPolicy resource operations; policy fetch operations logged via NGF's existing logging mechanisms +### Regulatory Compliance + +- **Audit trails**: Complete policy version history and deployment tracking +- **Change control**: Formal approval processes for policy compilation and deployment +- **Immutable policies**: Compiled policy bundles provide tamper-proof security configurations +- **Policy inheritance tracking**: Clear visibility into which policies apply to which routes + ## Alternatives ### Alternative 1: Filter-Based Attachment @@ -890,8 +864,7 @@ metadata: name: waf-enabled-proxy namespace: nginx-gateway spec: - waf: - policy: "Enabled" + waf: "Enabled" --- # 3. Gateway using WAF-enabled proxy From eb8ac8fedc9195496b78e882734f9a10871ce381 Mon Sep 17 00:00:00 2001 From: Ciara Stacke Date: Wed, 28 May 2025 14:16:36 +0100 Subject: [PATCH 4/8] Remove redundant phrase --- docs/proposals/nap-waf.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/proposals/nap-waf.md b/docs/proposals/nap-waf.md index c469f532ea..efdf98a6c9 100644 --- a/docs/proposals/nap-waf.md +++ b/docs/proposals/nap-waf.md @@ -192,7 +192,7 @@ This architecture demonstrates the hierarchical policy attachment system where G **Data Plane (Green/Red):** When WAF is enabled through NginxProxy configuration, each Gateway deploys as a multi-container NGINX Pod containing the main NGINX container with NAP module, plus the required WAF Enforcer and WAF Config Manager containers. These containers communicate through shared ephemeral volumes rather than network calls, maintaining NAP v5's architectural requirements. -**Application Namespace Resources:** All user-facing resources (Gateway, HTTPRoute, GRPCRoute, WafPolicy, NginxProxy, and optional authentication Secret) reside in application namespaces for proper isolation and RBAC management. The Secret is only required when using fallback authentication methods for accessing external policy storage - native cloud authentication for accessing external policy storage (S3, Azure Blob, etc.) uses annotations on the NGF service account in the nginx-gateway namespace. +**Application Namespace Resources:** All user-facing resources (Gateway, HTTPRoute, GRPCRoute, WafPolicy, NginxProxy, and optional authentication Secret) reside in application namespaces for proper isolation and RBAC management. The Secret is only required when using fallback authentication methods for accessing external policy storage - native cloud authentication (where available) uses annotations on the NGF service account in the nginx-gateway namespace. **Policy Attachment Flow (Orange):** WafPolicy resources use targetRefs to attach to Gateways or Routes. Gateway-level policies provide inherited protection for all attached HTTPRoutes and GRPCRoutes. Route-level policies can override Gateway-level policies for specific routes requiring different protection levels. From 308d7a3be8bd5384f95a863dc047532ca03c22ca Mon Sep 17 00:00:00 2001 From: Ciara Stacke Date: Thu, 29 May 2025 13:28:50 +0100 Subject: [PATCH 5/8] Add polling mechanism to proposal --- docs/proposals/nap-waf.md | 102 +++++++++++++++++++++++++++++++------- 1 file changed, 85 insertions(+), 17 deletions(-) diff --git a/docs/proposals/nap-waf.md b/docs/proposals/nap-waf.md index efdf98a6c9..7b17585fb5 100644 --- a/docs/proposals/nap-waf.md +++ b/docs/proposals/nap-waf.md @@ -5,7 +5,7 @@ ## Summary -This proposal describes the integration of NGINX App Protect (NAP) WAF v5 into NGINX Gateway Fabric (NGF) to provide comprehensive WAF protection at Gateway and Route levels while working within NAP v5's architectural constraints of multi-container deployment and pre-compiled policy requirements. The design uses Gateway API inherited policy attachment to provide flexible, hierarchical WAF protection. +This proposal describes the integration of NGINX App Protect (NAP) WAF v5 into NGINX Gateway Fabric (NGF) to provide comprehensive WAF protection at Gateway and Route levels while working within NAP v5's architectural constraints of multi-container deployment and pre-compiled policy requirements. The design uses Gateway API inherited policy attachment to provide flexible, hierarchical WAF protection with GitOps-friendly static policy references through automatic polling and change detection. ## Goals @@ -13,6 +13,7 @@ This proposal describes the integration of NGINX App Protect (NAP) WAF v5 into N - Design WafPolicy custom resource using inherited policy attachment for hierarchical WAF configuration - Define deployment workflows that accommodate NAP v5's external policy compilation requirements - Provide secure and automated policy distribution mechanisms from external sources +- Support GitOps workflows with static policy file references and automatic change detection - Deliver enterprise-grade WAF capabilities through Kubernetes-native APIs with intuitive policy inheritance - Maintain alignment with NGF's existing security and operational patterns - Support configurable security logging for WAF events and policy violations @@ -41,6 +42,14 @@ NGINX App Protect WAF v5 imposes specific architectural requirements that fundam This proposal provides the best possible Kubernetes-native experience while respecting NAP v5 constraints, abstracting complexity from end users where possible while maintaining operational flexibility for enterprise environments. The design uses Gateway API's inherited policy attachment pattern to provide intuitive hierarchical security with the ability to override policies at more specific levels. +### GitOps Integration + +A key design principle is seamless GitOps workflow support through automatic change detection: + +- **Automatic Polling**: When polling is enabled, NGF periodically checks for policy changes using checksum validation +- **Efficient Updates**: Only downloads policy bundles when content actually changes +- **CI/CD Friendly**: Teams can update policies without modifying Kubernetes resources + ### Policy Attachment Strategy The design uses **inherited policy attachment** following Gateway API best practices: @@ -132,6 +141,7 @@ graph TB NGFPod -->|Watches Resources| NginxProxy NGFPod -->|Watches Resources| GatewayWafPolicy NGFPod -->|Watches Resources| RouteWafPolicy + NGFPod -->|Periodic Polling
Checksum Validation| Store NGFPod -->|Fetches Policy
Native Cloud Auth| Store NGFServiceAccount -.->|Cloud Provider
Authentication| Store NGFPod -.->|Fallback: Uses Credentials| Secret @@ -177,16 +187,11 @@ graph TB class PublicEndpoint endpoint class Secret optional - %% Notes about the architecture - classDef note fill:#fffacd,stroke:#daa520,stroke-width:1px,stroke-dasharray: 5 5 - Note1[📝 Note: Gateway-level WafPolicy provides inherited protection
Route-level WafPolicy can override for specific routes] - Note2[📝 Note: Secret only required for fallback authentication
Native cloud auth uses NGF Service Account annotations] - class Note1,Note2 note ``` This architecture demonstrates the hierarchical policy attachment system where Gateway-level WafPolicies provide default protection that can be overridden by Route-level policies for granular control: -**External Policy Management (Blue):** Security teams develop WAF policies using NAP v5 JSON schema, compile them using NAP v5 compiler tools, and publish the compiled policy bundles to accessible storage locations (S3, HTTP servers, or MinIO). +**External Policy Management (Blue):** Security teams develop WAF policies using NAP v5 JSON schema, compile them using NAP v5 compiler tools, and publish the compiled policy bundles to accessible storage locations (S3, HTTP servers, MinIO etc). **Control Plane (Purple):** The NGF Pod in the `nginx-gateway` namespace acts as the centralized control plane, watching for NginxProxy and WafPolicy resources across application namespaces, fetching compiled policies from external storage using appropriate authentication, and distributing policy configurations to NGINX Pods via secure gRPC connections. @@ -200,6 +205,8 @@ This architecture demonstrates the hierarchical policy attachment system where G **Policy Inheritance:** Gateway-level WafPolicies automatically protect all routes attached to the Gateway. Route-level WafPolicies can override Gateway policies with more specific protection. This design supports both broad default protection and granular security controls while maintaining operational simplicity. +- **GitOps Integration**: Optional automatic polling detects policy changes without requiring Kubernetes resource updates + The architecture demonstrates separation of concerns: external policy compilation and storage, centralized policy distribution with inheritance hierarchy, and distributed policy enforcement, while maintaining security through ephemeral storage and immutable infrastructure principles. ### Network Access Requirements @@ -232,6 +239,9 @@ Example air-gapped configuration: spec: policySource: fileLocation: "http://policy-server.nginx-system.svc.cluster.local/policies/prod-policy.tgz" + polling: + enabled: true + interval: "5m" ``` ### Policy Development Workflow @@ -243,7 +253,7 @@ Given NAP v5 constraints, users must follow this workflow: 3. **Compilation**: Use NAP v5 compiler tools to create policy and logging profile bundles 4. **Distribution**: Publish compiled policies and log profiles to accessible storage (S3, HTTP) 5. **Configuration**: Create WafPolicy CR with targetRefs referencing Gateway or Routes and configuring security logging -6. **Automatic Application**: NGF fetches and applies policies when WafPolicy is created or updated, with automatic inheritance +6. **Automatic Application**: NGF fetches and applies policies when WafPolicy is created or updated, with automatic inheritance. Policies can also be updated by publishing new content to the same configured file path; when polling is enabled, NGF automatically detects and applies changes. **Note**: Policy enforcement mode and behavior are defined within the compiled NAP policy itself. Security logging profiles can be either built-in names or custom compiled bundles. @@ -258,14 +268,24 @@ docker run --rm -v $(pwd):/policies nginx/nap-compiler:5.6.0 \ sha256sum compiled-policy.tgz > compiled-policy.tgz.sha256 # Publish to storage -aws s3 cp compiled-policy.tgz s3://company-policies/prod-policy-v$(date +%Y%m%d).tgz -aws s3 cp compiled-policy.tgz.sha256 s3://company-policies/prod-policy-v$(date +%Y%m%d).tgz.sha256 +aws s3 cp compiled-policy.tgz s3://company-policies/prod-policy.tgz +aws s3 cp compiled-policy.tgz.sha256 s3://company-policies/prod-policy.tgz.sha256 -# Manual update: Modify WafPolicy resource to reference new policy -kubectl patch wafpolicy gateway-protection \ - --patch '{"spec":{"policySource":{"fileLocation":"s3://company-policies/prod-policy-v'$(date +%Y%m%d)'.tgz"}}}' +# No Kubernetes resource changes needed - NGF automatically detects the update +echo "Policy updated. NGF will detect changes within polling interval." ``` +### Policy Polling and Change Detection + +NGF supports automatic policy change detection to support GitOps workflows: + +**Polling Mechanism:** + +- Configurable polling interval (default: 5 minutes) +- Checksum-based change detection for efficiency +- Only downloads policy bundles when content changes +- New policies applied immediately upon detection + ### Security Logging Configuration The securityLogs section supports multiple logging configurations, each generating an `app_protect_security_log` directive: @@ -284,6 +304,7 @@ The securityLogs section supports multiple logging configurations, each generati - Reference compiled logging profile bundles from remote sources - Same fetch and validation mechanisms as policy bundles - Support for checksums and retry policies +- Automatic polling for log profile updates **Destination Types:** @@ -347,10 +368,11 @@ The design supports hierarchical policy application with clear precedence rules: The integration leverages NGF's existing architecture: -- **Single NGF Pod**: Centralized control plane in `nginx-gateway` namespace manages all WAF operations +- **Single NGF Deployment**: Centralized control plane in `nginx-gateway` namespace manages all WAF operations and policy polling - **Per-Gateway Deployment**: Each Gateway with WAF enabled gets a dedicated multi-container NGINX Pod - **Selective WAF Enablement**: Only Gateways configured with WAF-enabled NginxProxy resources deploy NAP v5 containers - **Centralized Policy Management**: NGF controllers fetch policies and distribute them to appropriate NGINX Pods via the existing Agent gRPC connection +- **Automatic Change Detection**: NGF polling engine can detect policy changes and trigger updates across affected Gateways ## API, Customer Driven Interfaces, and User Experience @@ -414,6 +436,14 @@ spec: # Note: Policy content validation handled by NAP v5 components # We will support signature verification in the future + # Polling configuration for automatic change detection + polling: + enabled: true + interval: "5m" # Check every 5 minutes + # Optional: explicit checksum location + # If not specified, defaults to .sha256 + checksumLocation: "s3://ngf-waf-policies/production/gateway-policy-v1.2.3.tgz" + # Retry configuration for policy fetch failures retryPolicy: attempts: 3 @@ -441,6 +471,11 @@ spec: name: "policy-store-credentials" validation: methods: ["Checksum"] + # Log profiles also support polling for updates + polling: + enabled: true + interval: "10m" + # ChecksumLocation defaults to .sha256 retryPolicy: attempts: 3 backoff: "exponential" @@ -481,6 +516,9 @@ spec: fileLocation: "s3://ngf-waf-policies/production/admin-strict-policy-v1.0.0.tgz" authSecret: name: "policy-store-credentials" + polling: + enabled: true + interval: "2m" securityLogs: - name: "admin-logging" logProfile: "log_all" # Log everything for admin routes @@ -716,6 +754,7 @@ Some additional rules: - **Policy Attachment Logic**: targetRefs validation and inheritance resolution - **Multi-container Orchestration**: Container startup sequences and ephemeral volume management - **Policy Validation**: Compiled policy bundle checksum integrity checking +- **Polling Engine**: Change detection logic and retry mechanisms ### Integration Testing @@ -727,6 +766,7 @@ Some additional rules: - **Authentication**: Various credential types and failure handling for policy sources - **Network Scenarios**: Policy fetching from different source types (S3, HTTP, in-cluster) - **Selective Deployment**: Testing WAF enablement on subset of Gateways while others remain standard +- **Polling and Updates**: Automatic change detection and policy application without resource modifications ### Performance Testing @@ -737,6 +777,7 @@ Some additional rules: - **Scale Testing**: Multiple WafPolicy resources and policy updates under load - **Ephemeral Volume Performance**: Volume I/O performance and sizing validation - **Policy Inheritance Performance**: Impact of policy resolution on request processing +- **Polling Performance**: Resource impact of periodic policy checks and change detection - Note: current NFR testing likely covers all of these scenarios, but we may want to add a separate NGINX Plus with WAF run ### Conformance Testing @@ -753,6 +794,7 @@ Some additional rules: - **Integrity Verification**: Checksum validation of compiled policy bundles prevents tampering - **Secure Transport**: TLS encryption for all policy downloads from external sources - **Access Control**: RBAC restrictions on WafPolicy resource creation and modification +- **Polling Security**: Secure change detection mechanisms prevent unauthorized policy modifications ### Credential Management @@ -826,6 +868,16 @@ Some additional rules: **Approach**: Have NGINX containers fetch policies directly using njs **Rejected Reason**: Creates distributed system complexity, inconsistent state issues, and violates NGF's centralized control plane pattern +### Alternative 7: Manual Policy Updates Only + +**Approach**: Require users to manually update WafPolicy resources for each policy change +**Rejected Reason**: Breaks GitOps workflows and creates operational overhead; teams want to update policies without modifying Kubernetes resources + +### Alternative 8: Webhook-Only Updates + +**Approach**: Use only webhook notifications for policy updates, no polling +**Rejected Reason**: Creates dependency on reliable webhook delivery; polling provides fallback mechanism and works in environments where webhooks are not feasible + ## Future Enhancements - **Policy signature verification**: Cryptographic validation of policy bundle authenticity using public key infrastructure @@ -905,10 +957,19 @@ spec: namespace: applications policySource: - fileLocation: "s3://company-waf-policies/production/base-policy-v2.1.0.tgz" + fileLocation: "s3://company-waf-policies/production/base-policy.tgz" # Secret referenced for fallback - NGF will use IRSA if available, secret if not authSecret: name: "policy-store-credentials" + + # Automatic change detection for GitOps workflows + polling: + enabled: true + interval: "5m" + # Optional explicit checksum location + # If not specified, defaults to base-policy.tgz.sha256 + checksumLocation: "s3://company-waf-policies/production/base-policy.tgz.sha256" + securityLogs: - name: "gateway-logging" logProfile: "log_blocked" @@ -931,7 +992,10 @@ spec: namespace: applications policySource: - fileLocation: "s3://company-waf-policies/production/admin-strict-policy-v1.0.0.tgz" + fileLocation: "s3://company-waf-policies/production/admin-strict-policy.tgz" + polling: + enabled: true + securityLogs: - name: "admin-logging" logProfile: "log_all" # More verbose logging for admin routes @@ -1025,7 +1089,10 @@ spec: namespace: applications policySource: - fileLocation: "s3://company-waf-policies/production/api-specific-policy-v1.5.0.tgz" + fileLocation: "s3://company-waf-policies/production/api-specific-policy.tgz" + polling: + enabled: true + securityLogs: - name: "api-logging" logProfile: "log_blocked" @@ -1043,3 +1110,4 @@ This complete example demonstrates: - **HTTP and gRPC route support** with seamless policy inheritance - **Native cloud authentication** with fallback secret support - **Flexible logging configuration** per policy level +- **Automatic change detection** through configurable polling intervals From 02d0a8606de7e31a4bdeabde1d3da7a43d3c861e Mon Sep 17 00:00:00 2001 From: Ciara Stacke Date: Thu, 5 Jun 2025 11:57:26 +0100 Subject: [PATCH 6/8] Add sequence diagram and more detail on status conditions --- docs/proposals/nap-waf.md | 83 ++++++++++++++++++++++++++++++++------- 1 file changed, 69 insertions(+), 14 deletions(-) diff --git a/docs/proposals/nap-waf.md b/docs/proposals/nap-waf.md index 7b17585fb5..f832c436d8 100644 --- a/docs/proposals/nap-waf.md +++ b/docs/proposals/nap-waf.md @@ -50,12 +50,20 @@ A key design principle is seamless GitOps workflow support through automatic cha - **Efficient Updates**: Only downloads policy bundles when content actually changes - **CI/CD Friendly**: Teams can update policies without modifying Kubernetes resources +**Polling Mechanism:** + +- Configurable polling interval (default: 5 minutes) +- Checksum-based change detection for efficiency +- Only downloads policy bundles when content changes +- New policies applied immediately upon detection + ### Policy Attachment Strategy The design uses **inherited policy attachment** following Gateway API best practices: - **Gateway-level policies** provide default protection for all routes attached to the Gateway - **Route-level policies** can override Gateway-level policies for specific routes requiring different protection + - NB: cannot _disable_ WAF protection on a per route level, but the Route level WAFPolicy configuration will completely override the Gateway level WAFPolicy configuration - **Policy precedence**: More specific policies (Route-level) override less specific policies (Gateway-level) - **Automatic inheritance**: New routes automatically receive Gateway-level protection without explicit configuration @@ -246,8 +254,6 @@ spec: ### Policy Development Workflow -Given NAP v5 constraints, users must follow this workflow: - 1. **Policy Development**: Write WAF policies using NAP v5 JSON schema 2. **Log Profile Development**: Create custom logging profiles or use built-in profiles (log_all, log_blocked, etc.) 3. **Compilation**: Use NAP v5 compiler tools to create policy and logging profile bundles @@ -257,6 +263,24 @@ Given NAP v5 constraints, users must follow this workflow: **Note**: Policy enforcement mode and behavior are defined within the compiled NAP policy itself. Security logging profiles can be either built-in names or custom compiled bundles. +```mermaid +sequenceDiagram + participant SecTeam as Security Team + participant Compiler as Policy Compiler + participant Store as Policy Store + participant NGF as NGF Control Plane + participant NGINX as NGINX Data Plane + + SecTeam->>Compiler: Develop WAF Policies + Compiler->>Store: Publish Compiled Policies + NGF->>Store: Fetch Policies (Periodic Polling) + NGF->>NGF: Validate Policies (Checksum Verification) + NGF->>NGINX: Push Policies to Shared Volume + NGINX->>NGINX: Apply Policies + Client->>NGINX: Send HTTP/gRPC Requests + NGINX->>Client: Respond with Filtered Traffic +``` + Example CI/CD integration for manual updates: ```bash @@ -275,17 +299,6 @@ aws s3 cp compiled-policy.tgz.sha256 s3://company-policies/prod-policy.tgz.sha25 echo "Policy updated. NGF will detect changes within polling interval." ``` -### Policy Polling and Change Detection - -NGF supports automatic policy change detection to support GitOps workflows: - -**Polling Mechanism:** - -- Configurable polling interval (default: 5 minutes) -- Checksum-based change detection for efficiency -- Only downloads policy bundles when content changes -- New policies applied immediately upon detection - ### Security Logging Configuration The securityLogs section supports multiple logging configurations, each generating an `app_protect_security_log` directive: @@ -700,7 +713,45 @@ This label will help with discoverability and will be used by the planned Gatewa According to the [Policy and Metaresources GEP](https://gateway-api.sigs.k8s.io/geps/gep-713/), the `WafPolicy` CRD must include a `status` stanza with a slice of Conditions. -The `Accepted` Condition must be populated on the `WafPolicy` CRD using the reasons defined in the [PolicyCondition API](https://github.com/kubernetes-sigs/gateway-api/blob/main/apis/v1alpha2/policy_types.go). If these reasons are not sufficient, we can add implementation-specific reasons. +The `Accepted` Condition must be populated on the `WafPolicy` CRD using the reasons defined in the [PolicyCondition API](https://github.com/kubernetes-sigs/gateway-api/blob/main/apis/v1alpha2/policy_types.go). Below are example implementation-specific reasons that describe the lifecycle phases and potential issues encountered while processing the policy: + +| **Reason** | **Description** | **Example Message** | +|---------------------------|---------------------------------------------------------------------------------------------------|-------------------------------------------------------------------| +| **PolicySourceInvalid** | The `policySource` contains invalid or incomplete information. | "The policy source is invalid. Ensure fileLocation is correct." | +| **PolicyFetchError** | Failed to fetch the policy due to network issues, authentication problems, or source misconfiguration. | "Failed to fetch policy bundle due to a network issue or invalid credentials." | +| **PolicyIntegrityInvalid**| Checksum verification failed for the fetched policy bundle. | "Policy integrity check failed because of a checksum mismatch." | +| **PolicyValidationError** | The WAF policy bundle failed schema or format validation for NGINX App Protect WAF. | "The policy bundle did not pass schema validation. Update the policy and retry compilation." | +| **PolicyDeployed** | The policy was successfully deployed to the NGINX Data Plane (Pods). | "The policy has been successfully deployed and is now protecting the targeted resources." | +| **PolicyDeployedUpdate** | An updated version of the policy was successfully deployed to the NGINX Data Plane (Pods) after polling or change detection. | "The policy has been updated and successfully redeployed to the targeted resources." | +| **PolicyDeploymentError** | The data plane (NGINX Pods) failed to apply the policy. | "Failed to deploy the WAF policy to the NGINX Pods." | +| **AuthenticationError** | Authentication to the external store (e.g., S3, HTTP) failed. | "Authentication error while trying to fetch the policy bundle." | +| **PolicyConfigError** | The policy configuration prevents proper processing. | "The policy configuration is incomplete or incorrectly formatted. Correct the configuration and retry." | + +### Example Status Conditions in `WafPolicy` + +```yaml +status: + conditions: + - type: Accepted + status: "True" + reason: PolicyDeployedUpdate + message: "The policy has been updated and successfully redeployed to the Gateway." + + - type: Accepted + status: "False" + reason: PolicyFetchError + message: "Failed to fetch policy bundle due to a network issue or invalid credentials." + + - type: Accepted + status: "True" + reason: PolicyDeployed + message: "The policy has been successfully deployed and is now protecting the targeted resources." + + - type: Accepted + status: "False" + reason: PolicyIntegrityInvalid + message: "Policy integrity check failed because of a checksum mismatch." +``` #### Setting Status on Objects Affected by a Policy @@ -1111,3 +1162,7 @@ This complete example demonstrates: - **Native cloud authentication** with fallback secret support - **Flexible logging configuration** per policy level - **Automatic change detection** through configurable polling intervals + +## Open questions + +- Will NAP automatically pick up policy changes when the bundle is changed on disk? Do we need to reload NGINX? From 63110603ad9816b562995b280f76f1d8e70efce5 Mon Sep 17 00:00:00 2001 From: Ciara Stacke Date: Thu, 5 Jun 2025 13:56:04 +0100 Subject: [PATCH 7/8] Single targetRef and other clarifications --- docs/proposals/nap-waf.md | 67 +++++++++------------------------------ 1 file changed, 15 insertions(+), 52 deletions(-) diff --git a/docs/proposals/nap-waf.md b/docs/proposals/nap-waf.md index f832c436d8..42ccc26ddc 100644 --- a/docs/proposals/nap-waf.md +++ b/docs/proposals/nap-waf.md @@ -61,9 +61,10 @@ A key design principle is seamless GitOps workflow support through automatic cha The design uses **inherited policy attachment** following Gateway API best practices: +- **Single target per policy**: A WafPolicy targets a single resource (either a Gateway or a Route) following [gep-2649 guidelines](https://gateway-api.sigs.k8s.io/geps/gep-2649/#policy-targetref-api). - **Gateway-level policies** provide default protection for all routes attached to the Gateway - **Route-level policies** can override Gateway-level policies for specific routes requiring different protection - - NB: cannot _disable_ WAF protection on a per route level, but the Route level WAFPolicy configuration will completely override the Gateway level WAFPolicy configuration + - NB: Route-level WafPolicies always override Gateway-level WafPolicies for routes they explicitly target. However, it is not possible to completely disable WAF protection for a specific Route when a Gateway-level WafPolicy is active. Instead, the Route-level policy configuration entirely replaces the Gateway-level policy for that route. - **Policy precedence**: More specific policies (Route-level) override less specific policies (Gateway-level) - **Automatic inheritance**: New routes automatically receive Gateway-level protection without explicit configuration @@ -207,7 +208,7 @@ This architecture demonstrates the hierarchical policy attachment system where G **Application Namespace Resources:** All user-facing resources (Gateway, HTTPRoute, GRPCRoute, WafPolicy, NginxProxy, and optional authentication Secret) reside in application namespaces for proper isolation and RBAC management. The Secret is only required when using fallback authentication methods for accessing external policy storage - native cloud authentication (where available) uses annotations on the NGF service account in the nginx-gateway namespace. -**Policy Attachment Flow (Orange):** WafPolicy resources use targetRefs to attach to Gateways or Routes. Gateway-level policies provide inherited protection for all attached HTTPRoutes and GRPCRoutes. Route-level policies can override Gateway-level policies for specific routes requiring different protection levels. +**Policy Attachment Flow (Orange):** WafPolicy resources use targetRef to attach to Gateways or Routes. Only one resource can be targeted at a time. Gateway-level policies provide inherited protection for all attached HTTPRoutes and GRPCRoutes. Route-level policies can override Gateway-level policies for specific routes requiring different protection levels. **Traffic Flow (Yellow/Gold):** Client traffic (HTTP, HTTPS, and gRPC) flows through the public load balancer endpoint to the WAF-protected NGINX container, where NAP v5 applies security policies before forwarding filtered traffic to backend applications. @@ -258,7 +259,7 @@ spec: 2. **Log Profile Development**: Create custom logging profiles or use built-in profiles (log_all, log_blocked, etc.) 3. **Compilation**: Use NAP v5 compiler tools to create policy and logging profile bundles 4. **Distribution**: Publish compiled policies and log profiles to accessible storage (S3, HTTP) -5. **Configuration**: Create WafPolicy CR with targetRefs referencing Gateway or Routes and configuring security logging +5. **Configuration**: Create WafPolicy CR with targetRef referencing a Gateway or a Route and configuring security logging 6. **Automatic Application**: NGF fetches and applies policies when WafPolicy is created or updated, with automatic inheritance. Policies can also be updated by publishing new content to the same configured file path; when polling is enabled, NGF automatically detects and applies changes. **Note**: Policy enforcement mode and behavior are defined within the compiled NAP policy itself. Security logging profiles can be either built-in names or custom compiled bundles. @@ -434,8 +435,8 @@ metadata: namespace: applications spec: # Policy attachment - targets Gateway for inherited protection - targetRefs: - - group: gateway.networking.k8s.io + targetRef: + group: gateway.networking.k8s.io kind: Gateway name: secure-gateway namespace: applications @@ -518,8 +519,8 @@ metadata: namespace: applications spec: # Policy attachment - targets specific HTTPRoute to override Gateway policy - targetRefs: - - group: gateway.networking.k8s.io + targetRef: + group: gateway.networking.k8s.io kind: HTTPRoute name: admin-route namespace: applications @@ -603,7 +604,7 @@ spec: backendRefs: - name: admin-service port: 8080 - # Uses admin-strict-policy WafPolicy override via targetRefs + # Uses admin-strict-policy WafPolicy override via targetRef ``` #### GRPCRoute Integration @@ -802,7 +803,7 @@ Some additional rules: - **NginxProxy Extensions**: WAF enablement configuration parsing and validation - **WafPolicy Controller**: CRUD operations, status management, and policy fetching logic -- **Policy Attachment Logic**: targetRefs validation and inheritance resolution +- **Policy Attachment Logic**: targetRef validation and inheritance resolution - **Multi-container Orchestration**: Container startup sequences and ephemeral volume management - **Policy Validation**: Compiled policy bundle checksum integrity checking - **Polling Engine**: Change detection logic and retry mechanisms @@ -1001,8 +1002,8 @@ metadata: namespace: applications spec: # Policy attachment - protects entire Gateway and inherits to all routes - targetRefs: - - group: gateway.networking.k8s.io + targetRef: + group: gateway.networking.k8s.io kind: Gateway name: secure-gateway namespace: applications @@ -1036,8 +1037,8 @@ metadata: namespace: applications spec: # Policy attachment - overrides Gateway policy for specific route - targetRefs: - - group: gateway.networking.k8s.io + targetRef: + group: gateway.networking.k8s.io kind: HTTPRoute name: admin-route namespace: applications @@ -1093,7 +1094,7 @@ spec: backendRefs: - name: admin-service port: 8080 - # Uses admin-strict-protection WafPolicy override via targetRefs + # Uses admin-strict-protection WafPolicy override via targetRef --- # 8. GRPCRoute inheriting Gateway protection @@ -1116,48 +1117,10 @@ spec: port: 9000 # Inherits gateway-base-protection WafPolicy automatically ---- -# 9. Example showing multiple route targeting -apiVersion: gateway.nginx.org/v1alpha1 -kind: WafPolicy -metadata: - name: api-routes-protection - namespace: applications -spec: - # Policy attachment - targets multiple routes with same policy - targetRefs: - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: public-api-route - namespace: applications - - group: gateway.networking.k8s.io - kind: HTTPRoute - name: partner-api-route - namespace: applications - - group: gateway.networking.k8s.io - kind: GRPCRoute - name: api-grpc-service - namespace: applications - - policySource: - fileLocation: "s3://company-waf-policies/production/api-specific-policy.tgz" - polling: - enabled: true - - securityLogs: - - name: "api-logging" - logProfile: "log_blocked" - destination: - type: "Syslog" - syslog: - server: "syslog-svc.default:514" -``` - This complete example demonstrates: - **Gateway-level inherited protection** for all routes by default - **Route-level policy overrides** for specific security requirements -- **Multi-route targeting** for applying the same policy to multiple routes - **HTTP and gRPC route support** with seamless policy inheritance - **Native cloud authentication** with fallback secret support - **Flexible logging configuration** per policy level From 1ec987e27fc4420e0a92eb0478769ae04eadaaa1 Mon Sep 17 00:00:00 2001 From: Ciara Stacke Date: Wed, 11 Jun 2025 11:05:31 +0100 Subject: [PATCH 8/8] Change WafPolicy to WAFPolicy --- docs/proposals/nap-waf.md | 106 +++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/docs/proposals/nap-waf.md b/docs/proposals/nap-waf.md index 42ccc26ddc..c0fd553b0a 100644 --- a/docs/proposals/nap-waf.md +++ b/docs/proposals/nap-waf.md @@ -10,7 +10,7 @@ This proposal describes the integration of NGINX App Protect (NAP) WAF v5 into N ## Goals - Extend NginxProxy resource to enable NAP WAF for GatewayClass/Gateway with multi-container orchestration -- Design WafPolicy custom resource using inherited policy attachment for hierarchical WAF configuration +- Design WAFPolicy custom resource using inherited policy attachment for hierarchical WAF configuration - Define deployment workflows that accommodate NAP v5's external policy compilation requirements - Provide secure and automated policy distribution mechanisms from external sources - Support GitOps workflows with static policy file references and automatic change detection @@ -61,10 +61,10 @@ A key design principle is seamless GitOps workflow support through automatic cha The design uses **inherited policy attachment** following Gateway API best practices: -- **Single target per policy**: A WafPolicy targets a single resource (either a Gateway or a Route) following [gep-2649 guidelines](https://gateway-api.sigs.k8s.io/geps/gep-2649/#policy-targetref-api). +- **Single target per policy**: A WAFPolicy targets a single resource (either a Gateway or a Route) following [gep-2649 guidelines](https://gateway-api.sigs.k8s.io/geps/gep-2649/#policy-targetref-api). - **Gateway-level policies** provide default protection for all routes attached to the Gateway - **Route-level policies** can override Gateway-level policies for specific routes requiring different protection - - NB: Route-level WafPolicies always override Gateway-level WafPolicies for routes they explicitly target. However, it is not possible to completely disable WAF protection for a specific Route when a Gateway-level WafPolicy is active. Instead, the Route-level policy configuration entirely replaces the Gateway-level policy for that route. + - NB: Route-level WafPolicies always override Gateway-level WafPolicies for routes they explicitly target. However, it is not possible to completely disable WAF protection for a specific Route when a Gateway-level WAFPolicy is active. Instead, the Route-level policy configuration entirely replaces the Gateway-level policy for that route. - **Policy precedence**: More specific policies (Route-level) override less specific policies (Gateway-level) - **Automatic inheritance**: New routes automatically receive Gateway-level protection without explicit configuration @@ -108,8 +108,8 @@ graph TB %% Custom Resources (all in app namespace) NginxProxy[NginxProxy
waf.enabled=true] - GatewayWafPolicy[WafPolicy
Gateway-level Protection] - RouteWafPolicy[WafPolicy
Route-level Override] + GatewayWAFPolicy[WAFPolicy
Gateway-level Protection] + RouteWAFPolicy[WAFPolicy
Route-level Override] Secret[Secret
Store Credentials
Optional - Fallback Auth Only] %% NGINX Data Plane (WAF Enabled) @@ -136,20 +136,20 @@ graph TB Compiler -->|Publish Bundle| Store %% Policy Attachment Flow - GatewayWafPolicy -.->|Targets & Protects| Gateway - RouteWafPolicy -.->|Targets & Overrides| HTTPRoute + GatewayWAFPolicy -.->|Targets & Protects| Gateway + RouteWAFPolicy -.->|Targets & Overrides| HTTPRoute Gateway -->|Inherits Protection| HTTPRoute Gateway -->|Inherits Protection| GRPCRoute %% Configuration Flow - Store -.->|Policy Location| GatewayWafPolicy - Store -.->|Policy Location| RouteWafPolicy + Store -.->|Policy Location| GatewayWAFPolicy + Store -.->|Policy Location| RouteWAFPolicy NginxProxy -.->|Enables WAF| Gateway %% Control Plane Operations NGFPod -->|Watches Resources| NginxProxy - NGFPod -->|Watches Resources| GatewayWafPolicy - NGFPod -->|Watches Resources| RouteWafPolicy + NGFPod -->|Watches Resources| GatewayWAFPolicy + NGFPod -->|Watches Resources| RouteWAFPolicy NGFPod -->|Periodic Polling
Checksum Validation| Store NGFPod -->|Fetches Policy
Native Cloud Auth| Store NGFServiceAccount -.->|Cloud Provider
Authentication| Store @@ -190,7 +190,7 @@ graph TB class NGFServiceAccount cloudAuth class Gateway,HTTPRoute,GRPCRoute gateway class WafEnforcer,WafConfigMgr,PolicyVol,NginxProxy wafRequired - class GatewayWafPolicy,RouteWafPolicy policy + class GatewayWAFPolicy,RouteWAFPolicy policy class Application app class PolicyVol,ConfigVol volume class PublicEndpoint endpoint @@ -202,13 +202,13 @@ This architecture demonstrates the hierarchical policy attachment system where G **External Policy Management (Blue):** Security teams develop WAF policies using NAP v5 JSON schema, compile them using NAP v5 compiler tools, and publish the compiled policy bundles to accessible storage locations (S3, HTTP servers, MinIO etc). -**Control Plane (Purple):** The NGF Pod in the `nginx-gateway` namespace acts as the centralized control plane, watching for NginxProxy and WafPolicy resources across application namespaces, fetching compiled policies from external storage using appropriate authentication, and distributing policy configurations to NGINX Pods via secure gRPC connections. +**Control Plane (Purple):** The NGF Pod in the `nginx-gateway` namespace acts as the centralized control plane, watching for NginxProxy and WAFPolicy resources across application namespaces, fetching compiled policies from external storage using appropriate authentication, and distributing policy configurations to NGINX Pods via secure gRPC connections. **Data Plane (Green/Red):** When WAF is enabled through NginxProxy configuration, each Gateway deploys as a multi-container NGINX Pod containing the main NGINX container with NAP module, plus the required WAF Enforcer and WAF Config Manager containers. These containers communicate through shared ephemeral volumes rather than network calls, maintaining NAP v5's architectural requirements. -**Application Namespace Resources:** All user-facing resources (Gateway, HTTPRoute, GRPCRoute, WafPolicy, NginxProxy, and optional authentication Secret) reside in application namespaces for proper isolation and RBAC management. The Secret is only required when using fallback authentication methods for accessing external policy storage - native cloud authentication (where available) uses annotations on the NGF service account in the nginx-gateway namespace. +**Application Namespace Resources:** All user-facing resources (Gateway, HTTPRoute, GRPCRoute, WAFPolicy, NginxProxy, and optional authentication Secret) reside in application namespaces for proper isolation and RBAC management. The Secret is only required when using fallback authentication methods for accessing external policy storage - native cloud authentication (where available) uses annotations on the NGF service account in the nginx-gateway namespace. -**Policy Attachment Flow (Orange):** WafPolicy resources use targetRef to attach to Gateways or Routes. Only one resource can be targeted at a time. Gateway-level policies provide inherited protection for all attached HTTPRoutes and GRPCRoutes. Route-level policies can override Gateway-level policies for specific routes requiring different protection levels. +**Policy Attachment Flow (Orange):** WAFPolicy resources use targetRef to attach to Gateways or Routes. Only one resource can be targeted at a time. Gateway-level policies provide inherited protection for all attached HTTPRoutes and GRPCRoutes. Route-level policies can override Gateway-level policies for specific routes requiring different protection levels. **Traffic Flow (Yellow/Gold):** Client traffic (HTTP, HTTPS, and gRPC) flows through the public load balancer endpoint to the WAF-protected NGINX container, where NAP v5 applies security policies before forwarding filtered traffic to backend applications. @@ -259,8 +259,8 @@ spec: 2. **Log Profile Development**: Create custom logging profiles or use built-in profiles (log_all, log_blocked, etc.) 3. **Compilation**: Use NAP v5 compiler tools to create policy and logging profile bundles 4. **Distribution**: Publish compiled policies and log profiles to accessible storage (S3, HTTP) -5. **Configuration**: Create WafPolicy CR with targetRef referencing a Gateway or a Route and configuring security logging -6. **Automatic Application**: NGF fetches and applies policies when WafPolicy is created or updated, with automatic inheritance. Policies can also be updated by publishing new content to the same configured file path; when polling is enabled, NGF automatically detects and applies changes. +5. **Configuration**: Create WAFPolicy CR with targetRef referencing a Gateway or a Route and configuring security logging +6. **Automatic Application**: NGF fetches and applies policies when WAFPolicy is created or updated, with automatic inheritance. Policies can also be updated by publishing new content to the same configured file path; when polling is enabled, NGF automatically detects and applies changes. **Note**: Policy enforcement mode and behavior are defined within the compiled NAP policy itself. Security logging profiles can be either built-in names or custom compiled bundles. @@ -365,12 +365,12 @@ The design supports hierarchical policy application with clear precedence rules: **Inheritance Hierarchy:** -- Gateway-level WafPolicy → HTTPRoute (inherited) -- Gateway-level WafPolicy → GRPCRoute (inherited) +- Gateway-level WAFPolicy → HTTPRoute (inherited) +- Gateway-level WAFPolicy → GRPCRoute (inherited) **Override Precedence (most specific wins):** -- Route-level WafPolicy > Gateway-level WafPolicy +- Route-level WAFPolicy > Gateway-level WAFPolicy **Conflict Resolution:** @@ -401,8 +401,8 @@ metadata: name: nginx-proxy-waf namespace: nginx-gateway spec: - # WAF policy configuration (extensible design) - waf: "Enabled" # "Enabled" | "Disabled" + # WAF deployment configuration + waf: "enabled" # "enabled" | "disabled" # configuration tweaks optional, e.g.: # kubernetes: # deployment: @@ -425,11 +425,11 @@ spec: # tag: "5.6.0" ``` -### WafPolicy Custom Resource with Policy Attachment +### WAFPolicy Custom Resource with Policy Attachment ```yaml apiVersion: gateway.nginx.org/v1alpha1 -kind: WafPolicy +kind: WAFPolicy metadata: name: gateway-protection-policy namespace: applications @@ -513,7 +513,7 @@ spec: --- # Route-level override example apiVersion: gateway.nginx.org/v1alpha1 -kind: WafPolicy +kind: WAFPolicy metadata: name: admin-strict-policy namespace: applications @@ -604,7 +604,7 @@ spec: backendRefs: - name: admin-service port: 8080 - # Uses admin-strict-policy WafPolicy override via targetRef + # Uses admin-strict-policy WAFPolicy override via targetRef ``` #### GRPCRoute Integration @@ -627,7 +627,7 @@ spec: backendRefs: - name: grpc-service port: 9000 - # WAF protection inherited from Gateway-level WafPolicy + # WAF protection inherited from Gateway-level WAFPolicy ``` ### Authentication Methods @@ -651,7 +651,7 @@ For cloud-hosted policy storage, NGF automatically detects and uses native cloud **AWS S3 with IAM Roles for Service Accounts (IRSA):** ```yaml -# Cluster operator configures service account (no WafPolicy changes needed) +# Cluster operator configures service account (no WAFPolicy changes needed) apiVersion: v1 kind: ServiceAccount metadata: @@ -660,7 +660,7 @@ metadata: annotations: eks.amazonaws.com/role-arn: "arn:aws:iam::123456789012:role/NGFPolicyAccessRole" -# WafPolicy uses S3 without explicit credentials +# WAFPolicy uses S3 without explicit credentials # NGF service account in nginx-gateway namespace provides IRSA authentication spec: policySource: @@ -707,14 +707,14 @@ data: #### CRD Label -According to the [Policy and Metaresources GEP](https://gateway-api.sigs.k8s.io/geps/gep-713/), the `WafPolicy` CRD must have the `gateway.networking.k8s.io/policy: inherited` label to specify that it is an inherited policy. +According to the [Policy and Metaresources GEP](https://gateway-api.sigs.k8s.io/geps/gep-713/), the `WAFPolicy` CRD must have the `gateway.networking.k8s.io/policy: inherited` label to specify that it is an inherited policy. This label will help with discoverability and will be used by the planned Gateway API Policy [kubectl plugin](https://gateway-api.sigs.k8s.io/geps/gep-713/#kubectl-plugin-or-command-line-tool). #### Conditions -According to the [Policy and Metaresources GEP](https://gateway-api.sigs.k8s.io/geps/gep-713/), the `WafPolicy` CRD must include a `status` stanza with a slice of Conditions. +According to the [Policy and Metaresources GEP](https://gateway-api.sigs.k8s.io/geps/gep-713/), the `WAFPolicy` CRD must include a `status` stanza with a slice of Conditions. -The `Accepted` Condition must be populated on the `WafPolicy` CRD using the reasons defined in the [PolicyCondition API](https://github.com/kubernetes-sigs/gateway-api/blob/main/apis/v1alpha2/policy_types.go). Below are example implementation-specific reasons that describe the lifecycle phases and potential issues encountered while processing the policy: +The `Accepted` Condition must be populated on the `WAFPolicy` CRD using the reasons defined in the [PolicyCondition API](https://github.com/kubernetes-sigs/gateway-api/blob/main/apis/v1alpha2/policy_types.go). Below are example implementation-specific reasons that describe the lifecycle phases and potential issues encountered while processing the policy: | **Reason** | **Description** | **Example Message** | |---------------------------|---------------------------------------------------------------------------------------------------|-------------------------------------------------------------------| @@ -728,7 +728,7 @@ The `Accepted` Condition must be populated on the `WafPolicy` CRD using the reas | **AuthenticationError** | Authentication to the external store (e.g., S3, HTTP) failed. | "Authentication error while trying to fetch the policy bundle." | | **PolicyConfigError** | The policy configuration prevents proper processing. | "The policy configuration is incomplete or incorrectly formatted. Correct the configuration and retry." | -### Example Status Conditions in `WafPolicy` +### Example Status Conditions in `WAFPolicy` ```yaml status: @@ -772,19 +772,19 @@ import ( const ( - WafPolicyAffected gatewayv1alpha2.PolicyConditionType = "gateway.nginx.org/WafPolicyAffected" + WAFPolicyAffected gatewayv1alpha2.PolicyConditionType = "gateway.nginx.org/WAFPolicyAffected" PolicyAffectedReason gatewayv1alpha2.PolicyConditionReason = "PolicyAffected" ) ``` -NGINX Gateway Fabric must set this Condition on all HTTPRoutes and Gateways affected by a `WafPolicy`. +NGINX Gateway Fabric must set this Condition on all HTTPRoutes and Gateways affected by a `WAFPolicy`. Below is an example of what this Condition may look like: ```yaml Conditions: - Type: gateway.nginx.org/WafPolicyAffected - Message: Object affected by a WafPolicy. + Type: gateway.nginx.org/WAFPolicyAffected + Message: Object affected by a WAFPolicy. Observed Generation: 1 Reason: PolicyAffected Status: True @@ -792,17 +792,17 @@ Conditions: Some additional rules: -- This Condition should be added when the affected object starts being affected by a `WafPolicy`. -- If an object is affected by multiple `WafPolicy`, only one Condition should exist. -- When the last `WafPolicy` affecting that object is removed, the Condition should be removed. -- The Observed Generation is the generation of the affected object, not the generation of the `WafPolicy`. +- This Condition should be added when the affected object starts being affected by a `WAFPolicy`. +- If an object is affected by multiple `WAFPolicy`, only one Condition should exist. +- When the last `WAFPolicy` affecting that object is removed, the Condition should be removed. +- The Observed Generation is the generation of the affected object, not the generation of the `WAFPolicy`. ## Testing ### Unit Testing - **NginxProxy Extensions**: WAF enablement configuration parsing and validation -- **WafPolicy Controller**: CRUD operations, status management, and policy fetching logic +- **WAFPolicy Controller**: CRUD operations, status management, and policy fetching logic - **Policy Attachment Logic**: targetRef validation and inheritance resolution - **Multi-container Orchestration**: Container startup sequences and ephemeral volume management - **Policy Validation**: Compiled policy bundle checksum integrity checking @@ -826,7 +826,7 @@ Some additional rules: - **Throughput Analysis**: Concurrent request handling capacity with WAF protection - **Resource Utilization**: Memory and CPU consumption of multi-container pods - **Policy Size Impact**: Large compiled policy bundle handling and distribution timing -- **Scale Testing**: Multiple WafPolicy resources and policy updates under load +- **Scale Testing**: Multiple WAFPolicy resources and policy updates under load - **Ephemeral Volume Performance**: Volume I/O performance and sizing validation - **Policy Inheritance Performance**: Impact of policy resolution on request processing - **Polling Performance**: Resource impact of periodic policy checks and change detection @@ -845,7 +845,7 @@ Some additional rules: - **Integrity Verification**: Checksum validation of compiled policy bundles prevents tampering - **Secure Transport**: TLS encryption for all policy downloads from external sources -- **Access Control**: RBAC restrictions on WafPolicy resource creation and modification +- **Access Control**: RBAC restrictions on WAFPolicy resource creation and modification - **Polling Security**: Secure change detection mechanisms prevent unauthorized policy modifications ### Credential Management @@ -879,7 +879,7 @@ Some additional rules: - **Network Segmentation**: Operators must configure NetworkPolicies for controlled egress access - **Source Authorization**: Operators responsible for ensuring policy sources are legitimate and approved -- **Access Logging**: Standard Kubernetes audit logging captures WafPolicy resource operations; policy fetch operations logged via NGF's existing logging mechanisms +- **Access Logging**: Standard Kubernetes audit logging captures WAFPolicy resource operations; policy fetch operations logged via NGF's existing logging mechanisms ### Regulatory Compliance @@ -922,7 +922,7 @@ Some additional rules: ### Alternative 7: Manual Policy Updates Only -**Approach**: Require users to manually update WafPolicy resources for each policy change +**Approach**: Require users to manually update WAFPolicy resources for each policy change **Rejected Reason**: Breaks GitOps workflows and creates operational overhead; teams want to update policies without modifying Kubernetes resources ### Alternative 8: Webhook-Only Updates @@ -994,9 +994,9 @@ spec: hostname: "grpc.example.com" --- -# 4. Gateway-level WafPolicy (inherited by all routes) +# 4. Gateway-level WAFPolicy (inherited by all routes) apiVersion: gateway.nginx.org/v1alpha1 -kind: WafPolicy +kind: WAFPolicy metadata: name: gateway-base-protection namespace: applications @@ -1029,9 +1029,9 @@ spec: type: "Stderr" --- -# 5. Route-level WafPolicy override for admin endpoints +# 5. Route-level WAFPolicy override for admin endpoints apiVersion: gateway.nginx.org/v1alpha1 -kind: WafPolicy +kind: WAFPolicy metadata: name: admin-strict-protection namespace: applications @@ -1074,7 +1074,7 @@ spec: backendRefs: - name: api-service port: 8080 - # Inherits gateway-base-protection WafPolicy automatically + # Inherits gateway-base-protection WAFPolicy automatically --- # 7. HTTPRoute with policy override @@ -1094,7 +1094,7 @@ spec: backendRefs: - name: admin-service port: 8080 - # Uses admin-strict-protection WafPolicy override via targetRef + # Uses admin-strict-protection WAFPolicy override via targetRef --- # 8. GRPCRoute inheriting Gateway protection @@ -1115,7 +1115,7 @@ spec: backendRefs: - name: user-grpc-service port: 9000 - # Inherits gateway-base-protection WafPolicy automatically + # Inherits gateway-base-protection WAFPolicy automatically This complete example demonstrates: