From 9a6ed419c25205e0a1c6fcc0b0af52599d8b8538 Mon Sep 17 00:00:00 2001 From: Lizan Zhou Date: Sun, 9 Oct 2022 08:34:35 +0000 Subject: [PATCH 01/16] Add authn policy design with JWT only Signed-off-by: Lizan Zhou --- docs/design/authentication_policy.md | 40 ++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 docs/design/authentication_policy.md diff --git a/docs/design/authentication_policy.md b/docs/design/authentication_policy.md new file mode 100644 index 0000000000..db2d87336e --- /dev/null +++ b/docs/design/authentication_policy.md @@ -0,0 +1,40 @@ +# Envoy Gateway Authentication Policy API + +## Overview + +This authen policy is to declare the authentication mechanisms, to be enforce on connection and request going though Envoy Gateway. This includes the credential (X.509, JWT, etc), parameters (cipher suites, key algorithms) +The policy is similar to [OpenAPI 3.1 security objects](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#securitySchemeObject) without the API key part, and should be easily translatable from it with some additions. + +## Authentication mechanisms +This policy should support the following authentication mechanisms: +- JWT Bearer Token +- mutualTLS (client certificate) +- OAuth2 +- OIDC +- External authentication + +In the first phase, Envoy Gateway will implement JWT Bearer Token authentication. + +In general those policy translates into Envoy HTTP filters at HTTP connection manager level, and route specific settings will be applied for each route. These APIs are expressed in a Policy CRD and attached to Gateway API resources with [Policy Attachement](https://gateway-api.sigs.k8s.io/references/policy-attachment/). + +## JWT Bearer Token + +A JWT Bearer Token authentication policy will look like the following: + +``` +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: Authentication +metadata: + name: productpage +spec: + type: jwt + jwt: + iss: https://www.okta.com + aud: bookinfo.com + jwksUri: https://bookinfo.com/jwt/public-key/jwks.json + targetRef: + kind: HTTPRoute + name: httpbin +``` + +JWT Bearer token will be translate to Envoy's JWT authentication filter. The JWKS URI need to be translated to a separate cluster for JWKS fetch and refersh. From b5c4755ca6134e763cd577450861e615ccaf3412 Mon Sep 17 00:00:00 2001 From: Lizan Zhou Date: Wed, 2 Nov 2022 10:45:07 -0700 Subject: [PATCH 02/16] Update docs/design/authentication_policy.md Co-authored-by: Arko Dasgupta Signed-off-by: Lizan Zhou --- docs/design/authentication_policy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/design/authentication_policy.md b/docs/design/authentication_policy.md index db2d87336e..65d8c72bfc 100644 --- a/docs/design/authentication_policy.md +++ b/docs/design/authentication_policy.md @@ -2,7 +2,7 @@ ## Overview -This authen policy is to declare the authentication mechanisms, to be enforce on connection and request going though Envoy Gateway. This includes the credential (X.509, JWT, etc), parameters (cipher suites, key algorithms) +This authentication policy declares the authentication mechanisms, to be enforced on connection and request going though Envoy Gateway. This includes the credential (X.509, JWT, etc), parameters (cipher suites, key algorithms) The policy is similar to [OpenAPI 3.1 security objects](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#securitySchemeObject) without the API key part, and should be easily translatable from it with some additions. ## Authentication mechanisms From 3cb97e12ea99d1efd4621e84c36a06ed8937e3e7 Mon Sep 17 00:00:00 2001 From: Lizan Zhou Date: Wed, 2 Nov 2022 10:45:13 -0700 Subject: [PATCH 03/16] Update docs/design/authentication_policy.md Co-authored-by: Arko Dasgupta Signed-off-by: Lizan Zhou --- docs/design/authentication_policy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/design/authentication_policy.md b/docs/design/authentication_policy.md index 65d8c72bfc..5a8d072b9e 100644 --- a/docs/design/authentication_policy.md +++ b/docs/design/authentication_policy.md @@ -37,4 +37,4 @@ spec: name: httpbin ``` -JWT Bearer token will be translate to Envoy's JWT authentication filter. The JWKS URI need to be translated to a separate cluster for JWKS fetch and refersh. +JWT Bearer token will be translate to Envoy's JWT authentication filter. The JWKS URI need to be translated to a separate cluster for JWKS fetch and refresh. From 69bd6e4fe9601f63cdfc8540f6389f5026ad05bf Mon Sep 17 00:00:00 2001 From: danehans Date: Thu, 3 Nov 2022 08:27:01 -0700 Subject: [PATCH 04/16] Refactors request auth design doc Signed-off-by: danehans --- docs/design/authentication_policy.md | 40 --- docs/design/request-authentication.md | 384 ++++++++++++++++++++++++++ 2 files changed, 384 insertions(+), 40 deletions(-) delete mode 100644 docs/design/authentication_policy.md create mode 100644 docs/design/request-authentication.md diff --git a/docs/design/authentication_policy.md b/docs/design/authentication_policy.md deleted file mode 100644 index 5a8d072b9e..0000000000 --- a/docs/design/authentication_policy.md +++ /dev/null @@ -1,40 +0,0 @@ -# Envoy Gateway Authentication Policy API - -## Overview - -This authentication policy declares the authentication mechanisms, to be enforced on connection and request going though Envoy Gateway. This includes the credential (X.509, JWT, etc), parameters (cipher suites, key algorithms) -The policy is similar to [OpenAPI 3.1 security objects](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#securitySchemeObject) without the API key part, and should be easily translatable from it with some additions. - -## Authentication mechanisms -This policy should support the following authentication mechanisms: -- JWT Bearer Token -- mutualTLS (client certificate) -- OAuth2 -- OIDC -- External authentication - -In the first phase, Envoy Gateway will implement JWT Bearer Token authentication. - -In general those policy translates into Envoy HTTP filters at HTTP connection manager level, and route specific settings will be applied for each route. These APIs are expressed in a Policy CRD and attached to Gateway API resources with [Policy Attachement](https://gateway-api.sigs.k8s.io/references/policy-attachment/). - -## JWT Bearer Token - -A JWT Bearer Token authentication policy will look like the following: - -``` -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: Authentication -metadata: - name: productpage -spec: - type: jwt - jwt: - iss: https://www.okta.com - aud: bookinfo.com - jwksUri: https://bookinfo.com/jwt/public-key/jwks.json - targetRef: - kind: HTTPRoute - name: httpbin -``` - -JWT Bearer token will be translate to Envoy's JWT authentication filter. The JWKS URI need to be translated to a separate cluster for JWKS fetch and refresh. diff --git a/docs/design/request-authentication.md b/docs/design/request-authentication.md new file mode 100644 index 0000000000..5acb9398e7 --- /dev/null +++ b/docs/design/request-authentication.md @@ -0,0 +1,384 @@ +# Request Authentication + +## Overview + +[Issue 336][] specifies the need for exposing a user-facing API to configure request authentication. Request +authentication is defined as an authentication mechanism to be enforced by Envoy on a per-request basis. A connection +will be rejected if it contains invalid authentication information, based on the `Authentication` API type proposed in +this design document. + +Envoy Gateway leverages [Gateway API][] for configuring managed Envoy proxies. Gateway API defines core, extended, and +implementation-specific API [support levels][] for implementors such as Envoy Gateway to expose features. Since +implementing request authentication is not covered by `Core` or `Extended` APIs, an `Implementation-specific` API will +be created for this purpose. + +## Goals + +* Define an API for configuring request authentication. +* Implement [JWT] as the first supported authentication type. +* Allow users that manage routes, e.g. [HTTPRoute][], to authenticate matching requests before forwarding to a backend + service. +* Support HTTPRoutes as an Authentication API referent. + +## Non-Goals + +* Allow infrastructure administrators to override or establish default authentication policies. +* Support referents other than HTTPRoute. + +## Use-Cases + +These use-cases are presented as an aid for how users may attempt to utilize the outputs of the design. They are not an +exhaustive list of features for authentication support in Envoy Gateway. + +As a Service Producer, I need the ability to: +* Authenticate a request before forwarding it to a backend service. +* Have different authentication mechanisms per route rule. +* Choose from different authentication mechanisms supported by Envoy, e.g. OIDC. + +### Security API Group + +A new API group, `security.gateway.envoyproxy.io` is introduced to group security-related APIs. This will allow security +APIs to be versioned, changed, etc. over time. + +### Authentication API Type + +The Authentication API type defines authentication configuration for authenticating requests through managed Envoy +proxies. + +```go +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + +) + +type Authentication struct { + metav1.TypeMeta + metav1.ObjectMeta + + // Spec defines the desired state of the Authentication type. + Spec AuthenticationSpec + + // Note: The status sub-resource has been excluded but may be added in the future. +} + +// AuthenticationSpec defines the desired state of the Authentication type. +// +union +type AuthenticationSpec struct { + // Type defines the type of authentication provider to use. Supported provider + // types are: + // + // * JWT + // + // JWT defines the JSON Web Token (JWT) authentication provider type. + // + // +unionDiscriminator + Type AuthenticationType `json:"type"` + + // JWT defines the JSON Web Token (JWT) authentication provider type. When multiple + // jwtProviders are specified, the JWT is considered valid if any of the providers + // successfully validate the JWT. For additional details, see: + // + // https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/jwt_authn_filter.html + // + // +kubebuilder:validation:MaxItems=4 + // +optional + JwtProviders []JwtAuthenticationProvider `json:"jwtProviders,omitempty"` +} + +// AuthenticationType is a type of authentication provider. +// +kubebuilder:validation:Enum=JWT +type AuthenticationType string + +const ( + // JwtAuthenticationProviderType is the JWT authentication provider type. + JwtAuthenticationProviderType AuthenticationType = "JWT" +) + +// JwtAuthenticationProvider defines the JSON Web Token (JWT) authentication provider type +// and how JWTs should be verified: +type JwtAuthenticationProvider struct { + // Name defines a unique name for the JWT provider. A name can have a variety of forms, + // including RFC1123 subdomains, RFC 1123 labels, or RFC 1035 labels. + // + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=253 + Name string `json:"name"` + + // Issuer is the principal that issued the JWT. For additional details, see: + // + // https://tools.ietf.org/html/rfc7519#section-4.1.1 + // + // Example: + // issuer: https://auth.example.com + // + // If not provided, the JWT issuer is not checked. + // + // +kubebuilder:validation:MaxLength=253 + // +optional + Issuer string `json:"issuer,omitempty"` + + // Audiences is a list of JWT audiences allowed to access. For additional details, see: + // + // https://tools.ietf.org/html/rfc7519#section-4.1.3 + // + // Example: + // audiences: + // - foo.apps.example.com + // bar.apps.example.com + // + // If not provided, JWT audiences are not checked. + // + // +kubebuilder:validation:MaxItems=8 + // +optional + Audiences []string `json:"audiences,omitempty"` + + // RemoteJWKS defines how to fetch and cache JSON Web Key Sets (JWKS) from a remote + // HTTP/HTTPS endpoint. + RemoteJWKS RemoteJWKS `json:"remoteJWKS"` + + // TODO: Add TBD JWT fields based on defined use cases. +} + +// RemoteJWKS defines how to fetch and cache JSON Web Key Sets (JWKS) from a remote +// HTTP/HTTPS endpoint. +type RemoteJWKS struct { + // Uri is the HTTP/HTTPS URI to fetch the JWKS. + // + // Example: + // uri: https://www.googleapis.com/oauth2/v1/certs + // + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=253 + Uri string `json:"uri"` + + // TODO: Add TBD remote JWKS fields based on defined use cases. +} +``` + +The status subresource is not included in the Authentication API. Status will be surfaced by an HTTPRoute that +references an Authentication. For example, an HTTPRoute will surface the `ResolvedRefs=False` status condition if it +references an Authentication that does not exist. It may be beneficial to add status fields in the future based on +defined use-cases. For example, a remote JWKS can be validated based on the specified URI and have an appropriate +status condition surfaced. + +The following is an example of a JWT authentication provider: + +```yaml +apiVersion: security.gateway.envoyproxy.io/v1alpha1 +kind: Authentication +metadata: + name: example-jwt +spec: + type: JWT + jwtProviders: + - name: example + issuer: https://www.example.com + audiences: + - foo.com + remoteJwks: + uri: https://foo.com/jwt/public-key/jwks.json + +status: + +``` + +The following is an example HTTPRoute configured to use the above JWT authentication provider: + +```yaml +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: example-hwt-authn +spec: + parentRefs: + - name: eg + hostnames: + - www.example.com + rules: + - matches: + - path: + type: PathPrefix + value: /foo + filters: + - type: ExtensionRef + extensionRef: + group: security.gateway.envoyproxy.io + kind: Authentication + name: example-jwt + backendRefs: + - name: httpbin + port: 80 +``` + +Requests for `www.example.com/foo` will be authenticated using the referenced JWT provider before being forwarded to the +`httpbin` backend service. + +## Implementation Details + +The JWT authentication type is translated to an Envoy [JWT authentication filter][] and a cluster is created for each +remote JWKS. The following cluster is created for the JWT provider defines in the above Authentication: + +```yaml +clusters: + - name: foo.com|443 + load_assignment: + cluster_name: foo.com|443 + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: foo.com + port_value: 443 + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + sni: foo.com + common_tls_context: + validation_context: + match_subject_alt_names: + - exact: "*.foo.com" + trusted_ca: + filename: /etc/ssl/certs/ca-certificates.crt +``` + +A JWT authentication HTTP filter is added to the HTTP Connection Manager. For example: + +```yaml +dynamic_resources: + dynamic_listeners: + - name: example_listener + address: + socket_address: + address: 1.2.3.4 + port_value: 80 + filter_chains: + - filters: + - name: envoy.http_connection_manager + http_filters: + - name: envoy.filters.http.jwt_authn + typed_config: + "@type": type.googleapis.com/envoy.config.filter.http.jwt_authn.v2alpha.JwtAuthentication +``` + +This JWT authentication filter contains two fields: +* The `providers` field specifies how a JWT should be verified, such as where to extract the token, where to fetch the + public key (JWKS) and where to output its payload. This field is built from `jwtProviders` of an Authentication. +* The `rules` field specifies matching rules and their requirements. If a request matches a rule, its requirement + applies. The requirement specifies which JWT providers should be used. This field is built from a HTTPRoute + `matches` rule that references the Authentication extended filter. When a referenced Authentication specifies + multiple `jwtProviders`, the JWT is considered valid if __any__ of the providers successfully validate the JWT. + +The following JWT Authentication filter `providers` configuration is created from the above Authentication. + +```yaml +providers: + example: + issuer: https://www.example.com + audiences: + - foo.com + remote_jwks: + http_uri: + uri: https://foo.com/jwt/public-key/jwks.json + cluster: example_jwks_cluster + timeout: 1s +``` + +The following JWT Authentication filter `rules` configuration is created from the above HTTPRoute. + +```yaml +rules: + - match: + prefix: /foo + requires: + provider_name: example +``` + +If the Authentication included a second JWT provider named `example`, the resulting JWT Authentication filter `rules` +would be created: + +```yaml +rules: +- match: + prefix: /foo + requires: + requires_any: + requirements: + - provider_name: example + - provider_name: example2 +``` + +### Implementation Outline + +* Create a `security` API group and add the Authentication API type to this group. +* Update the Kubernetes provider to get/watch Authentication resources that are referenced by managed HTTPRoutes. Add + the referenced Authentication object to the resource map and publish it. +* Update the resource translator to include the Authentication API in HTTPRoute processing. +* Update the xDS translator to translate an Authentication into xDS resources. The translator should perform the + following: + * Convert a list of JWT rules from the xds IR into an Envoy JWT filter config. + * Create a JWT authentication filter. + * Build the HTTP Connection Manager (MCM) HTTP filters. + * Build the HCM. + * When building the Listener, create an HCM for each filter-chain. + +## Adding Authentication Provider Types + +Additional authentication provider types can be added in the future through the `ProviderType` API. For example, to add +the `Foo` authentication provider type: + +Define the `FooProvider` type: + +```go +package v1alpha1 + +// FooProvider defines the "Foo" authentication provider type. +type FooProvider struct { + // TODO: Define fields of the Foo authentication provider type. +} +``` + +Add the `FooProvider` type to `AuthenticationSpec`: + +```go +package v1alpha1 + +type AuthenticationSpec struct { + ... + + // Foo defines the Foo authentication type. For additional + // details, see: + // + // + // + // +optional + Foo *FooAuthentication `json:"foo"` +} +``` + +Authentication should support additional authentication types in the future, for example: +- mutualTLS (client certificate) +- OAuth2 +- OIDC +- External authentication + +## Outstanding Questions + +- If Envoy Gateway owns the Authentication API, is an xDS IR equivalent needed? +- Should local JWKS be implemented before remote JWKS? +- How should Envoy obtain the trusted CA for a remote JWKS? +- Should HTTPS be the only supported scheme for remote JWKS? +- Should OR'ing JWT providers be supported? +- Should Authentication provide status? +- Are the API field validation rules acceptable? + +[Issue 336]: https://github.com/envoyproxy/gateway/issues/336 +[Gateway API]: https://gateway-api.sigs.k8s.io/ +[support levels]: https://gateway-api.sigs.k8s.io/concepts/conformance/?h=extended#2-support-levels +[JWT]: https://jwt.io/ +[HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute/ +[JWKS]: https://www.rfc-editor.org/rfc/rfc7517 +[JWT authentication filter]: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/jwt_authn_filter#config-http-filters-jwt-authn From 36e65c1ca2fd0c53d5c8cc30d8088689cd1e4d6b Mon Sep 17 00:00:00 2001 From: Lizan Zhou Date: Sun, 9 Oct 2022 08:34:35 +0000 Subject: [PATCH 05/16] Add authn policy design with JWT only Signed-off-by: Lizan Zhou --- docs/latest/design/authentication_policy.md | 40 +++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 docs/latest/design/authentication_policy.md diff --git a/docs/latest/design/authentication_policy.md b/docs/latest/design/authentication_policy.md new file mode 100644 index 0000000000..db2d87336e --- /dev/null +++ b/docs/latest/design/authentication_policy.md @@ -0,0 +1,40 @@ +# Envoy Gateway Authentication Policy API + +## Overview + +This authen policy is to declare the authentication mechanisms, to be enforce on connection and request going though Envoy Gateway. This includes the credential (X.509, JWT, etc), parameters (cipher suites, key algorithms) +The policy is similar to [OpenAPI 3.1 security objects](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#securitySchemeObject) without the API key part, and should be easily translatable from it with some additions. + +## Authentication mechanisms +This policy should support the following authentication mechanisms: +- JWT Bearer Token +- mutualTLS (client certificate) +- OAuth2 +- OIDC +- External authentication + +In the first phase, Envoy Gateway will implement JWT Bearer Token authentication. + +In general those policy translates into Envoy HTTP filters at HTTP connection manager level, and route specific settings will be applied for each route. These APIs are expressed in a Policy CRD and attached to Gateway API resources with [Policy Attachement](https://gateway-api.sigs.k8s.io/references/policy-attachment/). + +## JWT Bearer Token + +A JWT Bearer Token authentication policy will look like the following: + +``` +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: Authentication +metadata: + name: productpage +spec: + type: jwt + jwt: + iss: https://www.okta.com + aud: bookinfo.com + jwksUri: https://bookinfo.com/jwt/public-key/jwks.json + targetRef: + kind: HTTPRoute + name: httpbin +``` + +JWT Bearer token will be translate to Envoy's JWT authentication filter. The JWKS URI need to be translated to a separate cluster for JWKS fetch and refersh. From 12284786d871545723b45ee2797722b2e0612275 Mon Sep 17 00:00:00 2001 From: Lizan Zhou Date: Wed, 2 Nov 2022 10:45:07 -0700 Subject: [PATCH 06/16] Update docs/design/authentication_policy.md Co-authored-by: Arko Dasgupta Signed-off-by: Lizan Zhou --- docs/latest/design/authentication_policy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/latest/design/authentication_policy.md b/docs/latest/design/authentication_policy.md index db2d87336e..65d8c72bfc 100644 --- a/docs/latest/design/authentication_policy.md +++ b/docs/latest/design/authentication_policy.md @@ -2,7 +2,7 @@ ## Overview -This authen policy is to declare the authentication mechanisms, to be enforce on connection and request going though Envoy Gateway. This includes the credential (X.509, JWT, etc), parameters (cipher suites, key algorithms) +This authentication policy declares the authentication mechanisms, to be enforced on connection and request going though Envoy Gateway. This includes the credential (X.509, JWT, etc), parameters (cipher suites, key algorithms) The policy is similar to [OpenAPI 3.1 security objects](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#securitySchemeObject) without the API key part, and should be easily translatable from it with some additions. ## Authentication mechanisms From ba5b9b69e2208e2774f5f59b5608299678e9d7ba Mon Sep 17 00:00:00 2001 From: Lizan Zhou Date: Wed, 2 Nov 2022 10:45:13 -0700 Subject: [PATCH 07/16] Update docs/design/authentication_policy.md Co-authored-by: Arko Dasgupta Signed-off-by: Lizan Zhou --- docs/latest/design/authentication_policy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/latest/design/authentication_policy.md b/docs/latest/design/authentication_policy.md index 65d8c72bfc..5a8d072b9e 100644 --- a/docs/latest/design/authentication_policy.md +++ b/docs/latest/design/authentication_policy.md @@ -37,4 +37,4 @@ spec: name: httpbin ``` -JWT Bearer token will be translate to Envoy's JWT authentication filter. The JWKS URI need to be translated to a separate cluster for JWKS fetch and refersh. +JWT Bearer token will be translate to Envoy's JWT authentication filter. The JWKS URI need to be translated to a separate cluster for JWKS fetch and refresh. From 69923b3ec364bf4841b92e878b7f89db313a6b01 Mon Sep 17 00:00:00 2001 From: danehans Date: Thu, 3 Nov 2022 08:27:01 -0700 Subject: [PATCH 08/16] Refactors request auth design doc Signed-off-by: danehans --- docs/latest/design/request-authentication.md | 384 +++++++++++++++++++ 1 file changed, 384 insertions(+) create mode 100644 docs/latest/design/request-authentication.md diff --git a/docs/latest/design/request-authentication.md b/docs/latest/design/request-authentication.md new file mode 100644 index 0000000000..5acb9398e7 --- /dev/null +++ b/docs/latest/design/request-authentication.md @@ -0,0 +1,384 @@ +# Request Authentication + +## Overview + +[Issue 336][] specifies the need for exposing a user-facing API to configure request authentication. Request +authentication is defined as an authentication mechanism to be enforced by Envoy on a per-request basis. A connection +will be rejected if it contains invalid authentication information, based on the `Authentication` API type proposed in +this design document. + +Envoy Gateway leverages [Gateway API][] for configuring managed Envoy proxies. Gateway API defines core, extended, and +implementation-specific API [support levels][] for implementors such as Envoy Gateway to expose features. Since +implementing request authentication is not covered by `Core` or `Extended` APIs, an `Implementation-specific` API will +be created for this purpose. + +## Goals + +* Define an API for configuring request authentication. +* Implement [JWT] as the first supported authentication type. +* Allow users that manage routes, e.g. [HTTPRoute][], to authenticate matching requests before forwarding to a backend + service. +* Support HTTPRoutes as an Authentication API referent. + +## Non-Goals + +* Allow infrastructure administrators to override or establish default authentication policies. +* Support referents other than HTTPRoute. + +## Use-Cases + +These use-cases are presented as an aid for how users may attempt to utilize the outputs of the design. They are not an +exhaustive list of features for authentication support in Envoy Gateway. + +As a Service Producer, I need the ability to: +* Authenticate a request before forwarding it to a backend service. +* Have different authentication mechanisms per route rule. +* Choose from different authentication mechanisms supported by Envoy, e.g. OIDC. + +### Security API Group + +A new API group, `security.gateway.envoyproxy.io` is introduced to group security-related APIs. This will allow security +APIs to be versioned, changed, etc. over time. + +### Authentication API Type + +The Authentication API type defines authentication configuration for authenticating requests through managed Envoy +proxies. + +```go +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + +) + +type Authentication struct { + metav1.TypeMeta + metav1.ObjectMeta + + // Spec defines the desired state of the Authentication type. + Spec AuthenticationSpec + + // Note: The status sub-resource has been excluded but may be added in the future. +} + +// AuthenticationSpec defines the desired state of the Authentication type. +// +union +type AuthenticationSpec struct { + // Type defines the type of authentication provider to use. Supported provider + // types are: + // + // * JWT + // + // JWT defines the JSON Web Token (JWT) authentication provider type. + // + // +unionDiscriminator + Type AuthenticationType `json:"type"` + + // JWT defines the JSON Web Token (JWT) authentication provider type. When multiple + // jwtProviders are specified, the JWT is considered valid if any of the providers + // successfully validate the JWT. For additional details, see: + // + // https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/jwt_authn_filter.html + // + // +kubebuilder:validation:MaxItems=4 + // +optional + JwtProviders []JwtAuthenticationProvider `json:"jwtProviders,omitempty"` +} + +// AuthenticationType is a type of authentication provider. +// +kubebuilder:validation:Enum=JWT +type AuthenticationType string + +const ( + // JwtAuthenticationProviderType is the JWT authentication provider type. + JwtAuthenticationProviderType AuthenticationType = "JWT" +) + +// JwtAuthenticationProvider defines the JSON Web Token (JWT) authentication provider type +// and how JWTs should be verified: +type JwtAuthenticationProvider struct { + // Name defines a unique name for the JWT provider. A name can have a variety of forms, + // including RFC1123 subdomains, RFC 1123 labels, or RFC 1035 labels. + // + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=253 + Name string `json:"name"` + + // Issuer is the principal that issued the JWT. For additional details, see: + // + // https://tools.ietf.org/html/rfc7519#section-4.1.1 + // + // Example: + // issuer: https://auth.example.com + // + // If not provided, the JWT issuer is not checked. + // + // +kubebuilder:validation:MaxLength=253 + // +optional + Issuer string `json:"issuer,omitempty"` + + // Audiences is a list of JWT audiences allowed to access. For additional details, see: + // + // https://tools.ietf.org/html/rfc7519#section-4.1.3 + // + // Example: + // audiences: + // - foo.apps.example.com + // bar.apps.example.com + // + // If not provided, JWT audiences are not checked. + // + // +kubebuilder:validation:MaxItems=8 + // +optional + Audiences []string `json:"audiences,omitempty"` + + // RemoteJWKS defines how to fetch and cache JSON Web Key Sets (JWKS) from a remote + // HTTP/HTTPS endpoint. + RemoteJWKS RemoteJWKS `json:"remoteJWKS"` + + // TODO: Add TBD JWT fields based on defined use cases. +} + +// RemoteJWKS defines how to fetch and cache JSON Web Key Sets (JWKS) from a remote +// HTTP/HTTPS endpoint. +type RemoteJWKS struct { + // Uri is the HTTP/HTTPS URI to fetch the JWKS. + // + // Example: + // uri: https://www.googleapis.com/oauth2/v1/certs + // + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=253 + Uri string `json:"uri"` + + // TODO: Add TBD remote JWKS fields based on defined use cases. +} +``` + +The status subresource is not included in the Authentication API. Status will be surfaced by an HTTPRoute that +references an Authentication. For example, an HTTPRoute will surface the `ResolvedRefs=False` status condition if it +references an Authentication that does not exist. It may be beneficial to add status fields in the future based on +defined use-cases. For example, a remote JWKS can be validated based on the specified URI and have an appropriate +status condition surfaced. + +The following is an example of a JWT authentication provider: + +```yaml +apiVersion: security.gateway.envoyproxy.io/v1alpha1 +kind: Authentication +metadata: + name: example-jwt +spec: + type: JWT + jwtProviders: + - name: example + issuer: https://www.example.com + audiences: + - foo.com + remoteJwks: + uri: https://foo.com/jwt/public-key/jwks.json + +status: + +``` + +The following is an example HTTPRoute configured to use the above JWT authentication provider: + +```yaml +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: example-hwt-authn +spec: + parentRefs: + - name: eg + hostnames: + - www.example.com + rules: + - matches: + - path: + type: PathPrefix + value: /foo + filters: + - type: ExtensionRef + extensionRef: + group: security.gateway.envoyproxy.io + kind: Authentication + name: example-jwt + backendRefs: + - name: httpbin + port: 80 +``` + +Requests for `www.example.com/foo` will be authenticated using the referenced JWT provider before being forwarded to the +`httpbin` backend service. + +## Implementation Details + +The JWT authentication type is translated to an Envoy [JWT authentication filter][] and a cluster is created for each +remote JWKS. The following cluster is created for the JWT provider defines in the above Authentication: + +```yaml +clusters: + - name: foo.com|443 + load_assignment: + cluster_name: foo.com|443 + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: foo.com + port_value: 443 + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + sni: foo.com + common_tls_context: + validation_context: + match_subject_alt_names: + - exact: "*.foo.com" + trusted_ca: + filename: /etc/ssl/certs/ca-certificates.crt +``` + +A JWT authentication HTTP filter is added to the HTTP Connection Manager. For example: + +```yaml +dynamic_resources: + dynamic_listeners: + - name: example_listener + address: + socket_address: + address: 1.2.3.4 + port_value: 80 + filter_chains: + - filters: + - name: envoy.http_connection_manager + http_filters: + - name: envoy.filters.http.jwt_authn + typed_config: + "@type": type.googleapis.com/envoy.config.filter.http.jwt_authn.v2alpha.JwtAuthentication +``` + +This JWT authentication filter contains two fields: +* The `providers` field specifies how a JWT should be verified, such as where to extract the token, where to fetch the + public key (JWKS) and where to output its payload. This field is built from `jwtProviders` of an Authentication. +* The `rules` field specifies matching rules and their requirements. If a request matches a rule, its requirement + applies. The requirement specifies which JWT providers should be used. This field is built from a HTTPRoute + `matches` rule that references the Authentication extended filter. When a referenced Authentication specifies + multiple `jwtProviders`, the JWT is considered valid if __any__ of the providers successfully validate the JWT. + +The following JWT Authentication filter `providers` configuration is created from the above Authentication. + +```yaml +providers: + example: + issuer: https://www.example.com + audiences: + - foo.com + remote_jwks: + http_uri: + uri: https://foo.com/jwt/public-key/jwks.json + cluster: example_jwks_cluster + timeout: 1s +``` + +The following JWT Authentication filter `rules` configuration is created from the above HTTPRoute. + +```yaml +rules: + - match: + prefix: /foo + requires: + provider_name: example +``` + +If the Authentication included a second JWT provider named `example`, the resulting JWT Authentication filter `rules` +would be created: + +```yaml +rules: +- match: + prefix: /foo + requires: + requires_any: + requirements: + - provider_name: example + - provider_name: example2 +``` + +### Implementation Outline + +* Create a `security` API group and add the Authentication API type to this group. +* Update the Kubernetes provider to get/watch Authentication resources that are referenced by managed HTTPRoutes. Add + the referenced Authentication object to the resource map and publish it. +* Update the resource translator to include the Authentication API in HTTPRoute processing. +* Update the xDS translator to translate an Authentication into xDS resources. The translator should perform the + following: + * Convert a list of JWT rules from the xds IR into an Envoy JWT filter config. + * Create a JWT authentication filter. + * Build the HTTP Connection Manager (MCM) HTTP filters. + * Build the HCM. + * When building the Listener, create an HCM for each filter-chain. + +## Adding Authentication Provider Types + +Additional authentication provider types can be added in the future through the `ProviderType` API. For example, to add +the `Foo` authentication provider type: + +Define the `FooProvider` type: + +```go +package v1alpha1 + +// FooProvider defines the "Foo" authentication provider type. +type FooProvider struct { + // TODO: Define fields of the Foo authentication provider type. +} +``` + +Add the `FooProvider` type to `AuthenticationSpec`: + +```go +package v1alpha1 + +type AuthenticationSpec struct { + ... + + // Foo defines the Foo authentication type. For additional + // details, see: + // + // + // + // +optional + Foo *FooAuthentication `json:"foo"` +} +``` + +Authentication should support additional authentication types in the future, for example: +- mutualTLS (client certificate) +- OAuth2 +- OIDC +- External authentication + +## Outstanding Questions + +- If Envoy Gateway owns the Authentication API, is an xDS IR equivalent needed? +- Should local JWKS be implemented before remote JWKS? +- How should Envoy obtain the trusted CA for a remote JWKS? +- Should HTTPS be the only supported scheme for remote JWKS? +- Should OR'ing JWT providers be supported? +- Should Authentication provide status? +- Are the API field validation rules acceptable? + +[Issue 336]: https://github.com/envoyproxy/gateway/issues/336 +[Gateway API]: https://gateway-api.sigs.k8s.io/ +[support levels]: https://gateway-api.sigs.k8s.io/concepts/conformance/?h=extended#2-support-levels +[JWT]: https://jwt.io/ +[HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute/ +[JWKS]: https://www.rfc-editor.org/rfc/rfc7517 +[JWT authentication filter]: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/jwt_authn_filter#config-http-filters-jwt-authn From d8211237725e52f338e045c0b447e5e405845195 Mon Sep 17 00:00:00 2001 From: Lizan Zhou Date: Sun, 9 Oct 2022 08:34:35 +0000 Subject: [PATCH 09/16] Add authn policy design with JWT only Signed-off-by: Lizan Zhou --- docs/latest/design/authentication_policy.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/latest/design/authentication_policy.md b/docs/latest/design/authentication_policy.md index 5a8d072b9e..d632afa235 100644 --- a/docs/latest/design/authentication_policy.md +++ b/docs/latest/design/authentication_policy.md @@ -2,7 +2,11 @@ ## Overview +<<<<<<< HEAD:docs/latest/design/authentication_policy.md This authentication policy declares the authentication mechanisms, to be enforced on connection and request going though Envoy Gateway. This includes the credential (X.509, JWT, etc), parameters (cipher suites, key algorithms) +======= +This authen policy is to declare the authentication mechanisms, to be enforce on connection and request going though Envoy Gateway. This includes the credential (X.509, JWT, etc), parameters (cipher suites, key algorithms) +>>>>>>> 9a6ed41 (Add authn policy design with JWT only):docs/design/authentication_policy.md The policy is similar to [OpenAPI 3.1 security objects](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#securitySchemeObject) without the API key part, and should be easily translatable from it with some additions. ## Authentication mechanisms @@ -37,4 +41,8 @@ spec: name: httpbin ``` +<<<<<<< HEAD:docs/latest/design/authentication_policy.md JWT Bearer token will be translate to Envoy's JWT authentication filter. The JWKS URI need to be translated to a separate cluster for JWKS fetch and refresh. +======= +JWT Bearer token will be translate to Envoy's JWT authentication filter. The JWKS URI need to be translated to a separate cluster for JWKS fetch and refersh. +>>>>>>> 9a6ed41 (Add authn policy design with JWT only):docs/design/authentication_policy.md From 33772f72f7dda27e471c2beffc6ec6579a4f7d83 Mon Sep 17 00:00:00 2001 From: Lizan Zhou Date: Wed, 2 Nov 2022 10:45:07 -0700 Subject: [PATCH 10/16] Update docs/design/authentication_policy.md Co-authored-by: Arko Dasgupta Signed-off-by: Lizan Zhou --- docs/latest/design/authentication_policy.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/latest/design/authentication_policy.md b/docs/latest/design/authentication_policy.md index d632afa235..46b7f169d0 100644 --- a/docs/latest/design/authentication_policy.md +++ b/docs/latest/design/authentication_policy.md @@ -2,11 +2,15 @@ ## Overview +<<<<<<< HEAD:docs/latest/design/authentication_policy.md <<<<<<< HEAD:docs/latest/design/authentication_policy.md This authentication policy declares the authentication mechanisms, to be enforced on connection and request going though Envoy Gateway. This includes the credential (X.509, JWT, etc), parameters (cipher suites, key algorithms) ======= This authen policy is to declare the authentication mechanisms, to be enforce on connection and request going though Envoy Gateway. This includes the credential (X.509, JWT, etc), parameters (cipher suites, key algorithms) >>>>>>> 9a6ed41 (Add authn policy design with JWT only):docs/design/authentication_policy.md +======= +This authentication policy declares the authentication mechanisms, to be enforced on connection and request going though Envoy Gateway. This includes the credential (X.509, JWT, etc), parameters (cipher suites, key algorithms) +>>>>>>> b5c4755 (Update docs/design/authentication_policy.md):docs/design/authentication_policy.md The policy is similar to [OpenAPI 3.1 security objects](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#securitySchemeObject) without the API key part, and should be easily translatable from it with some additions. ## Authentication mechanisms From aa4c617b3c0be043b825c85ca5342a9c472d71d5 Mon Sep 17 00:00:00 2001 From: Lizan Zhou Date: Wed, 2 Nov 2022 10:45:13 -0700 Subject: [PATCH 11/16] Update docs/design/authentication_policy.md Co-authored-by: Arko Dasgupta Signed-off-by: Lizan Zhou --- docs/latest/design/authentication_policy.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/latest/design/authentication_policy.md b/docs/latest/design/authentication_policy.md index 46b7f169d0..761d93bccc 100644 --- a/docs/latest/design/authentication_policy.md +++ b/docs/latest/design/authentication_policy.md @@ -45,8 +45,12 @@ spec: name: httpbin ``` +<<<<<<< HEAD:docs/latest/design/authentication_policy.md <<<<<<< HEAD:docs/latest/design/authentication_policy.md JWT Bearer token will be translate to Envoy's JWT authentication filter. The JWKS URI need to be translated to a separate cluster for JWKS fetch and refresh. ======= JWT Bearer token will be translate to Envoy's JWT authentication filter. The JWKS URI need to be translated to a separate cluster for JWKS fetch and refersh. >>>>>>> 9a6ed41 (Add authn policy design with JWT only):docs/design/authentication_policy.md +======= +JWT Bearer token will be translate to Envoy's JWT authentication filter. The JWKS URI need to be translated to a separate cluster for JWKS fetch and refresh. +>>>>>>> 3cb97e1 (Update docs/design/authentication_policy.md):docs/design/authentication_policy.md From 12f33db7a8fa599935d0ef5b10f7f9054fb2f289 Mon Sep 17 00:00:00 2001 From: danehans Date: Fri, 11 Nov 2022 09:07:56 -0800 Subject: [PATCH 12/16] Resolves Review Feedback Signed-off-by: danehans --- docs/latest/design/request-authentication.md | 272 +++++++++++++++++-- 1 file changed, 249 insertions(+), 23 deletions(-) diff --git a/docs/latest/design/request-authentication.md b/docs/latest/design/request-authentication.md index 5acb9398e7..be7b8bd3f5 100644 --- a/docs/latest/design/request-authentication.md +++ b/docs/latest/design/request-authentication.md @@ -18,12 +18,14 @@ be created for this purpose. * Implement [JWT] as the first supported authentication type. * Allow users that manage routes, e.g. [HTTPRoute][], to authenticate matching requests before forwarding to a backend service. -* Support HTTPRoutes as an Authentication API referent. +* Support HTTPRoutes as an Authentication API referent. HTTPRoute provides multiple [extension points][]. The + [HTTPRouteFilter][] is the extension point supported by the Authentication API. ## Non-Goals * Allow infrastructure administrators to override or establish default authentication policies. * Support referents other than HTTPRoute. +* Support Gateway API extension points other than HTTPRouteFilter. ## Use-Cases @@ -163,13 +165,15 @@ references an Authentication that does not exist. It may be beneficial to add st defined use-cases. For example, a remote JWKS can be validated based on the specified URI and have an appropriate status condition surfaced. -The following is an example of a JWT authentication provider: +#### Authentication Example + +The following is an Authentication example with one JWT authentication provider: ```yaml apiVersion: security.gateway.envoyproxy.io/v1alpha1 kind: Authentication metadata: - name: example-jwt + name: example spec: type: JWT jwtProviders: @@ -184,13 +188,16 @@ status: ``` +__Note:__ `type` is a union type, allowing only one of any supported provider type such as `jwtProviders` to be +specified. + The following is an example HTTPRoute configured to use the above JWT authentication provider: ```yaml apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: - name: example-hwt-authn + name: example spec: parentRefs: - name: eg @@ -206,22 +213,27 @@ spec: extensionRef: group: security.gateway.envoyproxy.io kind: Authentication - name: example-jwt + name: example backendRefs: - - name: httpbin - port: 80 + - name: backend + port: 3000 ``` Requests for `www.example.com/foo` will be authenticated using the referenced JWT provider before being forwarded to the -`httpbin` backend service. +backend service named "backend". ## Implementation Details The JWT authentication type is translated to an Envoy [JWT authentication filter][] and a cluster is created for each -remote JWKS. The following cluster is created for the JWT provider defines in the above Authentication: +remote JWKS. The following examples provide additional details on how Gateway API and Authentication resources are +translated into Envoy configuration. + +### Example 1: One Route with One JWT Provider + +The following cluster is created from the above HTTPRoute and Authentication: ```yaml -clusters: +dynamic_clusters: - name: foo.com|443 load_assignment: cluster_name: foo.com|443 @@ -266,7 +278,8 @@ dynamic_resources: This JWT authentication filter contains two fields: * The `providers` field specifies how a JWT should be verified, such as where to extract the token, where to fetch the - public key (JWKS) and where to output its payload. This field is built from `jwtProviders` of an Authentication. + public key (JWKS) and where to output its payload. This field is built from the source resource `namespace-name`, and + the JWT provider name of an Authentication. * The `rules` field specifies matching rules and their requirements. If a request matches a rule, its requirement applies. The requirement specifies which JWT providers should be used. This field is built from a HTTPRoute `matches` rule that references the Authentication extended filter. When a referenced Authentication specifies @@ -294,23 +307,234 @@ rules: - match: prefix: /foo requires: - provider_name: example + provider_name: default-example-example ``` -If the Authentication included a second JWT provider named `example`, the resulting JWT Authentication filter `rules` -would be created: +### Example 2: Two HTTPRoutes with Different Authentications + +The following example contains: +* Two HTTPRoutes with different hostnames. +* Each HTTPRoute references a different Authentication +* Each Authentication contains a different JWT provider. ```yaml -rules: -- match: - prefix: /foo - requires: - requires_any: - requirements: - - provider_name: example - - provider_name: example2 +apiVersion: security.gateway.envoyproxy.io/v1alpha1 +kind: Authentication +metadata: + name: example1 +spec: + type: JWT + jwtProviders: + - name: example1 + issuer: https://www.example1.com + audiences: + - foo.com + remoteJwks: + uri: https://foo.com/jwt/public-key/jwks.json +--- +apiVersion: security.gateway.envoyproxy.io/v1alpha1 +kind: Authentication +metadata: + name: example2 +spec: + type: JWT + jwtProviders: + - name: example2 + issuer: https://www.example2.com + audiences: + - bar.com + remoteJwks: + uri: https://bar.com/jwt/public-key/jwks.json +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: example1 +spec: + hostnames: + - www.example1.com + parentRefs: + - group: gateway.networking.k8s.io + kind: Gateway + name: eg + rules: + - matches: + - path: + type: PathPrefix + value: /foo + filters: + - type: ExtensionRef + extensionRef: + group: security.gateway.envoyproxy.io + kind: Authentication + name: example1 + backendRefs: + - name: backend + port: 3000 +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: example2 +spec: + hostnames: + - www.example2.com + parentRefs: + - group: gateway.networking.k8s.io + kind: Gateway + name: eg + rules: + - matches: + - path: + type: PathPrefix + value: /bar + filters: + - type: ExtensionRef + extensionRef: + group: security.gateway.envoyproxy.io + kind: Authentication + name: example2 + backendRefs: + - name: backend2 + port: 3000 +``` + +The following xDS configuration is created from the above example resources: + +```yaml +configs: +... +dynamic_listeners: + - name: default-eg-http + ... + default_filter_chain: + filters: + - name: envoy.filters.network.http_connection_manager_1 + typed_config: + '@type': >- + type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: http + rds: + config_source: + ... + route_config_name: default-eg-http-1 + http_filters: + - name: envoy.filters.http.jwt_authn + typed_config: + '@type': >- + type.googleapis.com/envoy.config.filter.http.jwt_authn.v2alpha.JwtAuthentication + providers: + default-example1-example1: + issuer: https://www.example1.com + audiences: + - foo.com + remote_jwks: + http_uri: + uri: https://foo.com/jwt/public-key/jwks.json + cluster: default-example1-example1-jwt + rules: + - match: + exact: /foo + requires: + provider_name: default-example1-example1 + - name: envoy.filters.http.router + typed_config: + '@type': >- + type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + - name: envoy.filters.network.http_connection_manager_2 + typed_config: + '@type': >- + type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: http + rds: + config_source: + ... + route_config_name: default-eg-http-2 + http_filters: + - name: envoy.filters.http.jwt_authn + typed_config: + '@type': >- + type.googleapis.com/envoy.config.filter.http.jwt_authn.v2alpha.JwtAuthentication + providers: + default-example2-example2: + issuer: https://www.example2.com + audiences: + - bar.com + remote_jwks: + http_uri: + uri: https://bar.com/jwt/public-key/jwks.json + cluster: default-example2-example2-jwt + rules: + - match: + exact: /bar + requires: + provider_name: default-example2-example2 + - name: envoy.filters.http.router + typed_config: + '@type': >- + type.googleapis.com/envoy.extensions.filters.http.router.v3.Router +dynamic_route_configs: + - route_config: + '@type': type.googleapis.com/envoy.config.route.v3.RouteConfiguration + name: default-eg-http-1 + virtual_hosts: + - name: default-eg-http-1 + domains: + - '*' + routes: + - match: + prefix: /foo + headers: + - name: ':authority' + string_match: + exact: www.example1.com + route: + cluster: default-backend-rule-0-match-0-www.example1.com + - route_config: + '@type': type.googleapis.com/envoy.config.route.v3.RouteConfiguration + name: default-eg-http + virtual_hosts: + - name: default-eg-http-2 + domains: + - '*' + routes: + - match: + prefix: /bar + headers: + - name: ':authority' + string_match: + exact: www.example2.com + route: + cluster: default-backend2-rule-0-match-0-www.example2.com +dynamic_active_clusters: + - cluster: + name: default-backend-rule-0-match-0-www.example.com + ... + endpoints: + - locality: {} + lb_endpoints: + - endpoint: + address: + socket_address: + address: $BACKEND_SERVICE1_IP + port_value: 3000 + - cluster: + '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster + name: default-backend-rule-1-match-0-www.example.com + ... + endpoints: + - locality: {} + lb_endpoints: + - endpoint: + address: + socket_address: + address: $BACKEND_SERVICE2_IP + port_value: 3000 +... ``` +__Note:__ The JWT provider cluster and route is omitted from the above example for brevity. + ### Implementation Outline * Create a `security` API group and add the Authentication API type to this group. @@ -321,7 +545,7 @@ rules: following: * Convert a list of JWT rules from the xds IR into an Envoy JWT filter config. * Create a JWT authentication filter. - * Build the HTTP Connection Manager (MCM) HTTP filters. + * Build the HTTP Connection Manager (HCM) HTTP filters. * Build the HCM. * When building the Listener, create an HCM for each filter-chain. @@ -380,5 +604,7 @@ Authentication should support additional authentication types in the future, for [support levels]: https://gateway-api.sigs.k8s.io/concepts/conformance/?h=extended#2-support-levels [JWT]: https://jwt.io/ [HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute/ +[extension points]: https://gateway-api.sigs.k8s.io/concepts/api-overview/?h=extension#extension-points +[HTTPRouteFilter]: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteFilter [JWKS]: https://www.rfc-editor.org/rfc/rfc7517 [JWT authentication filter]: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/jwt_authn_filter#config-http-filters-jwt-authn From 3b1e792fbf659c3427f8f54ef1299b7eb8e0a616 Mon Sep 17 00:00:00 2001 From: danehans Date: Wed, 16 Nov 2022 10:43:19 -0800 Subject: [PATCH 13/16] Removes duplicative docs Signed-off-by: danehans --- docs/design/request-authentication.md | 384 -------------------- docs/latest/design/authentication_policy.md | 56 --- 2 files changed, 440 deletions(-) delete mode 100644 docs/design/request-authentication.md delete mode 100644 docs/latest/design/authentication_policy.md diff --git a/docs/design/request-authentication.md b/docs/design/request-authentication.md deleted file mode 100644 index 5acb9398e7..0000000000 --- a/docs/design/request-authentication.md +++ /dev/null @@ -1,384 +0,0 @@ -# Request Authentication - -## Overview - -[Issue 336][] specifies the need for exposing a user-facing API to configure request authentication. Request -authentication is defined as an authentication mechanism to be enforced by Envoy on a per-request basis. A connection -will be rejected if it contains invalid authentication information, based on the `Authentication` API type proposed in -this design document. - -Envoy Gateway leverages [Gateway API][] for configuring managed Envoy proxies. Gateway API defines core, extended, and -implementation-specific API [support levels][] for implementors such as Envoy Gateway to expose features. Since -implementing request authentication is not covered by `Core` or `Extended` APIs, an `Implementation-specific` API will -be created for this purpose. - -## Goals - -* Define an API for configuring request authentication. -* Implement [JWT] as the first supported authentication type. -* Allow users that manage routes, e.g. [HTTPRoute][], to authenticate matching requests before forwarding to a backend - service. -* Support HTTPRoutes as an Authentication API referent. - -## Non-Goals - -* Allow infrastructure administrators to override or establish default authentication policies. -* Support referents other than HTTPRoute. - -## Use-Cases - -These use-cases are presented as an aid for how users may attempt to utilize the outputs of the design. They are not an -exhaustive list of features for authentication support in Envoy Gateway. - -As a Service Producer, I need the ability to: -* Authenticate a request before forwarding it to a backend service. -* Have different authentication mechanisms per route rule. -* Choose from different authentication mechanisms supported by Envoy, e.g. OIDC. - -### Security API Group - -A new API group, `security.gateway.envoyproxy.io` is introduced to group security-related APIs. This will allow security -APIs to be versioned, changed, etc. over time. - -### Authentication API Type - -The Authentication API type defines authentication configuration for authenticating requests through managed Envoy -proxies. - -```go -package v1alpha1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - -) - -type Authentication struct { - metav1.TypeMeta - metav1.ObjectMeta - - // Spec defines the desired state of the Authentication type. - Spec AuthenticationSpec - - // Note: The status sub-resource has been excluded but may be added in the future. -} - -// AuthenticationSpec defines the desired state of the Authentication type. -// +union -type AuthenticationSpec struct { - // Type defines the type of authentication provider to use. Supported provider - // types are: - // - // * JWT - // - // JWT defines the JSON Web Token (JWT) authentication provider type. - // - // +unionDiscriminator - Type AuthenticationType `json:"type"` - - // JWT defines the JSON Web Token (JWT) authentication provider type. When multiple - // jwtProviders are specified, the JWT is considered valid if any of the providers - // successfully validate the JWT. For additional details, see: - // - // https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/jwt_authn_filter.html - // - // +kubebuilder:validation:MaxItems=4 - // +optional - JwtProviders []JwtAuthenticationProvider `json:"jwtProviders,omitempty"` -} - -// AuthenticationType is a type of authentication provider. -// +kubebuilder:validation:Enum=JWT -type AuthenticationType string - -const ( - // JwtAuthenticationProviderType is the JWT authentication provider type. - JwtAuthenticationProviderType AuthenticationType = "JWT" -) - -// JwtAuthenticationProvider defines the JSON Web Token (JWT) authentication provider type -// and how JWTs should be verified: -type JwtAuthenticationProvider struct { - // Name defines a unique name for the JWT provider. A name can have a variety of forms, - // including RFC1123 subdomains, RFC 1123 labels, or RFC 1035 labels. - // - // +kubebuilder:validation:MinLength=1 - // +kubebuilder:validation:MaxLength=253 - Name string `json:"name"` - - // Issuer is the principal that issued the JWT. For additional details, see: - // - // https://tools.ietf.org/html/rfc7519#section-4.1.1 - // - // Example: - // issuer: https://auth.example.com - // - // If not provided, the JWT issuer is not checked. - // - // +kubebuilder:validation:MaxLength=253 - // +optional - Issuer string `json:"issuer,omitempty"` - - // Audiences is a list of JWT audiences allowed to access. For additional details, see: - // - // https://tools.ietf.org/html/rfc7519#section-4.1.3 - // - // Example: - // audiences: - // - foo.apps.example.com - // bar.apps.example.com - // - // If not provided, JWT audiences are not checked. - // - // +kubebuilder:validation:MaxItems=8 - // +optional - Audiences []string `json:"audiences,omitempty"` - - // RemoteJWKS defines how to fetch and cache JSON Web Key Sets (JWKS) from a remote - // HTTP/HTTPS endpoint. - RemoteJWKS RemoteJWKS `json:"remoteJWKS"` - - // TODO: Add TBD JWT fields based on defined use cases. -} - -// RemoteJWKS defines how to fetch and cache JSON Web Key Sets (JWKS) from a remote -// HTTP/HTTPS endpoint. -type RemoteJWKS struct { - // Uri is the HTTP/HTTPS URI to fetch the JWKS. - // - // Example: - // uri: https://www.googleapis.com/oauth2/v1/certs - // - // +kubebuilder:validation:MinLength=1 - // +kubebuilder:validation:MaxLength=253 - Uri string `json:"uri"` - - // TODO: Add TBD remote JWKS fields based on defined use cases. -} -``` - -The status subresource is not included in the Authentication API. Status will be surfaced by an HTTPRoute that -references an Authentication. For example, an HTTPRoute will surface the `ResolvedRefs=False` status condition if it -references an Authentication that does not exist. It may be beneficial to add status fields in the future based on -defined use-cases. For example, a remote JWKS can be validated based on the specified URI and have an appropriate -status condition surfaced. - -The following is an example of a JWT authentication provider: - -```yaml -apiVersion: security.gateway.envoyproxy.io/v1alpha1 -kind: Authentication -metadata: - name: example-jwt -spec: - type: JWT - jwtProviders: - - name: example - issuer: https://www.example.com - audiences: - - foo.com - remoteJwks: - uri: https://foo.com/jwt/public-key/jwks.json - -status: - -``` - -The following is an example HTTPRoute configured to use the above JWT authentication provider: - -```yaml -apiVersion: gateway.networking.k8s.io/v1beta1 -kind: HTTPRoute -metadata: - name: example-hwt-authn -spec: - parentRefs: - - name: eg - hostnames: - - www.example.com - rules: - - matches: - - path: - type: PathPrefix - value: /foo - filters: - - type: ExtensionRef - extensionRef: - group: security.gateway.envoyproxy.io - kind: Authentication - name: example-jwt - backendRefs: - - name: httpbin - port: 80 -``` - -Requests for `www.example.com/foo` will be authenticated using the referenced JWT provider before being forwarded to the -`httpbin` backend service. - -## Implementation Details - -The JWT authentication type is translated to an Envoy [JWT authentication filter][] and a cluster is created for each -remote JWKS. The following cluster is created for the JWT provider defines in the above Authentication: - -```yaml -clusters: - - name: foo.com|443 - load_assignment: - cluster_name: foo.com|443 - endpoints: - - lb_endpoints: - - endpoint: - address: - socket_address: - address: foo.com - port_value: 443 - transport_socket: - name: envoy.transport_sockets.tls - typed_config: - "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext - sni: foo.com - common_tls_context: - validation_context: - match_subject_alt_names: - - exact: "*.foo.com" - trusted_ca: - filename: /etc/ssl/certs/ca-certificates.crt -``` - -A JWT authentication HTTP filter is added to the HTTP Connection Manager. For example: - -```yaml -dynamic_resources: - dynamic_listeners: - - name: example_listener - address: - socket_address: - address: 1.2.3.4 - port_value: 80 - filter_chains: - - filters: - - name: envoy.http_connection_manager - http_filters: - - name: envoy.filters.http.jwt_authn - typed_config: - "@type": type.googleapis.com/envoy.config.filter.http.jwt_authn.v2alpha.JwtAuthentication -``` - -This JWT authentication filter contains two fields: -* The `providers` field specifies how a JWT should be verified, such as where to extract the token, where to fetch the - public key (JWKS) and where to output its payload. This field is built from `jwtProviders` of an Authentication. -* The `rules` field specifies matching rules and their requirements. If a request matches a rule, its requirement - applies. The requirement specifies which JWT providers should be used. This field is built from a HTTPRoute - `matches` rule that references the Authentication extended filter. When a referenced Authentication specifies - multiple `jwtProviders`, the JWT is considered valid if __any__ of the providers successfully validate the JWT. - -The following JWT Authentication filter `providers` configuration is created from the above Authentication. - -```yaml -providers: - example: - issuer: https://www.example.com - audiences: - - foo.com - remote_jwks: - http_uri: - uri: https://foo.com/jwt/public-key/jwks.json - cluster: example_jwks_cluster - timeout: 1s -``` - -The following JWT Authentication filter `rules` configuration is created from the above HTTPRoute. - -```yaml -rules: - - match: - prefix: /foo - requires: - provider_name: example -``` - -If the Authentication included a second JWT provider named `example`, the resulting JWT Authentication filter `rules` -would be created: - -```yaml -rules: -- match: - prefix: /foo - requires: - requires_any: - requirements: - - provider_name: example - - provider_name: example2 -``` - -### Implementation Outline - -* Create a `security` API group and add the Authentication API type to this group. -* Update the Kubernetes provider to get/watch Authentication resources that are referenced by managed HTTPRoutes. Add - the referenced Authentication object to the resource map and publish it. -* Update the resource translator to include the Authentication API in HTTPRoute processing. -* Update the xDS translator to translate an Authentication into xDS resources. The translator should perform the - following: - * Convert a list of JWT rules from the xds IR into an Envoy JWT filter config. - * Create a JWT authentication filter. - * Build the HTTP Connection Manager (MCM) HTTP filters. - * Build the HCM. - * When building the Listener, create an HCM for each filter-chain. - -## Adding Authentication Provider Types - -Additional authentication provider types can be added in the future through the `ProviderType` API. For example, to add -the `Foo` authentication provider type: - -Define the `FooProvider` type: - -```go -package v1alpha1 - -// FooProvider defines the "Foo" authentication provider type. -type FooProvider struct { - // TODO: Define fields of the Foo authentication provider type. -} -``` - -Add the `FooProvider` type to `AuthenticationSpec`: - -```go -package v1alpha1 - -type AuthenticationSpec struct { - ... - - // Foo defines the Foo authentication type. For additional - // details, see: - // - // - // - // +optional - Foo *FooAuthentication `json:"foo"` -} -``` - -Authentication should support additional authentication types in the future, for example: -- mutualTLS (client certificate) -- OAuth2 -- OIDC -- External authentication - -## Outstanding Questions - -- If Envoy Gateway owns the Authentication API, is an xDS IR equivalent needed? -- Should local JWKS be implemented before remote JWKS? -- How should Envoy obtain the trusted CA for a remote JWKS? -- Should HTTPS be the only supported scheme for remote JWKS? -- Should OR'ing JWT providers be supported? -- Should Authentication provide status? -- Are the API field validation rules acceptable? - -[Issue 336]: https://github.com/envoyproxy/gateway/issues/336 -[Gateway API]: https://gateway-api.sigs.k8s.io/ -[support levels]: https://gateway-api.sigs.k8s.io/concepts/conformance/?h=extended#2-support-levels -[JWT]: https://jwt.io/ -[HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute/ -[JWKS]: https://www.rfc-editor.org/rfc/rfc7517 -[JWT authentication filter]: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/jwt_authn_filter#config-http-filters-jwt-authn diff --git a/docs/latest/design/authentication_policy.md b/docs/latest/design/authentication_policy.md deleted file mode 100644 index 761d93bccc..0000000000 --- a/docs/latest/design/authentication_policy.md +++ /dev/null @@ -1,56 +0,0 @@ -# Envoy Gateway Authentication Policy API - -## Overview - -<<<<<<< HEAD:docs/latest/design/authentication_policy.md -<<<<<<< HEAD:docs/latest/design/authentication_policy.md -This authentication policy declares the authentication mechanisms, to be enforced on connection and request going though Envoy Gateway. This includes the credential (X.509, JWT, etc), parameters (cipher suites, key algorithms) -======= -This authen policy is to declare the authentication mechanisms, to be enforce on connection and request going though Envoy Gateway. This includes the credential (X.509, JWT, etc), parameters (cipher suites, key algorithms) ->>>>>>> 9a6ed41 (Add authn policy design with JWT only):docs/design/authentication_policy.md -======= -This authentication policy declares the authentication mechanisms, to be enforced on connection and request going though Envoy Gateway. This includes the credential (X.509, JWT, etc), parameters (cipher suites, key algorithms) ->>>>>>> b5c4755 (Update docs/design/authentication_policy.md):docs/design/authentication_policy.md -The policy is similar to [OpenAPI 3.1 security objects](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#securitySchemeObject) without the API key part, and should be easily translatable from it with some additions. - -## Authentication mechanisms -This policy should support the following authentication mechanisms: -- JWT Bearer Token -- mutualTLS (client certificate) -- OAuth2 -- OIDC -- External authentication - -In the first phase, Envoy Gateway will implement JWT Bearer Token authentication. - -In general those policy translates into Envoy HTTP filters at HTTP connection manager level, and route specific settings will be applied for each route. These APIs are expressed in a Policy CRD and attached to Gateway API resources with [Policy Attachement](https://gateway-api.sigs.k8s.io/references/policy-attachment/). - -## JWT Bearer Token - -A JWT Bearer Token authentication policy will look like the following: - -``` -apiVersion: gateway.envoyproxy.io/v1alpha1 -kind: Authentication -metadata: - name: productpage -spec: - type: jwt - jwt: - iss: https://www.okta.com - aud: bookinfo.com - jwksUri: https://bookinfo.com/jwt/public-key/jwks.json - targetRef: - kind: HTTPRoute - name: httpbin -``` - -<<<<<<< HEAD:docs/latest/design/authentication_policy.md -<<<<<<< HEAD:docs/latest/design/authentication_policy.md -JWT Bearer token will be translate to Envoy's JWT authentication filter. The JWKS URI need to be translated to a separate cluster for JWKS fetch and refresh. -======= -JWT Bearer token will be translate to Envoy's JWT authentication filter. The JWKS URI need to be translated to a separate cluster for JWKS fetch and refersh. ->>>>>>> 9a6ed41 (Add authn policy design with JWT only):docs/design/authentication_policy.md -======= -JWT Bearer token will be translate to Envoy's JWT authentication filter. The JWKS URI need to be translated to a separate cluster for JWKS fetch and refresh. ->>>>>>> 3cb97e1 (Update docs/design/authentication_policy.md):docs/design/authentication_policy.md From 362eb96b187fd3fcace83d8aae600ff1be9b52cd Mon Sep 17 00:00:00 2001 From: danehans Date: Wed, 16 Nov 2022 11:13:34 -0800 Subject: [PATCH 14/16] Refers to PR 773 for API Details Signed-off-by: danehans --- docs/latest/design/request-authentication.md | 97 +++----------------- 1 file changed, 12 insertions(+), 85 deletions(-) diff --git a/docs/latest/design/request-authentication.md b/docs/latest/design/request-authentication.md index be7b8bd3f5..31ed2faaa9 100644 --- a/docs/latest/design/request-authentication.md +++ b/docs/latest/design/request-authentication.md @@ -71,99 +71,27 @@ type AuthenticationSpec struct { // Type defines the type of authentication provider to use. Supported provider // types are: // - // * JWT - // - // JWT defines the JSON Web Token (JWT) authentication provider type. + // * JWT: A provider that uses JSON Web Token (JWT) for authenticating requests. // // +unionDiscriminator - Type AuthenticationType `json:"type"` - + Type AuthenticationType + // JWT defines the JSON Web Token (JWT) authentication provider type. When multiple // jwtProviders are specified, the JWT is considered valid if any of the providers - // successfully validate the JWT. For additional details, see: - // - // https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/jwt_authn_filter.html - // - // +kubebuilder:validation:MaxItems=4 - // +optional - JwtProviders []JwtAuthenticationProvider `json:"jwtProviders,omitempty"` -} - -// AuthenticationType is a type of authentication provider. -// +kubebuilder:validation:Enum=JWT -type AuthenticationType string - -const ( - // JwtAuthenticationProviderType is the JWT authentication provider type. - JwtAuthenticationProviderType AuthenticationType = "JWT" -) - -// JwtAuthenticationProvider defines the JSON Web Token (JWT) authentication provider type -// and how JWTs should be verified: -type JwtAuthenticationProvider struct { - // Name defines a unique name for the JWT provider. A name can have a variety of forms, - // including RFC1123 subdomains, RFC 1123 labels, or RFC 1035 labels. - // - // +kubebuilder:validation:MinLength=1 - // +kubebuilder:validation:MaxLength=253 - Name string `json:"name"` - - // Issuer is the principal that issued the JWT. For additional details, see: - // - // https://tools.ietf.org/html/rfc7519#section-4.1.1 - // - // Example: - // issuer: https://auth.example.com - // - // If not provided, the JWT issuer is not checked. - // - // +kubebuilder:validation:MaxLength=253 - // +optional - Issuer string `json:"issuer,omitempty"` - - // Audiences is a list of JWT audiences allowed to access. For additional details, see: - // - // https://tools.ietf.org/html/rfc7519#section-4.1.3 - // - // Example: - // audiences: - // - foo.apps.example.com - // bar.apps.example.com - // - // If not provided, JWT audiences are not checked. - // - // +kubebuilder:validation:MaxItems=8 - // +optional - Audiences []string `json:"audiences,omitempty"` - - // RemoteJWKS defines how to fetch and cache JSON Web Key Sets (JWKS) from a remote - // HTTP/HTTPS endpoint. - RemoteJWKS RemoteJWKS `json:"remoteJWKS"` - - // TODO: Add TBD JWT fields based on defined use cases. + // successfully validate the JWT. + JwtProviders []JwtAuthenticationProvider } -// RemoteJWKS defines how to fetch and cache JSON Web Key Sets (JWKS) from a remote -// HTTP/HTTPS endpoint. -type RemoteJWKS struct { - // Uri is the HTTP/HTTPS URI to fetch the JWKS. - // - // Example: - // uri: https://www.googleapis.com/oauth2/v1/certs - // - // +kubebuilder:validation:MinLength=1 - // +kubebuilder:validation:MaxLength=253 - Uri string `json:"uri"` - - // TODO: Add TBD remote JWKS fields based on defined use cases. -} +... ``` +Refer to [PR 773][] for the detailed Authentication API spec. + The status subresource is not included in the Authentication API. Status will be surfaced by an HTTPRoute that references an Authentication. For example, an HTTPRoute will surface the `ResolvedRefs=False` status condition if it -references an Authentication that does not exist. It may be beneficial to add status fields in the future based on -defined use-cases. For example, a remote JWKS can be validated based on the specified URI and have an appropriate -status condition surfaced. +references an Authentication that does not exist. It may be beneficial to add Authentication status fields in the future +based on defined use-cases. For example, a remote JWKS can be validated based on the specified URI and have an +appropriate status condition surfaced. #### Authentication Example @@ -184,8 +112,6 @@ spec: remoteJwks: uri: https://foo.com/jwt/public-key/jwks.json -status: - ``` __Note:__ `type` is a union type, allowing only one of any supported provider type such as `jwtProviders` to be @@ -608,3 +534,4 @@ Authentication should support additional authentication types in the future, for [HTTPRouteFilter]: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteFilter [JWKS]: https://www.rfc-editor.org/rfc/rfc7517 [JWT authentication filter]: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/jwt_authn_filter#config-http-filters-jwt-authn +[PR 773]: https://github.com/envoyproxy/gateway/pull/733 From 8c2fde2f616a38b96cf602e0d40d5c6ebc2bbe3e Mon Sep 17 00:00:00 2001 From: danehans Date: Mon, 28 Nov 2022 09:49:32 -0800 Subject: [PATCH 15/16] Refactors JWT xDS Config Signed-off-by: danehans --- docs/latest/design/request-authentication.md | 62 +++++--------------- 1 file changed, 16 insertions(+), 46 deletions(-) diff --git a/docs/latest/design/request-authentication.md b/docs/latest/design/request-authentication.md index 31ed2faaa9..733b9bab84 100644 --- a/docs/latest/design/request-authentication.md +++ b/docs/latest/design/request-authentication.md @@ -335,7 +335,7 @@ dynamic_listeners: ... default_filter_chain: filters: - - name: envoy.filters.network.http_connection_manager_1 + - name: envoy.filters.network.http_connection_manager typed_config: '@type': >- type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager @@ -343,7 +343,7 @@ dynamic_listeners: rds: config_source: ... - route_config_name: default-eg-http-1 + route_config_name: default-eg-http http_filters: - name: envoy.filters.http.jwt_authn typed_config: @@ -358,53 +358,33 @@ dynamic_listeners: http_uri: uri: https://foo.com/jwt/public-key/jwks.json cluster: default-example1-example1-jwt + default-example2-example2: + issuer: https://www.example2.com + audiences: + - bar.com + remote_jwks: + http_uri: + uri: https://bar.com/jwt/public-key/jwks.json + cluster: default-example2-example2-jwt rules: - match: exact: /foo requires: provider_name: default-example1-example1 + - match: + exact: /bar + requires: + provider_name: default-example2-example2 - name: envoy.filters.http.router typed_config: '@type': >- type.googleapis.com/envoy.extensions.filters.http.router.v3.Router - - name: envoy.filters.network.http_connection_manager_2 - typed_config: - '@type': >- - type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager - stat_prefix: http - rds: - config_source: - ... - route_config_name: default-eg-http-2 - http_filters: - - name: envoy.filters.http.jwt_authn - typed_config: - '@type': >- - type.googleapis.com/envoy.config.filter.http.jwt_authn.v2alpha.JwtAuthentication - providers: - default-example2-example2: - issuer: https://www.example2.com - audiences: - - bar.com - remote_jwks: - http_uri: - uri: https://bar.com/jwt/public-key/jwks.json - cluster: default-example2-example2-jwt - rules: - - match: - exact: /bar - requires: - provider_name: default-example2-example2 - - name: envoy.filters.http.router - typed_config: - '@type': >- - type.googleapis.com/envoy.extensions.filters.http.router.v3.Router dynamic_route_configs: - route_config: '@type': type.googleapis.com/envoy.config.route.v3.RouteConfiguration - name: default-eg-http-1 + name: default-eg-http virtual_hosts: - - name: default-eg-http-1 + - name: default-eg-http domains: - '*' routes: @@ -416,14 +396,6 @@ dynamic_route_configs: exact: www.example1.com route: cluster: default-backend-rule-0-match-0-www.example1.com - - route_config: - '@type': type.googleapis.com/envoy.config.route.v3.RouteConfiguration - name: default-eg-http - virtual_hosts: - - name: default-eg-http-2 - domains: - - '*' - routes: - match: prefix: /bar headers: @@ -510,10 +482,8 @@ type AuthenticationSpec struct { ``` Authentication should support additional authentication types in the future, for example: -- mutualTLS (client certificate) - OAuth2 - OIDC -- External authentication ## Outstanding Questions From 947359c71dae95a0e725262014dc039cc21083f9 Mon Sep 17 00:00:00 2001 From: danehans Date: Wed, 30 Nov 2022 15:15:54 -0800 Subject: [PATCH 16/16] Removes API Group and Renames API to AuthenticationFilter Signed-off-by: danehans --- docs/latest/design/request-authentication.md | 130 ++++++++++--------- 1 file changed, 68 insertions(+), 62 deletions(-) diff --git a/docs/latest/design/request-authentication.md b/docs/latest/design/request-authentication.md index 733b9bab84..470d9223f1 100644 --- a/docs/latest/design/request-authentication.md +++ b/docs/latest/design/request-authentication.md @@ -4,8 +4,8 @@ [Issue 336][] specifies the need for exposing a user-facing API to configure request authentication. Request authentication is defined as an authentication mechanism to be enforced by Envoy on a per-request basis. A connection -will be rejected if it contains invalid authentication information, based on the `Authentication` API type proposed in -this design document. +will be rejected if it contains invalid authentication information, based on the `AuthenticationFilter` API type +proposed in this design document. Envoy Gateway leverages [Gateway API][] for configuring managed Envoy proxies. Gateway API defines core, extended, and implementation-specific API [support levels][] for implementors such as Envoy Gateway to expose features. Since @@ -37,11 +37,6 @@ As a Service Producer, I need the ability to: * Have different authentication mechanisms per route rule. * Choose from different authentication mechanisms supported by Envoy, e.g. OIDC. -### Security API Group - -A new API group, `security.gateway.envoyproxy.io` is introduced to group security-related APIs. This will allow security -APIs to be versioned, changed, etc. over time. - ### Authentication API Type The Authentication API type defines authentication configuration for authenticating requests through managed Envoy @@ -55,51 +50,50 @@ import ( ) -type Authentication struct { +type AuthenticationFilter struct { metav1.TypeMeta metav1.ObjectMeta // Spec defines the desired state of the Authentication type. - Spec AuthenticationSpec + Spec AuthenticationFilterSpec // Note: The status sub-resource has been excluded but may be added in the future. } -// AuthenticationSpec defines the desired state of the Authentication type. +// AuthenticationFilterSpec defines the desired state of the AuthenticationFilter type. // +union -type AuthenticationSpec struct { - // Type defines the type of authentication provider to use. Supported provider - // types are: +type AuthenticationFilterSpec struct { + // Type defines the type of authentication provider to use. Supported provider types are: // // * JWT: A provider that uses JSON Web Token (JWT) for authenticating requests. // // +unionDiscriminator - Type AuthenticationType + Type AuthenticationFilterType // JWT defines the JSON Web Token (JWT) authentication provider type. When multiple // jwtProviders are specified, the JWT is considered valid if any of the providers // successfully validate the JWT. - JwtProviders []JwtAuthenticationProvider + JwtProviders []JwtAuthenticationFilterProvider } ... ``` -Refer to [PR 773][] for the detailed Authentication API spec. +Refer to [PR 773][] for the detailed AuthenticationFilter API spec. -The status subresource is not included in the Authentication API. Status will be surfaced by an HTTPRoute that -references an Authentication. For example, an HTTPRoute will surface the `ResolvedRefs=False` status condition if it -references an Authentication that does not exist. It may be beneficial to add Authentication status fields in the future +The status subresource is not included in the AuthenticationFilter API. Status will be surfaced by an HTTPRoute that +references an AuthenticationFilter. For example, an HTTPRoute will surface the `ResolvedRefs=False` status condition if it +references an AuthenticationFilter that does not exist. It may be beneficial to add AuthenticationFilter status fields in the future based on defined use-cases. For example, a remote JWKS can be validated based on the specified URI and have an appropriate status condition surfaced. -#### Authentication Example +#### AuthenticationFilter Example -The following is an Authentication example with one JWT authentication provider: +The following is an AuthenticationFilter example with one JWT authentication provider: ```yaml -apiVersion: security.gateway.envoyproxy.io/v1alpha1 -kind: Authentication +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: AuthenticationFilter metadata: name: example spec: @@ -137,8 +131,8 @@ spec: filters: - type: ExtensionRef extensionRef: - group: security.gateway.envoyproxy.io - kind: Authentication + group: gateway.envoyproxy.io + kind: AuthenticationFilter name: example backendRefs: - name: backend @@ -151,12 +145,12 @@ backend service named "backend". ## Implementation Details The JWT authentication type is translated to an Envoy [JWT authentication filter][] and a cluster is created for each -remote JWKS. The following examples provide additional details on how Gateway API and Authentication resources are +remote JWKS. The following examples provide additional details on how Gateway API and AuthenticationFilter resources are translated into Envoy configuration. ### Example 1: One Route with One JWT Provider -The following cluster is created from the above HTTPRoute and Authentication: +The following cluster is created from the above HTTPRoute and AuthenticationFilter: ```yaml dynamic_clusters: @@ -202,16 +196,16 @@ dynamic_resources: "@type": type.googleapis.com/envoy.config.filter.http.jwt_authn.v2alpha.JwtAuthentication ``` -This JWT authentication filter contains two fields: +This JWT authentication HTTP filter contains two fields: * The `providers` field specifies how a JWT should be verified, such as where to extract the token, where to fetch the public key (JWKS) and where to output its payload. This field is built from the source resource `namespace-name`, and - the JWT provider name of an Authentication. + the JWT provider name of an AuthenticationFilter. * The `rules` field specifies matching rules and their requirements. If a request matches a rule, its requirement applies. The requirement specifies which JWT providers should be used. This field is built from a HTTPRoute - `matches` rule that references the Authentication extended filter. When a referenced Authentication specifies - multiple `jwtProviders`, the JWT is considered valid if __any__ of the providers successfully validate the JWT. + `matches` rule that references the AuthenticationFilter. When a referenced Authentication specifies multiple + `jwtProviders`, the JWT is considered valid if __any__ of the providers successfully validate the JWT. -The following JWT Authentication filter `providers` configuration is created from the above Authentication. +The following JWT authentication HTTP filter `providers` configuration is created from the above AuthenticationFilter. ```yaml providers: @@ -226,7 +220,7 @@ providers: timeout: 1s ``` -The following JWT Authentication filter `rules` configuration is created from the above HTTPRoute. +The following JWT authentication HTTP filter `rules` configuration is created from the above HTTPRoute. ```yaml rules: @@ -236,16 +230,16 @@ rules: provider_name: default-example-example ``` -### Example 2: Two HTTPRoutes with Different Authentications +### Example 2: Two HTTPRoutes with Different AuthenticationFilters The following example contains: * Two HTTPRoutes with different hostnames. -* Each HTTPRoute references a different Authentication -* Each Authentication contains a different JWT provider. +* Each HTTPRoute references a different AuthenticationFilter. +* Each AuthenticationFilter contains a different JWT provider. ```yaml -apiVersion: security.gateway.envoyproxy.io/v1alpha1 -kind: Authentication +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: AuthenticationFilter metadata: name: example1 spec: @@ -258,8 +252,8 @@ spec: remoteJwks: uri: https://foo.com/jwt/public-key/jwks.json --- -apiVersion: security.gateway.envoyproxy.io/v1alpha1 -kind: Authentication +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: AuthenticationFilter metadata: name: example2 spec: @@ -291,8 +285,8 @@ spec: filters: - type: ExtensionRef extensionRef: - group: security.gateway.envoyproxy.io - kind: Authentication + group: gateway.envoyproxy.io + kind: AuthenticationFilter name: example1 backendRefs: - name: backend @@ -317,8 +311,8 @@ spec: filters: - type: ExtensionRef extensionRef: - group: security.gateway.envoyproxy.io - kind: Authentication + group: gateway.envoyproxy.io + kind: AuthenticationFilter name: example2 backendRefs: - name: backend2 @@ -435,40 +429,39 @@ __Note:__ The JWT provider cluster and route is omitted from the above example f ### Implementation Outline -* Create a `security` API group and add the Authentication API type to this group. -* Update the Kubernetes provider to get/watch Authentication resources that are referenced by managed HTTPRoutes. Add - the referenced Authentication object to the resource map and publish it. -* Update the resource translator to include the Authentication API in HTTPRoute processing. -* Update the xDS translator to translate an Authentication into xDS resources. The translator should perform the +* Update the Kubernetes provider to get/watch AuthenticationFilter resources that are referenced by managed HTTPRoutes. + Add the referenced AuthenticationFilter object to the resource map and publish it. +* Update the resource translator to include the AuthenticationFilter API in HTTPRoute processing. +* Update the xDS translator to translate an AuthenticationFilter into xDS resources. The translator should perform the following: * Convert a list of JWT rules from the xds IR into an Envoy JWT filter config. - * Create a JWT authentication filter. + * Create a JWT authentication HTTP filter. * Build the HTTP Connection Manager (HCM) HTTP filters. * Build the HCM. * When building the Listener, create an HCM for each filter-chain. -## Adding Authentication Provider Types +## Adding Authentication Types -Additional authentication provider types can be added in the future through the `ProviderType` API. For example, to add -the `Foo` authentication provider type: +Additional authentication types can be added in the future through the `AuthenticationFilterType` API. For +example, to add the `Foo` authentication type: -Define the `FooProvider` type: +Define the `Foo` authentication provider: ```go package v1alpha1 -// FooProvider defines the "Foo" authentication provider type. -type FooProvider struct { - // TODO: Define fields of the Foo authentication provider type. +// FooAuthenticationFilterProvider defines the "Foo" authentication filter provider type. +type FooAuthenticationFilterProvider struct { + // TODO: Define fields of the Foo authentication filter provider type. } ``` -Add the `FooProvider` type to `AuthenticationSpec`: +Add the `FooAuthenticationFilterProvider` type to `AuthenticationFilterSpec`: ```go package v1alpha1 -type AuthenticationSpec struct { +type AuthenticationFilterSpec struct { ... // Foo defines the Foo authentication type. For additional @@ -477,17 +470,30 @@ type AuthenticationSpec struct { // // // +optional - Foo *FooAuthentication `json:"foo"` + Foo *FooAuthenticationFilterProvider } ``` -Authentication should support additional authentication types in the future, for example: +Lastly, add the type to the `AuthenticationType` enum: + +```go +// AuthenticationType is a type of authentication provider. +// +kubebuilder:validation:Enum=JWT,FOO +type AuthenticationFilterType string + +const ( + // JwtAuthenticationProviderType is the JWT authentication provider type. + FooAuthenticationFilterProviderType AuthenticationFilterType = "FOO" +) +``` + +The AuthenticationFilter API should support additional authentication types in the future, for example: - OAuth2 - OIDC ## Outstanding Questions -- If Envoy Gateway owns the Authentication API, is an xDS IR equivalent needed? +- If Envoy Gateway owns the AuthenticationFilter API, is an xDS IR equivalent needed? - Should local JWKS be implemented before remote JWKS? - How should Envoy obtain the trusted CA for a remote JWKS? - Should HTTPS be the only supported scheme for remote JWKS?