github.com/nginxinc/kubernetes-ingress@v1.12.5/docs-web/configuration/policy-resource.md (about) 1 # Policy Resource 2 3 The Policy resource allows you to configure features like access control and rate-limiting, which you can add to your [VirtualServer and VirtualServerRoute resources](/nginx-ingress-controller/configuration/virtualserver-and-virtualserverroute-resources/). 4 5 The resource is implemented as a [Custom Resource](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/). 6 7 This document is the reference documentation for the Policy resource. An example of a Policy for access control is available in our [GitHub repo](https://github.com/nginxinc/kubernetes-ingress/blob/v1.12.5/examples-of-custom-resources/access-control). 8 9 ## Contents 10 11 - [Policy Resource](#policy-resource) 12 - [Contents](#contents) 13 - [Prerequisites](#prerequisites) 14 - [Policy Specification](#policy-specification) 15 - [AccessControl](#accesscontrol) 16 - [AccessControl Merging Behavior](#accesscontrol-merging-behavior) 17 - [RateLimit](#ratelimit) 18 - [RateLimit Merging Behavior](#ratelimit-merging-behavior) 19 - [JWT](#jwt) 20 - [JWT Merging Behavior](#jwt-merging-behavior) 21 - [IngressMTLS](#ingressmtls) 22 - [IngressMTLS Merging Behavior](#ingressmtls-merging-behavior) 23 - [EgressMTLS](#egressmtls) 24 - [EgressMTLS Merging Behavior](#egressmtls-merging-behavior) 25 - [OIDC](#oidc) 26 - [Prerequisites](#prerequisites-1) 27 - [Limitations](#limitations) 28 - [OIDC Merging Behavior](#oidc-merging-behavior) 29 - [Using Policy](#using-policy) 30 - [WAF](#waf) 31 - [WAF Merging Behavior](#waf-merging-behavior) 32 - [Applying Policies](#applying-policies) 33 - [Invalid Policies](#invalid-policies) 34 - [Validation](#validation) 35 - [Structural Validation](#structural-validation) 36 - [Comprehensive Validation](#comprehensive-validation) 37 38 ## Prerequisites 39 40 Policies work together with [VirtualServer and VirtualServerRoute resources](/nginx-ingress-controller/configuration/virtualserver-and-virtualserverroute-resources/), which you need to create separately. 41 42 ## Policy Specification 43 44 Below is an example of a policy that allows access for clients from the subnet `10.0.0.0/8` and denies access for any other clients: 45 ```yaml 46 apiVersion: k8s.nginx.org/v1 47 kind: Policy 48 metadata: 49 name: allow-localhost 50 spec: 51 accessControl: 52 allow: 53 - 10.0.0.0/8 54 ``` 55 56 ```eval_rst 57 .. list-table:: 58 :header-rows: 1 59 60 * - Field 61 - Description 62 - Type 63 - Required 64 * - ``accessControl`` 65 - The access control policy based on the client IP address. 66 - `accessControl <#accesscontrol>`_ 67 - No* 68 * - ``rateLimit`` 69 - The rate limit policy controls the rate of processing requests per a defined key. 70 - `rateLimit <#ratelimit>`_ 71 - No* 72 * - ``jwt`` 73 - The JWT policy configures NGINX Plus to authenticate client requests using JSON Web Tokens. 74 - `jwt <#jwt>`_ 75 - No* 76 * - ``ingressMTLS`` 77 - The IngressMTLS policy configures client certificate verification. 78 - `ingressMTLS <#ingressmtls>`_ 79 - No* 80 * - ``egressMTLS`` 81 - The EgressMTLS policy configures upstreams authentication and certificate verification. 82 - `egressMTLS <#egressmtls>`_ 83 - No* 84 * - ``waf`` 85 - The WAF policy configures WAF and log configuration policies for `NGINX AppProtect </nginx-ingress-controller/app-protect/installation/>`_ 86 - `WAF <#waf>`_ 87 - No* 88 ``` 89 90 \* A policy must include exactly one policy. 91 92 ### AccessControl 93 94 The access control policy configures NGINX to deny or allow requests from clients with the specified IP addresses/subnets. 95 96 For example, the following policy allows access for clients from the subnet `10.0.0.0/8` and denies access for any other clients: 97 ```yaml 98 accessControl: 99 allow: 100 - 10.0.0.0/8 101 ``` 102 103 In contrast, the policy below does the opposite: denies access for clients from `10.0.0.0/8` and allows access for any other clients: 104 ```yaml 105 accessControl: 106 deny: 107 - 10.0.0.0/8 108 ``` 109 110 > Note: The feature is implemented using the NGINX [ngx_http_access_module](http://nginx.org/en/docs/http/ngx_http_access_module.html). The Ingress Controller access control policy supports either allow or deny rules, but not both (as the module does). 111 112 ```eval_rst 113 .. list-table:: 114 :header-rows: 1 115 116 * - Field 117 - Description 118 - Type 119 - Required 120 * - ``allow`` 121 - Allows access for the specified networks or addresses. For example, ``192.168.1.1`` or ``10.1.1.0/16``. 122 - ``[]string`` 123 - No* 124 * - ``deny`` 125 - Denies access for the specified networks or addresses. For example, ``192.168.1.1`` or ``10.1.1.0/16``. 126 - ``[]string`` 127 - No* 128 ``` 129 \* an accessControl must include either `allow` or `deny`. 130 131 #### AccessControl Merging Behavior 132 133 A VirtualServer/VirtualServerRoute can reference multiple access control policies. For example, here we reference two policies, each with configured allow lists: 134 ```yaml 135 policies: 136 - name: allow-policy-one 137 - name: allow-policy-two 138 ``` 139 When you reference more than one access control policy, the Ingress Controller will merge the contents into a single allow list or a single deny list. 140 141 Referencing both allow and deny policies, as shown in the example below, is not supported. If both allow and deny lists are referenced, the Ingress Controller uses just the allow list policies. 142 ```yaml 143 policies: 144 - name: deny-policy 145 - name: allow-policy-one 146 - name: allow-policy-two 147 ``` 148 149 ### RateLimit 150 151 > **Feature Status**: Rate-Limiting is available as a preview feature: it is suitable for experimenting and testing; however, it must be used with caution in production environments. Additionally, while the feature is in preview status, we might introduce some backward-incompatible changes to the resource specification in the next releases. The feature is disabled by default. To enable it, set the [enable-preview-policies](/nginx-ingress-controller/configuration/global-configuration/command-line-arguments/#cmdoption-enable-preview-policies) command-line argument of the Ingress Controller. 152 153 The rate limit policy configures NGINX to limit the processing rate of requests. 154 155 For example, the following policy will limit all subsequent requests coming from a single IP address once a rate of 10 requests per second is exceeded: 156 ```yaml 157 rateLimit: 158 rate: 10r/s 159 zoneSize: 10M 160 key: ${binary_remote_addr} 161 ``` 162 163 > Note: The feature is implemented using the NGINX [ngx_http_limit_req_module](https://nginx.org/en/docs/http/ngx_http_limit_req_module.html). 164 165 ```eval_rst 166 .. list-table:: 167 :header-rows: 1 168 169 * - Field 170 - Description 171 - Type 172 - Required 173 * - ``rate`` 174 - The rate of requests permitted. The rate is specified in requests per second (r/s) or requests per minute (r/m). 175 - ``string`` 176 - Yes 177 * - ``key`` 178 - The key to which the rate limit is applied. Can contain text, variables, or a combination of them. Variables must be surrounded by ``${}``. For example: ``${binary_remote_addr}``. Accepted variables are ``$binary_remote_addr``, ``$request_uri``, ``$url``, ``$http_``, ``$args``, ``$arg_``, ``$cookie_``. 179 - ``string`` 180 - Yes 181 * - ``zoneSize`` 182 - Size of the shared memory zone. Only positive values are allowed. Allowed suffixes are ``k`` or ``m``, if none are present ``k`` is assumed. 183 - ``string`` 184 - Yes 185 * - ``delay`` 186 - The delay parameter specifies a limit at which excessive requests become delayed. If not set all excessive requests are delayed. 187 - ``int`` 188 - No* 189 * - ``noDelay`` 190 - Disables the delaying of excessive requests while requests are being limited. Overrides ``delay`` if both are set. 191 - ``bool`` 192 - No* 193 * - ``burst`` 194 - Excessive requests are delayed until their number exceeds the ``burst`` size, in which case the request is terminated with an error. 195 - ``int`` 196 - No* 197 * - ``dryRun`` 198 - Enables the dry run mode. In this mode, the rate limit is not actually applied, but the the number of excessive requests is accounted as usual in the shared memory zone. 199 - ``bool`` 200 - No* 201 * - ``logLevel`` 202 - Sets the desired logging level for cases when the server refuses to process requests due to rate exceeding, or delays request processing. Allowed values are ``info``, ``notice``, ``warn`` or ``error``. Default is ``error``. 203 - ``string`` 204 - No* 205 * - ``rejectCode`` 206 - Sets the status code to return in response to rejected requests. Must fall into the range ``400..599``. Default is ``503``. 207 - ``string`` 208 - No* 209 ``` 210 211 > For each policy referenced in a VirtualServer and/or its VirtualServerRoutes, the Ingress Controller will generate a single rate limiting zone defined by the [`limit_req_zone`](http://nginx.org/en/docs/http/ngx_http_limit_req_module.html#limit_req_zone) directive. If two VirtualServer resources reference the same policy, the Ingress Controller will generate two different rate limiting zones, one zone per VirtualServer. 212 213 #### RateLimit Merging Behavior 214 A VirtualServer/VirtualServerRoute can reference multiple rate limit policies. For example, here we reference two policies: 215 ```yaml 216 policies: 217 - name: rate-limit-policy-one 218 - name: rate-limit-policy-two 219 ``` 220 221 When you reference more than one rate limit policy, the Ingress Controller will configure NGINX to use all referenced rate limits. When you define multiple policies, each additional policy inherits the `dryRun`, `logLevel`, and `rejectCode` parameters from the first policy referenced (`rate-limit-policy-one`, in the example above). 222 223 ### JWT 224 225 > **Feature Status**: JWT is available as a preview feature: it is suitable for experimenting and testing; however, it must be used with caution in production environments. Additionally, while the feature is in preview status, we might introduce some backward-incompatible changes to the resource specification in the next releases. The feature is disabled by default. To enable it, set the [enable-preview-policies](/nginx-ingress-controller/configuration/global-configuration/command-line-arguments/#cmdoption-enable-preview-policies) command-line argument of the Ingress Controller. 226 227 > Note: This feature is only available in NGINX Plus. 228 229 The JWT policy configures NGINX Plus to authenticate client requests using JSON Web Tokens. 230 231 For example, the following policy will reject all requests that do not include a valid JWT in the HTTP header `token`: 232 ```yaml 233 jwt: 234 secret: jwk-secret 235 realm: "My API" 236 token: $http_token 237 ``` 238 239 You can pass the JWT claims and JOSE headers to the upstream servers. For example: 240 ```yaml 241 action: 242 proxy: 243 upstream: webapp 244 requestHeaders: 245 set: 246 - name: user 247 value: ${jwt_claim_user} 248 - name: alg 249 value: ${jwt_header_alg} 250 ``` 251 We use the `requestHeaders` of the [Action.Proxy](/nginx-ingress-controller/configuration/virtualserver-and-virtualserverroute-resources/#action-proxy) to set the values of two headers that NGINX will pass to the upstream servers. 252 253 The value of the `${jwt_claim_user}` variable is the `user` claim of a JWT. For other claims, use `${jwt_claim_name}`, where `name` is the name of the claim. Note that nested claims and claims that include a period (`.`) are not supported. Similarly, use `${jwt_header_name}` where `name` is the name of a header. In our example, we use the `alg` header. 254 255 256 > Note: The feature is implemented using the NGINX Plus [ngx_http_auth_jwt_module](https://nginx.org/en/docs/http/ngx_http_auth_jwt_module.html). 257 258 ```eval_rst 259 .. list-table:: 260 :header-rows: 1 261 262 * - Field 263 - Description 264 - Type 265 - Required 266 * - ``secret`` 267 - The name of the Kubernetes secret that stores the JWK. It must be in the same namespace as the Policy resource. The secret must be of the type ``nginx.org/jwk``, and the JWK must be stored in the secret under the key ``jwk``, otherwise the secret will be rejected as invalid. 268 - ``string`` 269 - Yes 270 * - ``realm`` 271 - The realm of the JWT. 272 - ``string`` 273 - Yes 274 * - ``token`` 275 - The token specifies a variable that contains the JSON Web Token. By default the JWT is passed in the ``Authorization`` header as a Bearer Token. JWT may be also passed as a cookie or a part of a query string, for example: ``$cookie_auth_token``. Accepted variables are ``$http_``, ``$arg_``, ``$cookie_``. 276 - ``string`` 277 - No 278 ``` 279 280 #### JWT Merging Behavior 281 282 A VirtualServer/VirtualServerRoute can reference multiple JWT policies. However, only one can be applied. Every subsequent reference will be ignored. For example, here we reference two policies: 283 ```yaml 284 policies: 285 - name: jwt-policy-one 286 - name: jwt-policy-two 287 ``` 288 In this example the Ingress Controller will use the configuration from the first policy reference `jwt-policy-one`, and ignores `jwt-policy-two`. 289 290 ### IngressMTLS 291 292 > **Feature Status**: IngressMTLS is available as a preview feature: it is suitable for experimenting and testing; however, it must be used with caution in production environments. Additionally, while the feature is in preview status, we might introduce some backward-incompatible changes to the resource specification in the next releases. The feature is disabled by default. To enable it, set the [enable-preview-policies](/nginx-ingress-controller/configuration/global-configuration/command-line-arguments/#cmdoption-enable-preview-policies) command-line argument of the Ingress Controller. 293 294 The IngressMTLS policy configures client certificate verification. 295 296 For example, the following policy will verify a client certificate using the CA certificate specified in the `ingress-mtls-secret`: 297 ```yaml 298 ingressMTLS: 299 clientCertSecret: ingress-mtls-secret 300 verifyClient: "on" 301 verifyDepth: 1 302 ``` 303 304 A VirtualServer that references an IngressMTLS policy must: 305 * Enable [TLS termination](/nginx-ingress-controller/configuration/virtualserver-and-virtualserverroute-resources/#virtualserver-tls). 306 * Reference the policy in the VirtualServer [`spec`](/nginx-ingress-controller/configuration/virtualserver-and-virtualserverroute-resources/#virtualserver-specification). It is not allowed to reference an IngressMTLS policy in a [`route `](/nginx-ingress-controller/configuration/virtualserver-and-virtualserverroute-resources/#virtualserver-route) or in a VirtualServerRoute [`subroute`](/nginx-ingress-controller/configuration/virtualserver-and-virtualserverroute-resources/#virtualserverroute-subroute). 307 308 If the conditions above are not met, NGINX will send the `500` status code to clients. 309 310 You can pass the client certificate details, including the certificate, to the upstream servers. For example: 311 ```yaml 312 action: 313 proxy: 314 upstream: webapp 315 requestHeaders: 316 set: 317 - name: client-cert-subj-dn 318 value: ${ssl_client_s_dn} # subject DN 319 - name: client-cert 320 value: ${ssl_client_escaped_cert} # client certificate in the PEM format (urlencoded) 321 ``` 322 We use the `requestHeaders` of the [Action.Proxy](/nginx-ingress-controller/configuration/virtualserver-and-virtualserverroute-resources/#action-proxy) to set the values of the two headers that NGINX will pass to the upstream servers. See the [list of embedded variables](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#variables) that are supported by the `ngx_http_ssl_module`, which you can use to pass the client certificate details. 323 324 > Note: The feature is implemented using the NGINX [ngx_http_ssl_module](https://nginx.org/en/docs/http/ngx_http_ssl_module.html). 325 326 ```eval_rst 327 .. list-table:: 328 :header-rows: 1 329 330 * - Field 331 - Description 332 - Type 333 - Required 334 * - ``clientCertSecret`` 335 - The name of the Kubernetes secret that stores the CA certificate. It must be in the same namespace as the Policy resource. The secret must be of the type ``nginx.org/ca``, and the certificate must be stored in the secret under the key ``ca.crt``, otherwise the secret will be rejected as invalid. 336 - ``string`` 337 - Yes 338 * - ``verifyClient`` 339 - Verification for the client. Possible values are ``"on"``, ``"off"``, ``"optional"``, ``"optional_no_ca"``. The default is ``"on"``. 340 - ``string`` 341 - No 342 * - ``verifyDepth`` 343 - Sets the verification depth in the client certificates chain. The default is ``1``. 344 - ``int`` 345 - No 346 ``` 347 348 #### IngressMTLS Merging Behavior 349 350 A VirtualServer can reference only a single IngressMTLS policy. Every subsequent reference will be ignored. For example, here we reference two policies: 351 ```yaml 352 policies: 353 - name: ingress-mtls-policy-one 354 - name: ingress-mtls-policy-two 355 ``` 356 In this example the Ingress Controller will use the configuration from the first policy reference `ingress-mtls-policy-one`, and ignores `ingress-mtls-policy-two`. 357 358 ### EgressMTLS 359 360 > **Feature Status**: EgressMTLS is available as a preview feature: it is suitable for experimenting and testing; however, it must be used with caution in production environments. Additionally, while the feature is in preview status, we might introduce some backward-incompatible changes to the resource specification in the next releases. The feature is disabled by default. To enable it, set the [enable-preview-policies](/nginx-ingress-controller/configuration/global-configuration/command-line-arguments/#cmdoption-enable-preview-policies) command-line argument of the Ingress Controller. 361 362 The EgressMTLS policy configures upstreams authentication and certificate verification. 363 364 For example, the following policy will use `egress-mtls-secret` to authenticate with the upstream application and `egress-trusted-ca-secret` to verify the certificate of the application: 365 ```yaml 366 egressMTLS: 367 tlsSecret: egress-mtls-secret 368 trustedCertSecret: egress-trusted-ca-secret 369 verifyServer: on 370 verifyDepth: 2 371 ``` 372 373 > Note: The feature is implemented using the NGINX [ngx_http_proxy_module](https://nginx.org/en/docs/http/ngx_http_proxy_module.html). 374 375 ```eval_rst 376 .. list-table:: 377 :header-rows: 1 378 379 * - Field 380 - Description 381 - Type 382 - Required 383 * - ``tlsSecret`` 384 - The name of the Kubernetes secret that stores the TLS certificate and key. It must be in the same namespace as the Policy resource. The secret must be of the type ``kubernetes.io/tls``, the certificate must be stored in the secret under the key ``tls.crt``, and the key must be stored under the key ``tls.key``, otherwise the secret will be rejected as invalid. 385 - ``string`` 386 - No 387 * - ``trustedCertSecret`` 388 - The name of the Kubernetes secret that stores the CA certificate. It must be in the same namespace as the Policy resource. The secret must be of the type ``nginx.org/ca``, and the certificate must be stored in the secret under the key ``ca.crt``, otherwise the secret will be rejected as invalid. 389 - ``string`` 390 - No 391 * - ``verifyServer`` 392 - Enables verification of the upstream HTTPS server certificate. 393 - ``bool`` 394 - No 395 * - ``verifyDepth`` 396 - Sets the verification depth in the proxied HTTPS server certificates chain. The default is ``1``. 397 - ``int`` 398 - No 399 * - ``sessionReuse`` 400 - Enables reuse of SSL sessions to the upstreams. The default is ``true``. 401 - ``bool`` 402 - No 403 * - ``serverName`` 404 - Enables passing of the server name through ``Server Name Indication`` extension. 405 - ``bool`` 406 - No 407 * - ``sslName`` 408 - Allows overriding the server name used to verify the certificate of the upstream HTTPS server. 409 - ``string`` 410 - No 411 * - ``ciphers`` 412 - Specifies the enabled ciphers for requests to an upstream HTTPS server. The default is ``DEFAULT``. 413 - ``string`` 414 - No 415 * - ``protocols`` 416 - Specifies the protocols for requests to an upstream HTTPS server. The default is ``TLSv1 TLSv1.1 TLSv1.2``. 417 - ``string`` 418 - No 419 ``` 420 > Note: the value of ``ciphers`` and ``protocols`` is not validated by the Ingress Controller. As a result, NGINX can fail to reload the configuration. To ensure that the configuration for a VirtualServer/VirtualServerRoute that references the policy was successfully applied, check its [status](/nginx-ingress-controller/configuration/global-configuration/reporting-resources-status/#virtualserver-and-virtualserverroute-resources). The validation will be added in the future releases. 421 422 #### EgressMTLS Merging Behavior 423 424 A VirtualServer/VirtualServerRoute can reference multiple EgressMTLS policies. However, only one can be applied. Every subsequent reference will be ignored. For example, here we reference two policies: 425 ```yaml 426 policies: 427 - name: egress-mtls-policy-one 428 - name: egress-mtls-policy-two 429 ``` 430 In this example the Ingress Controller will use the configuration from the first policy reference `egress-mtls-policy-one`, and ignores `egress-mtls-policy-two`. 431 432 ### OIDC 433 434 > **Feature Status**: OIDC is available as a preview feature: it is suitable for experimenting and testing; however, it must be used with caution in production environments. Additionally, while the feature is in preview status, we might introduce some backward-incompatible changes to the resource specification in the next releases. The feature is disabled by default. To enable it, set the [enable-preview-policies](/nginx-ingress-controller/configuration/global-configuration/command-line-arguments/#cmdoption-enable-preview-policies) command-line argument of the Ingress Controller. 435 436 The OIDC policy configures NGINX Plus as a relying party for OpenID Connect authentication. 437 438 For example, the following policy will use the client ID `nginx-plus` and the client secret `oidc-secret` to authenticate with the OpenID Connect provider `https://idp.example.com`: 439 ```yaml 440 spec: 441 oidc: 442 clientID: nginx-plus 443 clientSecret: oidc-secret 444 authEndpoint: https://idp.example.com/openid-connect/auth 445 tokenEndpoint: https://idp.example.com/openid-connect/token 446 jwksURI: https://idp.example.com/openid-connect/certs 447 ``` 448 449 NGINX Plus will pass the ID of an authenticated user to the backend in the HTTP header `username`. 450 451 > Note: The feature is implemented using the [reference implementation](https://github.com/nginxinc/nginx-openid-connect/) of NGINX Plus as a relying party for OpenID Connect authentication. 452 453 #### Prerequisites 454 455 For the OIDC feature to work, it is necessary to enable [zone synchronization](https://docs.nginx.com/nginx/admin-guide/high-availability/zone_sync/), otherwise NGINX Plus will fail to reload. Additionally, it is necessary to configure a resolver, so that NGINX Plus can resolve the IDP authorization endpoint. For an example of the necessary configuration see the documentation [here](https://github.com/nginxinc/kubernetes-ingress/blob/v1.12.5/examples-of-custom-resources/oidc#step-7---configure-nginx-plus-zone-synchronization-and-resolver). 456 457 > **Note**: The configuration in the example doesn't enable TLS and the synchronization between the replica happens in clear text. This could lead to the exposure of tokens. 458 459 #### Limitations 460 461 The OIDC policy defines a few internal locations that can't be customized: `/_jwks_uri`, `/_token`, `/_refresh`, `/_id_token_validation`, `/logout`, `/_logout`. In addition, as explained below `/_codexch` is the default value for redirect URI, but can be customized. Specifying one of these locations as a route in the VirtualServer or VirtualServerRoute will result in a collision and NGINX Plus will fail to reload. 462 463 ```eval_rst 464 .. list-table:: 465 :header-rows: 1 466 467 * - Field 468 - Description 469 - Type 470 - Required 471 * - ``clientID`` 472 - The client ID provided by your OpenID Connect provider. 473 - ``string`` 474 - Yes 475 * - ``clientSecret`` 476 - The name of the Kubernetes secret that stores the client secret provided by your OpenID Connect provider. It must be in the same namespace as the Policy resource. The secret must be of the type ``nginx.org/oidc``, and the secret under the key ``client-secret``, otherwise the secret will be rejected as invalid. 477 - ``string`` 478 - Yes 479 * - ``authEndpoint`` 480 - URL for the authorization endpoint provided by your OpenID Connect provider. 481 - ``string`` 482 - Yes 483 * - ``tokenEndpoint`` 484 - URL for the token endpoint provided by your OpenID Connect provider. 485 - ``string`` 486 - Yes 487 * - ``jwksURI`` 488 - URL for the JSON Web Key Set (JWK) document provided by your OpenID Connect provider. 489 - ``string`` 490 - Yes 491 * - ``scope`` 492 - List of OpenID Connect scopes. Possible values are ``openid``, ``profile``, ``email``, ``address` and ``phone``. The scope ``openid`` always needs to be present and others can be added concatenating them with a ``+`` sign, for example ``openid+profile+email``. The default is ``openid``. 493 - ``string`` 494 - No 495 * - ``redirectURI`` 496 - Allows overriding the default redirect URI. The default is ``/_codexch``. 497 - ``string`` 498 - No 499 ``` 500 501 > **Note**: Only one OIDC policy can be referenced in a VirtualServer and its VirtualServerRoutes. However, the same policy can still be applied to different routes in the VirtualServer and VirtualServerRoutes. 502 503 #### OIDC Merging Behavior 504 505 A VirtualServer/VirtualServerRoute can reference only a single OIDC policy. Every subsequent reference will be ignored. For example, here we reference two policies: 506 ```yaml 507 policies: 508 - name: oidc-policy-one 509 - name: oidc-policy-two 510 ``` 511 In this example the Ingress Controller will use the configuration from the first policy reference `oidc-policy-one`, and ignores `oidc-policy-two`. 512 513 ## Using Policy 514 515 You can use the usual `kubectl` commands to work with Policy resources, just as with built-in Kubernetes resources. 516 517 For example, the following command creates a Policy resource defined in `access-control-policy-allow.yaml` with the name `webapp-policy`: 518 ``` 519 $ kubectl apply -f access-control-policy-allow.yaml 520 policy.k8s.nginx.org/webapp-policy configured 521 ``` 522 523 You can get the resource by running: 524 ``` 525 $ kubectl get policy webapp-policy 526 NAME AGE 527 webapp-policy 27m 528 ``` 529 530 For `kubectl get` and similar commands, you can also use the short name `pol` instead of `policy`. 531 532 ### WAF 533 534 > **Feature Status**: WAF is available as a preview feature: it is suitable for experimenting and testing; however, it must be used with caution in production environments. Additionally, while the feature is in preview status, we might introduce some backward-incompatible changes to the resource specification in the next releases. The feature is disabled by default. To enable it, set the [enable-preview-policies](/nginx-ingress-controller/configuration/global-configuration/command-line-arguments/#cmdoption-enable-preview-policies) command-line argument of the Ingress Controller. 535 536 > Note: This feature is only available in NGINX Plus with AppProtect. 537 538 The WAF policy configures NGINX Plus to secure client requests using App Protect policies. 539 540 For example, the following policy will enable the referenced APPolicy and APLogConf with the configured log destination: 541 ```yaml 542 waf: 543 enable: true 544 apPolicy: "default/dataguard-alarm" 545 securityLog: 546 enable: true 547 apLogConf: "default/logconf" 548 logDest: "syslog:server=127.0.0.1:514" 549 ``` 550 551 > Note: The feature is implemented using the NGINX Plus [NGINX App Protect Module](https://docs.nginx.com/nginx-app-protect/configuration/). 552 553 ```eval_rst 554 .. list-table:: 555 :header-rows: 1 556 557 * - Field 558 - Description 559 - Type 560 - Required 561 * - ``enable`` 562 - Enables NGINX App Protect. 563 - ``bool`` 564 - Yes 565 * - ``apPolicy`` 566 - The `App Protect policy </nginx-ingress-controller/app-protect/configuration/#app-protect-policies/>`_ of the WAF. Accepts an optional namespace. 567 - ``string`` 568 - No 569 * - ``securityLog.enable`` 570 - Enables security log. 571 - ``bool`` 572 - No 573 * - ``securityLog.apLogConf`` 574 - The `App Protect log conf </nginx-ingress-controller/app-protect/configuration/#app-protect-logs>`_ resource. Accepts an optional namespace. 575 - ``string`` 576 - No 577 * - ``securityLog.logDest`` 578 - The log destination for the security log. Accepted variables are ``syslog:server=<ip-address | localhost>:<port>``, ``stderr``, ``<absolute path to file>``. Default is ``"syslog:server=127.0.0.1:514"``. 579 - ``string`` 580 - No 581 ``` 582 583 #### WAF Merging Behavior 584 585 A VirtualServer/VirtualServerRoute can reference multiple WAF policies. However, only one can be applied. Every subsequent reference will be ignored. For example, here we reference two policies: 586 ```yaml 587 policies: 588 - name: waf-policy-one 589 - name: waf-policy-two 590 ``` 591 In this example the Ingress Controller will use the configuration from the first policy reference `waf-policy-one`, and ignores `waf-policy-two`. 592 593 ### Applying Policies 594 595 You can apply policies to both VirtualServer and VirtualServerRoute resources. For example: 596 * VirtualServer: 597 ```yaml 598 apiVersion: k8s.nginx.org/v1 599 kind: VirtualServer 600 metadata: 601 name: cafe 602 namespace: cafe 603 spec: 604 host: cafe.example.com 605 tls: 606 secret: cafe-secret 607 policies: # spec policies 608 - policy1 609 upstreams: 610 - name: coffee 611 service: coffee-svc 612 port: 80 613 routes: 614 - path: /tea 615 policies: # route policies 616 - name: policy2 617 namespace: cafe 618 route: tea/tea 619 - path: /coffee 620 policies: # route policies 621 - name: policy3 622 namespace: cafe 623 action: 624 pass: coffee 625 ``` 626 627 For VirtualServer, you can apply a policy: 628 - to all routes (spec policies) 629 - to a specific route (route policies) 630 631 Route policies of the *same type* override spec policies. In the example above, if the type of the policies `policy-1` and `policy-3` is `accessControl`, then for requests to `cafe.example.com/coffee`, NGINX will apply `policy-3`. 632 633 The overriding is enforced by NGINX: the spec policies are implemented in the `server` context of the config, and the route policies are implemented in the `location` context. As a result, the route policies of the same type win. 634 * VirtualServerRoute, which is referenced by the VirtualServer above: 635 ```yaml 636 apiVersion: k8s.nginx.org/v1 637 kind: VirtualServerRoute 638 metadata: 639 name: tea 640 namespace: tea 641 spec: 642 host: cafe.example.com 643 upstreams: 644 - name: tea 645 service: tea-svc 646 port: 80 647 subroutes: # subroute policies 648 - path: /tea 649 policies: 650 - name: policy4 651 namespace: tea 652 action: 653 pass: tea 654 ``` 655 656 For VirtualServerRoute, you can apply a policy to a subroute (subroute policies). 657 658 Subroute policies of the same type override spec policies. In the example above, if the type of the policies `policy-1` (in the VirtualServer) and `policy-4` is `accessControl`, then for requests to `cafe.example.com/tea`, NGINX will apply `policy-4`. As with the VirtualServer, the overriding is enforced by NGINX. 659 660 Subroute policies always override route policies no matter the types. For example, the policy `policy-2` in the VirtualServer route will be ignored for the subroute `/tea`, because the subroute has its own policies (in our case, only one policy `policy4`). If the subroute didn't have any policies, then the `policy-2` would be applied. This overriding is enforced by the Ingress Controller -- the `location` context for the subroute will either have route policies or subroute policies, but not both. 661 662 ### Invalid Policies 663 664 NGINX will treat a policy as invalid if one of the following conditions is met: 665 * The policy doesn't pass the [comprehensive validation](#comprehensive-validation). 666 * The policy isn't present in the cluster. 667 * The policy doesn't meet its type-specific requirements. For example, an `ingressMTLS` policy requires TLS termination enabled in the VirtualServer. 668 669 670 For an invalid policy, NGINX returns the 500 status code for client requests with the following rules: 671 * If a policy is referenced in a VirtualServer `route` or a VirtualServerRoute `subroute`, then NGINX will return the 500 status code for requests for the URIs of that route/subroute. 672 * If a policy is referenced in the VirtualServer `spec`, then NGINX will return the 500 status code for requests for all URIs of that VirtualServer. 673 674 If a policy is invalid, the VirtualServer or VirtualServerRoute will have the [status](/nginx-ingress-controller/configuration/global-configuration/reporting-resources-status#virtualserver-and-virtualserverroute-resources) with the state `Warning` and the message explaining why the policy wasn't considered invalid. 675 676 ### Validation 677 678 Two types of validation are available for the Policy resource: 679 * *Structural validation*, done by `kubectl` and the Kubernetes API server. 680 * *Comprehensive validation*, done by the Ingress Controller. 681 682 #### Structural Validation 683 684 The custom resource definition for the Policy includes a structural OpenAPI schema, which describes the type of every field of the resource. 685 686 If you try to create (or update) a resource that violates the structural schema -- for example, the resource uses a string value instead of an array of strings in the `allow` field -- `kubectl` and the Kubernetes API server will reject the resource. 687 * Example of `kubectl` validation: 688 ``` 689 $ kubectl apply -f access-control-policy-allow.yaml 690 error: error validating "access-control-policy-allow.yaml": error validating data: ValidationError(Policy.spec.accessControl.allow): invalid type for org.nginx.k8s.v1.Policy.spec.accessControl.allow: got "string", expected "array"; if you choose to ignore these errors, turn validation off with --validate=false 691 ``` 692 * Example of Kubernetes API server validation: 693 ``` 694 $ kubectl apply -f access-control-policy-allow.yaml --validate=false 695 The Policy "webapp-policy" is invalid: spec.accessControl.allow: Invalid value: "string": spec.accessControl.allow in body must be of type array: "string" 696 ``` 697 698 If a resource passes structural validation, then the Ingress Controller's comprehensive validation runs. 699 700 #### Comprehensive Validation 701 702 The Ingress Controller validates the fields of a Policy resource. If a resource is invalid, the Ingress Controller will reject it. The resource will continue to exist in the cluster, but the Ingress Controller will ignore it. 703 704 You can use `kubectl` to check whether or not the Ingress Controller successfully applied a Policy configuration. For our example `webapp-policy` Policy, we can run: 705 ``` 706 $ kubectl describe pol webapp-policy 707 . . . 708 Events: 709 Type Reason Age From Message 710 ---- ------ ---- ---- ------- 711 Normal AddedOrUpdated 11s nginx-ingress-controller Policy default/webapp-policy was added or updated 712 ``` 713 Note how the events section includes a Normal event with the AddedOrUpdated reason that informs us that the configuration was successfully applied. 714 715 If you create an invalid resource, the Ingress Controller will reject it and emit a Rejected event. For example, if you create a Policy `webapp-policy` with an invalid IP `10.0.0.` in the `allow` field, you will get: 716 ``` 717 $ kubectl describe policy webapp-policy 718 . . . 719 Events: 720 Type Reason Age From Message 721 ---- ------ ---- ---- ------- 722 Warning Rejected 7s nginx-ingress-controller Policy default/webapp-policy is invalid and was rejected: spec.accessControl.allow[0]: Invalid value: "10.0.0.": must be a CIDR or IP 723 ``` 724 Note how the events section includes a Warning event with the Rejected reason. 725 726 Additionally, this information is also available in the `status` field of the Policy resource. Note the Status section of the Policy: 727 728 ``` 729 $ kubectl describe pol webapp-policy 730 . . . 731 Status: 732 Message: Policy default/webapp-policy is invalid and was rejected: spec.accessControl.allow[0]: Invalid value: "10.0.0.": must be a CIDR or IP 733 Reason: Rejected 734 State: Invalid 735 ``` 736 737 **Note**: If you make an existing resource invalid, the Ingress Controller will reject it.