@@ -12,31 +12,34 @@ import (
1212// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
1313// +kubebuilder:metadata:labels="gateway.networking.k8s.io/policy=inherited"
1414
15- // WafPolicy is an Inherited Attached Policy. It provides a way to configure NGINX App Protect Web Application Firewall
15+ // WAFPolicy is an Inherited Attached Policy. It provides a way to configure NGINX App Protect Web Application Firewall
1616// for Gateways and Routes.
17- type WafPolicy struct {
17+ type WAFPolicy struct {
1818 metav1.TypeMeta `json:",inline"`
1919 metav1.ObjectMeta `json:"metadata,omitempty"`
2020
21- // Spec defines the desired state of the WafPolicy .
22- Spec WafPolicySpec `json:"spec"`
21+ // Spec defines the desired state of the WAFPolicy .
22+ Spec WAFPolicySpec `json:"spec"`
2323
24- // Status defines the state of the WafPolicy .
24+ // Status defines the state of the WAFPolicy .
2525 Status gatewayv1alpha2.PolicyStatus `json:"status,omitempty"`
2626}
2727
2828// +kubebuilder:object:root=true
2929
30- // WafPolicyList contains a list of WafPolicies .
31- type WafPolicyList struct {
30+ // WAFPolicyList contains a list of WAFPolicies .
31+ type WAFPolicyList struct {
3232 metav1.TypeMeta `json:",inline"`
3333 metav1.ListMeta `json:"metadata,omitempty"`
34- Items []WafPolicy `json:"items"`
34+ Items []WAFPolicy `json:"items"`
3535}
3636
37- // WafPolicySpec defines the desired state of a WafPolicy.
38- type WafPolicySpec struct {
39- PolicySource * WafPolicySource `json:"policySource,omitempty"`
37+ // WAFPolicySpec defines the desired state of a WAFPolicy.
38+ type WAFPolicySpec struct {
39+ // PolicySource defines the source location and configuration for the compiled WAF policy bundle.
40+ //
41+ // +kubebuilder:validation:Required
42+ PolicySource WAFPolicySource `json:"policySource"`
4043
4144 // TargetRef identifies an API object to apply the policy to.
4245 // Object must be in the same namespace as the policy.
@@ -47,26 +50,35 @@ type WafPolicySpec struct {
4750 //nolint:lll
4851 TargetRef gatewayv1alpha2.LocalPolicyTargetReference `json:"targetRef"`
4952
50- SecurityLogs []WafSecurityLog `json:"securityLogs,omitempty"`
53+ // SecurityLogs defines the security logging configuration for app_protect_security_log directives.
54+ // Multiple logging configurations can be specified to send logs to different destinations.
55+ //
56+ // +optional
57+ // +kubebuilder:validation:MaxItems=32
58+ SecurityLogs []WAFSecurityLog `json:"securityLogs,omitempty"`
5159}
5260
53- type WafPolicySource struct {
54- // WafPolicyAuthSecret is the Secret containing authentication credentials for the WAF policy source.
61+ // WAFPolicySource defines the source location and configuration for fetching WAF policy bundles.
62+ type WAFPolicySource struct {
63+ // AuthSecret is the Secret containing authentication credentials for the WAF policy source.
5564 //
5665 // +optional
57- AuthSecret * WafPolicyAuthSecret `json:"authSecret,omitempty"`
66+ AuthSecret * WAFPolicyAuthSecret `json:"authSecret,omitempty"`
5867
59- Validation * WafPolicyValidation `json:"validation,omitempty"`
68+ // Validation defines the validation methods for policy integrity verification.
69+ //
70+ // +optional
71+ Validation * WAFPolicyValidation `json:"validation,omitempty"`
6072
6173 // Polling defines the polling configuration for automatic WAF policy change detection.
6274 //
6375 // +optional
64- Polling * WafPolicyPolling `json:"polling,omitempty"`
76+ Polling * WAFPolicyPolling `json:"polling,omitempty"`
6577
6678 // Retry defines the retry configuration for WAF policy fetch failures.
6779 //
6880 // +optional
69- Retry * WafPolicyRetry `json:"retry,omitempty"`
81+ Retry * WAFPolicyRetry `json:"retry,omitempty"`
7082
7183 // Timeout for policy downloads.
7284 //
@@ -76,12 +88,13 @@ type WafPolicySource struct {
7688 // FileLocation defines the location of the WAF policy file.
7789 //
7890 // +kubebuilder:validation:MinLength=1
91+ // +kubebuilder:validation:MaxLength=2048
7992 FileLocation string `json:"fileLocation"`
8093}
8194
82- // WafPolicyAuthSecret is the Secret containing authentication credentials for the WAF policy source.
95+ // WAFPolicyAuthSecret is the Secret containing authentication credentials for the WAF policy source.
8396// It must live in the same Namespace as the policy.
84- type WafPolicyAuthSecret struct {
97+ type WAFPolicyAuthSecret struct {
8598 // Name is the name of the Secret containing authentication credentials for the WAF policy source.
8699 //
87100 // +kubebuilder:validation:MinLength=1
@@ -90,109 +103,202 @@ type WafPolicyAuthSecret struct {
90103 Name string `json:"name"`
91104}
92105
93- type WafPolicyValidation struct {
94- Methods []string `json:"methods,omitempty"`
106+ // WAFPolicyValidation defines the validation methods for policy integrity verification.
107+ type WAFPolicyValidation struct {
108+ // Methods specifies the validation methods to use for policy integrity verification.
109+ // Currently supported: ["checksum"]
110+ //
111+ // +optional
112+ // +kubebuilder:validation:UniqueItems=true
113+ // +listType=set
114+ Methods []WAFPolicyValidationMethod `json:"methods,omitempty"`
95115}
96116
97- // WafPolicyPolling defines the polling configuration for automatic WAF policy change detection.
98- type WafPolicyPolling struct {
117+ // WAFPolicyValidationMethod defines the supported validation methods.
118+ //
119+ // +kubebuilder:validation:Enum=checksum
120+ type WAFPolicyValidationMethod string
121+
122+ const (
123+ // WAFPolicyValidationChecksum validates policy integrity using checksum verification.
124+ WAFPolicyValidationChecksum WAFPolicyValidationMethod = "checksum"
125+ )
126+
127+ // WAFPolicyPolling defines the polling configuration for automatic WAF policy change detection.
128+ type WAFPolicyPolling struct {
99129 // Enabled indicates whether polling is enabled for automatic WAF policy change detection.
130+ // When enabled, NGF will periodically check for policy changes using checksum validation.
100131 //
101132 // +optional
133+ // +kubebuilder:default=false
102134 Enabled * bool `json:"enabled,omitempty"`
103135
104136 // Interval is the polling interval to check for WAF policy changes.
137+ // Must be a valid duration string (e.g., "5m", "30s", "1h").
138+ // Defaults to "5m" if polling is enabled.
105139 //
106140 // +optional
141+ // +kubebuilder:default="5m"
107142 Interval * Duration `json:"interval,omitempty"`
108143
144+ // ChecksumLocation specifies the location of the checksum file for the policy bundle.
145+ // If not specified, defaults to <fileLocation>.sha256
146+ //
147+ // +optional
148+ // +kubebuilder:validation:MaxLength=2048
109149 ChecksumLocation * string `json:"checksumLocation,omitempty"`
110150}
111151
112- // WafPolicyRetry defines the retry configuration for WAF policy fetch failures.
113- type WafPolicyRetry struct {
152+ // WAFPolicyRetry defines the retry configuration for WAF policy fetch failures.
153+ type WAFPolicyRetry struct {
114154 // Attempts is the number of retry attempts for fetching the WAF policy.
155+ // Set to 0 to disable retries.
115156 //
116157 // +optional
117158 // +kubebuilder:validation:Minimum=0
159+ // +kubebuilder:default=3
118160 Attempts * int32 `json:"attempts,omitempty"`
119161
120- Backoff * string `json:"backoff,omitempty"`
162+ // Backoff defines the backoff strategy for retry attempts.
163+ // Supported values: "exponential", "linear"
164+ //
165+ // +optional
166+ // +kubebuilder:validation:Enum=exponential;linear
167+ // +kubebuilder:default="exponential"
168+ Backoff * WAFPolicyRetryBackoff `json:"backoff,omitempty"`
121169
170+ // MaxDelay is the maximum delay between retry attempts.
171+ // Must be a valid duration string (e.g., "5m", "30s").
172+ //
173+ // +optional
174+ // +kubebuilder:default="5m"
122175 MaxDelay * Duration `json:"maxDelay,omitempty"`
123176}
124177
125- // WafSecurityLog defines the security logging configuration for app_protect_security_log directives.
178+ // WAFPolicyRetryBackoff defines the supported backoff strategies.
179+ //
180+ // +kubebuilder:validation:Enum=exponential;linear
181+ type WAFPolicyRetryBackoff string
182+
183+ const (
184+ // WAFPolicyRetryBackoffExponential uses exponential backoff for retry delays.
185+ WAFPolicyRetryBackoffExponential WAFPolicyRetryBackoff = "exponential"
186+ // WAFPolicyRetryBackoffLinear uses linear backoff for retry delays.
187+ WAFPolicyRetryBackoffLinear WAFPolicyRetryBackoff = "linear"
188+ )
189+
190+ // WAFSecurityLog defines the security logging configuration for app_protect_security_log directives.
126191// LogProfile and LogProfileBundle are mutually exclusive per security log entry.
127192//
128193// +kubebuilder:validation:XValidation:message="only one of logProfile or logProfileBundle may be set",rule="!(has(self.logProfile) && has(self.logProfileBundle))"
194+ // +kubebuilder:validation:XValidation:message="at least one of logProfile or logProfileBundle must be set",rule="has(self.logProfile) || has(self.logProfileBundle)"
129195//
130196//nolint:lll
131- type WafSecurityLog struct {
132- Destination SecurityLogDestination `json:"destination"`
197+ type WAFSecurityLog struct {
198+ // Name is the name of the security log configuration.
199+ //
200+ // +optional
201+ // +kubebuilder:validation:MinLength=1
202+ // +kubebuilder:validation:MaxLength=63
203+ // +kubebuilder:validation:Pattern=`^[a-zA-Z0-9]([a-zA-Z0-9_-]*[a-zA-Z0-9])?$`
204+ Name * string `json:"name,omitempty"`
133205
134- // LogProfile defines the built-in logging profile.
206+ // LogProfile defines the built-in logging profile to use .
135207 //
136208 // +optional
137209 LogProfile * LogProfile `json:"logProfile,omitempty"`
138210
139- // LogProfile defines a custom logging profile bundle, similar to policy bundle.
211+ // LogProfileBundle defines a custom logging profile bundle, similar to policy bundle.
140212 //
141213 // +optional
142- LogProfileBundle * WafPolicySource `json:"logProfileBundle,omitempty"`
214+ LogProfileBundle * WAFPolicySource `json:"logProfileBundle,omitempty"`
143215
144- // Name is the name of the security log configuration .
145- Name string `json:"name "`
216+ // Destination defines where the security logs should be sent .
217+ Destination SecurityLogDestination `json:"destination "`
146218}
147219
148- // +kubebuilder:validation:XValidation:message="destination.file must be nil if the destination.type is not File",rule="!(has(self.file) && self.type != 'File')"
149- // +kubebuilder:validation:XValidation:message="destination.file must be specified for File destination.type",rule="!(!has(self.file) && self.type == 'File')"
150- // +kubebuilder:validation:XValidation:message="destination.syslog must be nil if the destination.type is not Syslog",rule="!(has(self.syslog) && self.type != 'Syslog')"
151- // +kubebuilder:validation:XValidation:message="destination.syslog must be specified for Syslog destination.type",rule="!(!has(self.syslog) && self.type == 'Syslog')"
220+ // SecurityLogDestination defines the destination for security logs.
221+ //
222+ // +kubebuilder:validation:XValidation:message="destination.file must be nil if the destination.type is not file",rule="!(has(self.file) && self.type != 'file')"
223+ // +kubebuilder:validation:XValidation:message="destination.file must be specified for file destination.type",rule="!(!has(self.file) && self.type == 'file')"
224+ // +kubebuilder:validation:XValidation:message="destination.syslog must be nil if the destination.type is not syslog",rule="!(has(self.syslog) && self.type != 'syslog')"
225+ // +kubebuilder:validation:XValidation:message="destination.syslog must be specified for syslog destination.type",rule="!(!has(self.syslog) && self.type == 'syslog')"
152226//
153227//nolint:lll
154228type SecurityLogDestination struct {
229+ // File defines the file destination configuration.
230+ // Only valid when type is "file".
231+ //
232+ // +optional
155233 File * SecurityLogFile `json:"file,omitempty"`
156234
235+ // Syslog defines the syslog destination configuration.
236+ // Only valid when type is "syslog".
237+ //
238+ // +optional
157239 Syslog * SecurityLogSyslog `json:"syslog,omitempty"`
158240
159241 // Type identifies the type of security log destination.
160242 //
161243 // +unionDiscriminator
162- // +kubebuilder:default:=Stderr
244+ // +kubebuilder:default=stderr
163245 Type SecurityLogDestinationType `json:"type"`
164246}
165247
166- // +kubebuilder:validation:Enum=Stderr;File;Syslog
248+ // SecurityLogDestinationType defines the supported security log destination types.
249+ //
250+ // +kubebuilder:validation:Enum=stderr;file;syslog
167251type SecurityLogDestinationType string
168252
169253const (
170- SecurityLogDestinationTypeStderr SecurityLogDestinationType = "Stderr"
171- SecurityLogDestinationTypeFile SecurityLogDestinationType = "File"
172- SecurityLogDestinationTypeSyslog SecurityLogDestinationType = "Syslog"
254+ // SecurityLogDestinationTypeStderr outputs logs to container stderr.
255+ SecurityLogDestinationTypeStderr SecurityLogDestinationType = "stderr"
256+ // SecurityLogDestinationTypeFile writes logs to a specified file path.
257+ SecurityLogDestinationTypeFile SecurityLogDestinationType = "file"
258+ // SecurityLogDestinationTypeSyslog sends logs to a syslog server via TCP.
259+ SecurityLogDestinationTypeSyslog SecurityLogDestinationType = "syslog"
173260)
174261
262+ // SecurityLogFile defines the file destination configuration for security logs.
175263type SecurityLogFile struct {
264+ // Path is the file path where security logs will be written.
265+ // Must be accessible to the waf-enforcer container.
266+ //
267+ // +kubebuilder:validation:MinLength=1
268+ // +kubebuilder:validation:MaxLength=4096
269+ // +kubebuilder:validation:Pattern=`^/.*$`
176270 Path string `json:"path"`
177271}
178272
273+ // SecurityLogSyslog defines the syslog destination configuration for security logs.
179274type SecurityLogSyslog struct {
275+ // Server is the syslog server address in the format "host:port".
276+ //
277+ // +kubebuilder:validation:MinLength=1
278+ // +kubebuilder:validation:MaxLength=253
279+ // +kubebuilder:validation:Pattern=`^[a-zA-Z0-9.-]+:[0-9]+$`
180280 Server string `json:"server"`
181281}
182282
183- // LogProfile defines the built-in logging profile.
184- //
283+ // LogProfile defines the built-in logging profiles available in NGINX App Protect.
185284// +kubebuilder:validation:Enum=log_default;log_all;log_illegal;log_blocked;log_grpc_all;log_grpc_blocked;log_grpc_illegal
186285//
187286//nolint:lll
188287type LogProfile string
189288
190289const (
191- LogProfileDefault LogProfile = "log_default"
192- LogProfileAll LogProfile = "log_all"
193- LogProfileIllegal LogProfile = "log_illegal"
194- LogProfileBlocked LogProfile = "log_blocked"
195- LogProfileGRPCAll LogProfile = "log_grpc_all"
290+ // LogProfileDefault is the default logging profile.
291+ LogProfileDefault LogProfile = "log_default"
292+ // LogProfileAll logs all requests (blocked and passed).
293+ LogProfileAll LogProfile = "log_all"
294+ // LogProfileIllegal logs illegal requests.
295+ LogProfileIllegal LogProfile = "log_illegal"
296+ // LogProfileBlocked logs only blocked requests.
297+ LogProfileBlocked LogProfile = "log_blocked"
298+ // LogProfileGRPCAll logs all gRPC requests.
299+ LogProfileGRPCAll LogProfile = "log_grpc_all"
300+ // LogProfileGRPCBlocked logs blocked gRPC requests.
196301 LogProfileGRPCBlocked LogProfile = "log_grpc_blocked"
302+ // LogProfileGRPCIllegal logs illegal gRPC requests.
197303 LogProfileGRPCIllegal LogProfile = "log_grpc_illegal"
198304)
0 commit comments