-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcodacy-rules.yaml
More file actions
626 lines (625 loc) · 22.9 KB
/
codacy-rules.yaml
File metadata and controls
626 lines (625 loc) · 22.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
rules:
- id: codacy.bash.security.hard-coded-password
languages:
- bash
- sh
message: Hardcoded passwords are a security risk. They can be easily found by attackers and used to gain unauthorized access to the system.
pattern-regex: (?i)(?<![\$\w"'\[\]])\bpassword\s*(?<![=])=(?![=])\s*["'][^"']+["']
severity: ERROR
metadata:
owasp:
- A3:2017 Sensitive Data Exposure
description: Hardcoded passwords are a security risk.
category: security
technology:
- bash
- shell
impact: HIGH
confidence: MEDIUM
- id: codacy.java.security.hard-coded-password
severity: ERROR
languages:
- java
patterns:
- pattern-either:
- pattern: String $PASSWORD = "$VALUE";
- metavariable-regex:
metavariable: "$PASSWORD"
regex: "(?i).*(password|motdepasse|heslo|adgangskode|wachtwoord|salasana|passwort|passord|senha|geslo|clave|losenord|clave|parola|secret|pwd|key).*"
message: Hardcoded passwords are a security risk. They can be easily found by attackers and used to gain unauthorized access to the system.
metadata:
owasp:
- A3:2017 Sensitive Data Exposure
description: Hardcoded passwords are a security risk.
category: security
technology:
- java
impact: HIGH
confidence: MEDIUM
- id: codacy.csharp.security.hard-coded-password
severity: ERROR
languages:
- csharp
patterns:
- pattern-either:
- pattern: var $PASSWORD = "$VALUE";
- metavariable-regex:
metavariable: "$PASSWORD"
regex: "(?i).*(password|motdepasse|heslo|adgangskode|wachtwoord|salasana|passwort|passord|senha|geslo|clave|losenord|clave|parola|secret|pwd|key).*"
message: Hardcoded passwords are a security risk. They can be easily found by attackers and used to gain unauthorized access to the system.
metadata:
owasp:
- A3:2017 Sensitive Data Exposure
description: Hardcoded passwords are a security risk.
category: security
technology:
- .net
impact: HIGH
confidence: MEDIUM
- id: codacy.javascript.security.hard-coded-password
severity: ERROR
languages:
- javascript
- typescript
patterns:
- pattern-either:
- pattern: let $PASSWORD = "$VALUE"
- pattern: const $PASSWORD = "$VALUE"
- pattern: var $PASSWORD = "$VALUE"
- pattern: let $PASSWORD = '$VALUE'
- pattern: const $PASSWORD = '$VALUE'
- pattern: var $PASSWORD = '$VALUE'
- pattern: let $PASSWORD = `$VALUE`
- pattern: const $PASSWORD = `$VALUE`
- pattern: var $PASSWORD = `$VALUE`
- metavariable-regex:
metavariable: "$PASSWORD"
regex: "(?i).*(password|motdepasse|heslo|adgangskode|wachtwoord|salasana|passwort|passord|senha|geslo|clave|losenord|clave|parola|secret|pwd|key).*"
message: Hardcoded passwords are a security risk. They can be easily found by attackers and used to gain unauthorized access to the system.
metadata:
owasp:
- A3:2017 Sensitive Data Exposure
description: Hardcoded passwords are a security risk.
category: security
technology:
- javascript
impact: HIGH
confidence: MEDIUM
- id: codacy.generic.plsql.empty-strings
severity: WARNING
languages:
- generic
pattern: $VAR VARCHAR2($LENGTH) := '';
message: Empty strings can lead to unexpected behavior and should be handled carefully.
metadata:
description: Detects empty strings in the code which might cause issues or bugs.
category: security
impact: MEDIUM
confidence: MEDIUM
- id: codacy.generic.plsql.find-all-passwords
severity: ERROR
languages:
- generic
patterns:
- pattern: |
$PASSWORD VARCHAR2($LENGTH) := $...VALUE;
- metavariable-regex:
metavariable: "$PASSWORD"
regex: "(?i).*(password|motdepasse|heslo|adgangskode|wachtwoord|salasana|passwort|passord|senha|geslo|clave|losenord|clave|parola|secret|pwd|key).*"
options:
generic_ellipsis_max_span: 0
message: >
Hardcoded or exposed passwords are a security risk. They can be easily found by attackers and used to gain unauthorized access to the system.
metadata:
owasp:
- A3:2017 Sensitive Data Exposure
description: Finding all occurrences of passwords in different languages and formats, while avoiding common false positives.
category: security
impact: HIGH
confidence: MEDIUM
- id: codacy.generic.plsql.resource-injection
severity: ERROR
languages:
- generic
patterns:
- pattern-either:
- pattern: |
$RESOURCE := DBMS_CUBE.BUILD($...ARGS);
- pattern: |
$RESOURCE := DBMS_FILE_TRANSFER.COPY_FILE($...ARGS);
- pattern: |
$RESOURCE := DBMS_FILE_TRANSFER.GET_FILE($...ARGS);
- pattern: |
$RESOURCE := DBMS_FILE_TRANSFER.PUT_FILE($...ARGS);
- pattern: |
$RESOURCE := DBMS_SCHEDULER.GET_FILE($...ARGS);
- pattern: |
$RESOURCE := DBMS_SCHEDULER.PUT_FILE($...ARGS);
- pattern: |
$RESOURCE := DBMS_SCHEDULER.CREATE_PROGRAM($...ARGS);
- pattern: |
$RESOURCE := DBMS_SERVICE.CREATE_SERVICE($...ARGS);
- pattern: |
$RESOURCE := UTL_TCP.OPEN_CONNECTION($...ARGS);
- pattern: |
$RESOURCE := UTL_SMTP.OPEN_CONNECTION($...ARGS);
- pattern: |
$RESOURCE := WPG_DOCLOAD.DOWNLOAD_FILE($...ARGS);
options:
generic_ellipsis_max_span: 0
message: Resource injection detected. This can lead to unauthorized access or manipulation of resources.
metadata:
owasp:
- A3:2017 Sensitive Data Exposure
description: Detects assignments in PL/SQL involving risky DBMS functions that might cause security issues.
category: security
impact: HIGH
confidence: MEDIUM
- id: codacy.generic.sql.grant-all
severity: ERROR
languages:
- generic
pattern: |
GRANT ALL $X
paths:
include:
- '*.sql'
message: >
GRANT ALL privileges should not be used as it gives excessive permissions that violate the principle of least privilege.
Instead, grant only the specific privileges that are required.
metadata:
owasp:
- A5:2017 Broken Access Control
description: Detects use of GRANT ALL which gives excessive database privileges
category: security
impact: HIGH
confidence: LOW
- id: codacy.generic.sql.grant-select-no-role
languages:
- generic
severity: ERROR
message: >
GRANT SELECT privileges should only be given to role-based accounts
(ending in '_role'). Direct grants to users or non-role accounts violate
security best practices.
pattern-regex: GRANT\s+(?:DELETE|INSERT|SELECT|UPDATE)(?:\s*,\s*(?:DELETE|INSERT|SELECT|UPDATE))*\s+ON\s+[\w.*]+\s+TO\s+(?!\w*_[Rr][Oo][Ll][Ee]\b)\b\w+
paths:
include:
- "*.sql"
metadata:
owasp:
- A5:2017 Broken Access Control
description: Detects GRANT SELECT statements that are not targeting role-based
accounts
category: security
impact: MEDIUM
confidence: LOW
- id: codacy.generic.sql.fnd-profile-in-query
severity: ERROR
languages:
- generic
patterns:
- pattern-either:
- pattern-regex: (?i)SELECT\s+.*\bFND_PROFILE\.[a-zA-Z0-9_]+\(
- pattern-regex: (?i)SELECT\s+.*\bFROM\b.*\bWHERE\b.*\bFND_PROFILE\.[a-zA-Z0-9_]+\(
paths:
include:
- '*.sql'
message: >
FND_PROFILE functions should not be used directly in SELECT or WHERE clauses.
Instead, assign the FND_PROFILE function value to a variable first and then use that variable in the query.
This improves performance and maintainability.
metadata:
description: Detects direct usage of FND_PROFILE functions in SQL queries instead of using variables
category: performance
impact: MEDIUM
confidence: LOW
- id: codacy.java.security.flexible-search-sql-injection
languages:
- java
severity: ERROR
message: "Possible SQL Injection: Avoid concatenating user input in FlexibleSearchQuery."
patterns:
- pattern-either:
- pattern: |
new FlexibleSearchQuery("SELECT " + ...)
- pattern: |
new FlexibleSearchQuery("..." + $VAR + "...")
- pattern-not: |
new FlexibleSearchQuery("SELECT ... ?param")
metadata:
category: security
technology: [sap-commerce, hybris]
confidence: LOW
- id: codacy.csharp.security.null-dereference
languages:
- csharp
severity: ERROR
message: >
Potential null dereference detected. The parameter or variable could be
null and should be validated before accessing its members. Add a null
check before dereferencing the object to prevent NullReferenceException at
runtime.
patterns:
- pattern-inside: |
$RETURNTYPE $METHOD(...,$TYPE $NULLABLE, ...) { ... }
- pattern-not-inside: |
if ($NULLABLE == null) { ... }
...
- pattern-either:
- pattern: |
$NULLABLE.$MEMBER
- pattern: |
$FUNCTION_NAME($NULLABLE, ...);
- pattern-not: |
if ($NULLABLE == null) { return ... }
...
metadata:
category: security
technology:
- csharp
- dotnet
confidence: LOW
- id: codacy.generic.security.detect-invisible-unicode
languages:
- yaml
- json
severity: WARNING
message: It's possible to embed malicious secret instructions to AI rules files using unicode characters that are invisible to human reviewers.This can lead to future AI-generated code that has security vulnerabilities or other weaknesses baked in which may not be noticed.
pattern-regex: "[\u200B\u200C\u200D\u2060\uFEFF]"
paths:
include:
- "*.json"
- "*.yaml"
- "*.yml"
metadata:
description: Detects the invisible unicode characters
category: security
technology:
- AI
- Copilot
- Cursor
confidence: MEDIUM
- id: codacy.generic.csharp-lowercase-variables
languages:
- csharp
severity: INFO
message: "Variable names should be lowercase"
pattern-regex: (?:int|string|long|float|char|double|bool|var)\s([A-Z0-9])
paths:
include:
- "*.cs"
metadata:
description: Variable names should be lowercase
category: codestyle
technology:
- .net
impact: LOW
confidence: LOW
- id: codacy.generic.sql.hardcoded-language-currency-orgid
severity: ERROR
languages:
- generic
patterns:
- pattern-either:
- pattern-regex: "(?i)^(?:(?!--).)*\\b\\w*language\\w*\\b\\s*(=|:=)\\s*'?\\b[A-Z]{2}\\b'?"
- pattern-regex: "(?i)^(?:(?!--).)*\\b\\w*currency\\w*\\b\\s*(=|:=)\\s*'?\\b[A-Z]{3}\\b'?"
- pattern-regex: "(?i)^(?:(?!--).)*\\b(\\w*\\.)?org_id\\b\\s*(=|:=|IN|!=|<>)\\s*(\\(?\\s*'?\\d+'?(,\\s*'?\\d+'?)*\\s*\\)?)?"
paths:
include:
- "*.sql"
message: >
Hardcoded Language, Currency, or Org_Id values detected in SQL.Avoid hardcoding such values; use parameters or configuration instead.
metadata:
description: >
Detects hardcoded values for fields containing 'language', 'currency', or 'org_id' in SQL queries. These should be parameterized or retrieved from configuration.
category: performance
impact: MEDIUM
confidence: LOW
- id: codacy.generic.sql.lookup-type-without-language-or-apps-fnd
severity: ERROR
languages:
- generic
patterns:
- pattern-either:
- pattern-regex: "(?i)lookup_type(?![^;]{0,200}language\\s*=)"
- pattern-regex: "apps\\.fnd_lookup_values"
paths:
include:
- "*.sql"
message: >
Usage of 'lookup_type' without a language clause or reference to 'apps.fnd_lookup_values' detected.These patterns must be reviewed for localization and security risks.
metadata:
description: >
Flags usage of 'lookup_type' when no 'language = ...' clause is present, and flags any use of 'apps.fnd_lookup_values'.
category: performance
impact: MEDIUM
confidence: LOW
- id: codacy.generic.sql.from-all-without-orgid
severity: ERROR
languages:
- generic
patterns:
- pattern-regex: "(?i)from\\s+[a-z0-9_]*_all[a-z0-9_]*(?![^;]{0,300}\\b[a-z0-9_]*org_id\\b\\s*(=|:=))"
paths:
include:
- "*.sql"
message: >
Detected use of *_ALL* table without an org_id clause.These queries must include an org_id condition to ensure data partitioning.
metadata:
description: >
Flags any SQL query selecting from *_ALL* tables without checking for an org_id condition like org_id = ... or org_id := ...
category: performance
impact: MEDIUM
confidence: LOW
- id: codacy.generic.sql.rac-table-access
severity: ERROR
languages:
- generic
patterns:
- pattern-regex: '(?i)\b(SELECT|INSERT\s+INTO|UPDATE|DELETE\s+FROM)\b(?![^\n;]*\bRAC_\w*\b)[^\n;]*'
paths:
include:
- "*.sql"
message: >
All queries must target RAC_* tables.Query does not reference RAC_* table.
metadata:
description: >
Enforce that all SELECT, INSERT, UPDATE, and DELETE queries must be performed only on RAC_* tables.
category: performance
impact: MEDIUM
confidence: LOW
- id: codacy.generic.sql.rownum
severity: ERROR
languages:
- generic
patterns:
- pattern-regex: (?i)\bROWNUM\b
paths:
include:
- "*.sql"
message: >
The file contains ROWNUM usage which must be reviewed for performance and correctness.
metadata:
description: >
The file contains ROWNUM usage which must be reviewed for performance and correctness.
category: security
impact: MEDIUM
confidence: LOW
- id: codacy.python.openai.non-guardrails-direct-call
message: "Direct OpenAI SDK call detected. Use Guardrails client (GuardrailsOpenAI/GuardrailsAsyncOpenAI) instead."
severity: WARNING
languages: [python]
metadata:
category: security
cwe: "CWE-20: Improper Input Validation"
references:
- https://openai.github.io/openai-guardrails-python/
justification: >
Guardrails is a drop-in replacement that automatically validates inputs/outputs.
Prefer Guardrails clients over raw openai.* calls.
confidence: MEDIUM
patterns:
- pattern-either:
- pattern: openai.ChatCompletion.create(...)
- pattern: openai.Completion.create(...)
- pattern: openai.chat.completions.create(...)
- pattern: openai.responses.create(...)
- pattern: openai.embeddings.create(...)
- pattern: openai.images.generate(...)
- pattern: openai.audio.transcriptions.create(...)
- pattern: openai.audio.speech.create(...)
- id: codacy.python.openai.non-guardrails-client-usage
message: "OpenAI client used without Guardrails. Replace with GuardrailsOpenAI / GuardrailsAsyncOpenAI."
severity: WARNING
languages: [python]
metadata:
category: security
cwe: "CWE-20: Improper Input Validation"
references:
- https://openai.github.io/openai-guardrails-python/
justification: >
Guardrails advises using GuardrailsOpenAI/GuardrailsAsyncOpenAI as a drop-in replacement
so validation runs automatically on every API call.
confidence: MEDIUM
# Catch typical client flows while avoiding false hits when the client *is* a Guardrails client.
patterns:
- pattern-either:
# Synchronous client patterns
- pattern: |
$C = OpenAI(...)
...
$C.chat.completions.create(...)
- pattern: |
$C = OpenAI(...)
...
$C.responses.create(...)
- pattern: |
$C = OpenAI(...)
...
$C.embeddings.create(...)
# Async client patterns
- pattern: |
$C = AsyncOpenAI(...)
...
$C.chat.completions.create(...)
- pattern: |
$C = AsyncOpenAI(...)
...
$C.responses.create(...)
- pattern: |
$C = AsyncOpenAI(...)
...
$C.embeddings.create(...)
- pattern-not: |
$C = GuardrailsOpenAI(...)
- pattern-not: |
$C = GuardrailsAsyncOpenAI(...)
- id: codacy.python.openai.import-without-guardrails
message: "OpenAI SDK imported without Guardrails import. Consider GuardrailsOpenAI / GuardrailsAsyncOpenAI."
severity: INFO
languages: [python]
metadata:
category: security
references:
- https://openai.github.io/openai-guardrails-python/
confidence: MEDIUM
# Soft signal: import present but no Guardrails import in same file.
# This is informational to help teams spot likely non-guardrailed files early.
pattern: |
import openai
pattern-not: |
from guardrails import GuardrailsOpenAI |
from guardrails import GuardrailsAsyncOpenAI
- id: codacy.csharp.security.sql-injection.dynamic-query
severity: ERROR
languages:
- csharp
message: Possible SQL Injection via dynamic SQL (SELECT/INSERT/UPDATE/DELETE/EXEC) concatenation; use parameterized queries (command.Parameters.Add / AddWithValue) instead.
patterns:
- pattern-either:
# Insecure constructor usage with concatenation
- pattern: new MySqlCommand($Q + $REST, ...)
- pattern: new SqlCommand($Q + $REST, ...)
# Insecure CommandText assignment with concatenation
- pattern: $CMD.CommandText = $Q + $REST;
# Generic variable/field assignment (e.g., cd.command = "SELECT ..." + userInput)
- pattern: $TARGET = $Q + $REST;
- metavariable-regex:
metavariable: "$Q"
regex: "(?i).*(select|insert|update|delete|exec).*"
- pattern-not: new MySqlCommand("SELECT ... @PARAM ...", ...)
- pattern-not: new SqlCommand("SELECT ... @PARAM ...", ...)
- pattern-not: $CMD.CommandText = "SELECT ... @PARAM ...";
# Broad regex fallback to catch chained concatenations including a control .Text usage (typical Windows Forms / ASP.NET user input)
- pattern-regex: (?i)(SELECT|INSERT|UPDATE|DELETE|EXEC)[^;\n]*\+[^;\n]*\.Text
metadata:
category: security
technology:
- csharp
- dotnet
cwe: "CWE-89: SQL Injection"
impact: HIGH
likelihood: MEDIUM
confidence: LOW
- id: codacy.csharp.best-practice.misleading-exception-class-name
severity: WARNING
languages:
- csharp
message: Class name contains 'Exception' but does not inherit from System.Exception or its subclasses. This misleads maintainers and API users about the class's purpose.
patterns:
- pattern: |
public class $CLASS { ... }
- metavariable-regex:
metavariable: "$CLASS"
regex: ".*Exception$"
- pattern-not: |
public class $CLASS : Exception { ... }
- pattern-not: |
public class $CLASS : System.Exception { ... }
- pattern-not: |
public class $CLASS : $PARENT { ... }
metadata:
category: best-practice
technology:
- csharp
- dotnet
description: Classes with 'Exception' in their name should inherit from Exception or its subclasses
impact: LOW
confidence: HIGH
- id: codacy.k8s.ingress.nginx.retirement.ingress-resource
languages:
- yaml
severity: WARNING
message: >
This Ingress is configured to use the Ingress NGINX controller
(kubernetes.io/ingress.class: nginx or ingressClassName: nginx).
Ingress NGINX is scheduled for retirement (no fixes after March 2026).
Plan to migrate to Gateway API or another Ingress controller.
patterns:
- pattern-either:
# Classic way: annotation kubernetes.io/ingress.class: nginx
- pattern: |
apiVersion: ...
kind: Ingress
metadata:
...
annotations:
...
kubernetes.io/ingress.class: nginx
...
# Newer way: spec.ingressClassName: nginx
- pattern: |
apiVersion: ...
kind: Ingress
spec:
...
ingressClassName: nginx
...
metadata:
category: security
technology:
- kubernetes
description: >
Detects Ingress resources configured to use the Ingress NGINX controller.
Ingress NGINX is scheduled for retirement (no fixes after March 2026).
impact: MEDIUM
confidence: HIGH
references:
- https://kubernetes.io/blog/2025/11/11/ingress-nginx-retirement/
- https://kubernetes.github.io/ingress-nginx/user-guide/basic-usage/
- id: codacy.k8s.ingress.nginx.retirement.ingress-class
languages:
- yaml
severity: WARNING
message: >
This IngressClass is wired to the Ingress NGINX controller
(spec.controller: k8s.io/ingress-nginx).
Ingress NGINX is scheduled for retirement (no fixes after March 2026).
Plan to migrate to Gateway API or another Ingress controller.
pattern: |
apiVersion: networking.k8s.io/v1
kind: IngressClass
...
spec:
controller: k8s.io/ingress-nginx
metadata:
category: security
technology:
- kubernetes
description: >
Detects IngressClass objects wired to the Ingress NGINX controller.
Ingress NGINX is scheduled for retirement (no fixes after March 2026).
impact: MEDIUM
confidence: HIGH
references:
- https://kubernetes.io/blog/2025/11/11/ingress-nginx-retirement/
- id: codacy.k8s.ingress.nginx.retirement.workload
languages:
- yaml
severity: WARNING
message: >
This Kubernetes resource is labelled as part of the Ingress NGINX
controller stack (app.kubernetes.io/name: ingress-nginx).
Ingress NGINX is scheduled for retirement (no fixes after March 2026).
Plan to migrate to Gateway API or another Ingress controller.
pattern: |
apiVersion: ...
kind: $KIND
metadata:
...
labels:
...
app.kubernetes.io/name: ingress-nginx
...
metadata:
category: security
technology:
- kubernetes
description: >
Detects Kubernetes resources labelled as part of the Ingress NGINX
controller stack. Ingress NGINX is scheduled for retirement (no fixes after March 2026).
impact: MEDIUM
confidence: HIGH
references:
- https://kubernetes.io/blog/2025/11/11/ingress-nginx-retirement/