You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/proposals/authentication-filter.md
+59-62Lines changed: 59 additions & 62 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -14,7 +14,7 @@ This new filter should eventually expose all forms of authentication available t
14
14
- Design Authentication CRD with Basic Auth and JWT Auth in mind
15
15
- Determine initial resource specification
16
16
- Evaluate filter early in request processing, occurring before URLRewrite, header modifiers and backend selection
17
-
- Authentication failures returns 401 Unauthorized by default
17
+
- Authentication failures return 401 Unauthorized by default
18
18
- Ensure response codes are configurable
19
19
20
20
## Non-Goals
@@ -25,9 +25,9 @@ This new filter should eventually expose all forms of authentication available t
25
25
26
26
## Introduction
27
27
28
-
This document focuses explicitly on Authentication (AuthN) and not Authorization (AuthZ). Authentication (AuthN) defines the verification of identity. It asks the question, "Who are you?". This is different from Authorization (AuthZ), which preceeds Authentication. It asks the question, "What are you allowed to do".
28
+
This document focuses explicitly on Authentication (AuthN) and not Authorization (AuthZ). Authentication (AuthN) defines the verification of identity. It asks the question, "Who are you?". This is different from Authorization (AuthZ), which follows Authentication. It asks the question, "What are you allowed to do?"
29
29
30
-
This document also focus on HTTP Basic Authentication and JWT Authentication. Other authentication methods such as OpenID Connect (OIDC) are mentioned, but are not part of the CRD design. These will be covered in future design and implementation tasks.
30
+
This document also focuses on HTTP Basic Authentication and JWT Authentication. Other authentication methods such as OpenID Connect (OIDC) are mentioned, but are not part of the CRD design. These will be covered in future design and implementation tasks.
31
31
32
32
33
33
## Use Cases
@@ -68,7 +68,7 @@ This portion also contains:
68
68
- Example HTTPRoutes and NGINX configuration
69
69
3. Example spec for JWT Auth
70
70
- Example HTTPRoutes
71
-
- Examples for Local & Remote JWKS configration
71
+
- Examples for Local & Remote JWKS configuration
72
72
- Example NGINX configuration for both Local & Remote JWKS
73
73
- Example of additional optional fields
74
74
@@ -80,7 +80,7 @@ Below is the Golang API for the `AuthenticationFilter` API:
These are some directives the `Remote` mode uses over the `File` mode:
652
652
653
-
- `auth_jwt_key_request`: When using the `Remote` mode, this is used in place of `auth_jwt_key_file`. This will call the `internal` NGINX location `/_ngf-internal_jwks_uri` to redirect the request to the external auth provider (e.g. KeyCloak)
654
-
- `proxy_cache_path`: This is used to configuring caching of the JWKS after an initial request allowing subsequent requests to not request re-authenticaiton for a time
653
+
- `auth_jwt_key_request`: When using the `Remote` mode, this is used in place of `auth_jwt_key_file`. This will call the `internal` NGINX location `/_ngf-internal_jwks_uri` to redirect the request to the external auth provider (e.g. Keycloak)
654
+
- `proxy_cache_path`: This is used to configure caching of the JWKS after an initial request, allowing subsequent requests to avoid re-authentication for a time
655
655
656
656
```nginx
657
657
http {
@@ -753,8 +753,8 @@ spec:
753
753
754
754
### Attachment
755
755
756
-
Filters must be attached to a HTTPRoute at the `rules.matches` level.
757
-
This means that a single `AuthenticationFilter` may be attached mutliple times to a single HTTPRoute.
756
+
Filters must be attached to an HTTPRoute at the `rules.matches` level.
757
+
This means that a single `AuthenticationFilter` may be attached multiple times to a single HTTPRoute.
758
758
759
759
#### Basic example
760
760
@@ -766,10 +766,10 @@ This example shows a single HTTPRoute, with a single `filter` defined in a `rule
766
766
767
767
#### Referencing multiple AuthenticationFilter resources in a single rule
768
768
769
-
Only a single `AuthenticationFilter` may be referened in a single rule.
769
+
Only a single `AuthenticationFilter` may be referenced in a single rule.
770
770
771
-
The `Status` the HTTPRoute/GRPCRoute in this scenario should be set to `Invalid`, and the resource should be `Rejected`.
772
-
In this scenario, the route rule that is referencing multiple `AuthenticationFilter` resources will be `Rejected`/
771
+
The Status of the HTTPRoute/GRPCRoute in this scenario should be set to `Invalid`, and the resource should be `Rejected`.
772
+
In this scenario, the route rule that is referencing multiple `AuthenticationFilter` resources will be `Rejected`.
773
773
All other route rules will remain working.
774
774
775
775
The HTTPRoute/GRPCRoute resource will display an `UnresolvedRef` message to inform the user that the rule has been `Rejected`.
@@ -812,7 +812,7 @@ spec:
812
812
#### Referencing an AuthenticationFilter resource that is invalid
813
813
814
814
Note: With appropriate use of CEL validation, we are less likely to encounter a scenario where an AuthenticationFilter has been deployed to the cluster with an invalid configuration.
815
-
If this does happen, and a route rule references this AuthenticationFilter, the route rule will be set to `Invalid` and the the HTTPRoute/GRPCRoute will display the `UnresolvedRef` status.
815
+
If this does happen, and a route rule references this AuthenticationFilter, the route rule will be set to `Invalid` and the HTTPRoute/GRPCRoute will display the `UnresolvedRef` status.
816
816
817
817
#### Attaching a JWT AuthenticationFilter to a route when using NGINX OSS
818
818
@@ -836,13 +836,13 @@ For a filter to be considered "resolved", it must:
836
836
Invalid resolved filter scenarios:
837
837
838
838
- Resolved filter that references a secret that does not exist
839
-
- Resolved filter that referenced a secret with the incorrect data key
839
+
- Resolved filter that references a secret with the incorrect data key
840
840
841
841
Valid reference scenarios:
842
842
843
843
- Resolved filter referenced by a single route rule within a single HTTP/GRPCRoute
844
844
- Resolved filter referenced by multiple route rules within a single HTTP/GRPCRoute
845
-
- Resolved filter reference by multiple HTTP/GRPCRoutes
845
+
- Resolved filter referenced by multiple HTTP/GRPCRoutes
846
846
847
847
Invalid reference scenarios:
848
848
@@ -871,12 +871,12 @@ Proxy cache TTL should be configurable and set to a reasonable default, reducing
871
871
872
872
### Key rotation
873
873
874
-
Users should be advised to regularly rotate their JWKS keys in cases where they chose to reference a local JWKS via a `secrefRef`
874
+
Users should be advised to regularly rotate their JWKS keys in cases where they choose to reference a local JWKS via a `secretRef`.
875
875
876
876
### Optional headers
877
877
878
-
Below are a list of optional defensive headers that user's may choose to include.
879
-
In certain scenarios, these headers may be deployed to improve overall security from client reponses.
878
+
Below are a list of optional defensive headers that users may choose to include.
879
+
In certain scenarios, these headers may be deployed to improve overall security from client responses.
- This header explicitly set the body as plain text. This prevents browsers from treating the response as HTML or JavaScript, and is effective at mitigating Cross-side scrpting (XSS) through error pages
890
+
- This header explicitly sets the body as plain text. This prevents browsers from treating the response as HTML or JavaScript, and is effective at mitigating Cross-site scripting (XSS) through error pages
891
891
892
892
- X-Content-Type-Options: "nosniff"
893
-
- This header prevents content type confusion. This occurrs when browsers guesses HTML & JavaScript, and executes it despite a benign type.
893
+
- This header prevents content type confusion. This occurs when browsers guess HTML and JavaScript, and execute it despite a benign type.
894
894
895
895
- Cache-Control: "no-store"
896
-
- This header informs browsers and proxies not to cache the response. Avoids sensitive, auth-related content, from being being stored and served later to unintended recipients.
896
+
- This header informs browsers and proxies not to cache the response. Avoids sensitive, auth-related content from being stored and served later to unintended recipients.
897
897
898
898
899
899
### Validation
900
900
901
-
When referencing an `AuthenticationFilter` in either a HTTPRoute or GRPCRoute, it is important that we ensure all configurable fields are validated, and that the resulting NGINX configuration is correct and secure.
901
+
When referencing an `AuthenticationFilter` in either an HTTPRoute or GRPCRoute, it is important that we ensure all configurable fields are validated, and that the resulting NGINX configuration is correct and secure.
902
902
903
-
All fields in the `AuthenticationFilter` will be validated with Open API Schema.
903
+
All fields in the `AuthenticationFilter` will be validated with OpenAPI Schema.
904
904
We should also include [CEL](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation-rules) validation where required.
905
905
906
-
We should validated that only one `AuthenticationFilter` is referenced per-rule. Multiple references to an `AuthenticationFilter` in a single rule should result in an `Invalid` HTTPRoute/GRPCRoute, and the rule should be `Rejected`.
906
+
We should validate that only one `AuthenticationFilter` is referenced per-rule. Multiple references to an `AuthenticationFilter` in a single rule should result in an `Invalid` HTTPRoute/GRPCRoute, and the rule should be `Rejected`.
907
907
908
908
This scenario can use the status `RouteConditionPartiallyInvalid` defined in the Gateway API here: https://github.com/nginx/nginx-gateway-fabric/blob/3934c5c8c60b5aea91be4337d63d4e1d8640baa8/internal/controller/state/conditions/conditions.go#L402
909
909
910
910
## Alternatives
911
911
912
912
The Gateway API defines a means to standardise authentication through use of the [HTTPExternalAuthFilter](https://gateway-api.sigs.k8s.io/reference/spec/#httpexternalauthfilter) available in the HTTPRoute specification.
913
913
914
-
This allows users to reference an external authentication services, such as Keycloak, to handle the authentication requests.
914
+
This allows users to reference an external authentication service, such as Keycloak, to handle the authentication requests.
915
915
While this API is available in the experimental channel, it is subject to change.
916
916
917
917
Our decision to go forward with our own `AuthenticationFilter` was to ensure we could quickly provide authentication to our users while allowing us to closely monitor progress of the ExternalAuthFilter.
918
918
919
-
It is certainly possible for us to provide an External Authentication Services that leverages NGINX and is something we can further investigate as the API progresses.
919
+
It is certainly possible for us to provide an External Authentication Service that leverages NGINX and is something we can further investigate as the API progresses.
920
920
921
921
## Additional considerations
922
922
923
-
### Documenting filter behavour
923
+
### Documenting filter behavior
924
924
925
-
In regards to documentation of filter behaviour with the `AuthenticationFilter`, the Gateway API documentation on filters states the following:
925
+
In regards to documentation of filter behavior with the `AuthenticationFilter`, the Gateway API documentation on filters states the following:
926
926
927
927
```text
928
928
Wherever possible, implementations SHOULD implement filters in the order they are specified.
@@ -935,10 +935,10 @@ document that behavior.
935
935
936
936
## Stretch Goals
937
937
938
-
### Custom authentiation failure response
938
+
### Custom authentication failure response
939
939
940
940
By default, authentication failures return a 401 response.
941
-
If a used wanted to change this response code, or include additioanl headers in this response, we can include a custom named location that can be called by the [error_page](https://nginx.org/en/docs/http/ngx_http_core_module.html#error_page) directive.
941
+
If a user wanted to change this response code, or include additional headers in this response, we can include a custom named location that can be called by the [error_page](https://nginx.org/en/docs/http/ngx_http_core_module.html#error_page) directive.
942
942
943
943
Example AuthenticationFilter configuration:
944
944
@@ -977,15 +977,15 @@ server{
977
977
}
978
978
```
979
979
980
-
If we support this configuration, 3xx response codes should not be allowed and AuthenticationFilter.onFailure must not support redirect targets. This is to prevent to prevent open-redirect abuse.
980
+
If we support this configuration, 3xx response codes should not be allowed and AuthenticationFilter.onFailure must not support redirect targets. This is to prevent open-redirect abuse.
981
981
982
982
We should only allow 401 and 403 response codes.
983
983
984
984
### Cross namespace access
985
985
986
986
When referencing secrets for Basic Auth and JWT Auth, the initial implementation will use `LocalObjectReference`.
987
987
988
-
Future updates to this will use the `NamespacedSecretKeyReference` in conjunction with `ReferenceGrants` to support access to secrets in different namespace`
988
+
Future updates to this will use the `NamespacedSecretKeyReference` in conjunction with `ReferenceGrants` to support access to secrets in different namespaces.
989
989
990
990
Struct for `NamespacedSecretKeyReference`:
991
991
@@ -1001,9 +1001,8 @@ type NamespacedSecretKeyReference struct {
1001
1001
}
1002
1002
```
1003
1003
1004
-
For initial implementaion, both Basic Auth and Local JWKS should will only have access to Secrets in the same namespace.
1004
+
For the initial implementation, both Basic Auth and Local JWKS will only have access to Secrets in the same namespace.
1005
1005
1006
-
Example: Grant BasicAuth in app-ns to read a Secret in security-ns
1007
1006
Example: Grant BasicAuth in app-ns to read a Secret in security-ns
1008
1007
1009
1008
```yaml
@@ -1023,7 +1022,6 @@ spec:
1023
1022
name: basic-auth-users
1024
1023
```
1025
1024
1026
-
AuthenticationFilter referencing the cross-namespace Secret
1027
1025
AuthenticationFilter referencing the cross-namespace Secret
1028
1026
1029
1027
```yaml
@@ -1043,10 +1041,9 @@ spec:
1043
1041
1044
1042
### Additional Fields for JWT
1045
1043
1046
-
`require`, `tokenSource` and `propagation` are some additional fields that may be incldued in future updates to the API.
1044
+
`require`, `tokenSource` and `propagation` are some additional fields that may be included in future updates to the API.
1047
1045
These fields allow for more customization of how the JWT auth behaves, but aren't required for the minimal delivery of JWT Auth.
1048
1046
1049
-
Example of what implementation of these fields might look like:
1050
1047
Example of what implementation of these fields might look like:
1051
1048
1052
1049
```yaml
@@ -1073,7 +1070,7 @@ spec:
1073
1070
- "cli"
1074
1071
1075
1072
# Where client presents the token
1076
-
# By defaults to reading from Authorization header (Bearer)
1073
+
# By default, reading from Authorization header (Bearer)
1077
1074
tokenSource:
1078
1075
type: Header
1079
1076
# Alternative: read from a cookie named tokenName
@@ -1194,7 +1191,7 @@ type HeaderValue struct {
1194
1191
1195
1192
-[Gateway API ExternalAuthFilter GEP](https://gateway-api.sigs.k8s.io/geps/gep-1494/)
-[Kubernetes documentation on CEL validaton](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation-rules)
1194
+
-[Kubernetes documentation on CEL validation](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation-rules)
0 commit comments