diff --git a/api/v1alpha1/authenticationfilter_types.go b/api/v1alpha1/authenticationfilter_types.go new file mode 100644 index 0000000000..8770c2fb2b --- /dev/null +++ b/api/v1alpha1/authenticationfilter_types.go @@ -0,0 +1,126 @@ +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +//+kubebuilder:object:root=true + +type AuthenticationFilter struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired state of the AuthenticationFilter type. + Spec AuthenticationFilterSpec `json:"spec"` + + // Note: The status sub-resource has been excluded but may be added in the future. +} + +// AuthenticationFilterSpec defines the desired state of the AuthenticationFilter type. +// +union +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 AuthenticationFilterType `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 []JwtAuthenticationFilterProvider `json:"jwtProviders,omitempty"` +} + +// AuthenticationFilterType is a type of authentication provider. +// +kubebuilder:validation:Enum=JWT +type AuthenticationFilterType string + +const ( + // JwtAuthenticationFilterProviderType is the JWT authentication provider type. + JwtAuthenticationFilterProviderType AuthenticationFilterType = "JWT" +) + +// JwtAuthenticationFilterProvider defines the JSON Web Token (JWT) authentication provider type +// and how JWTs should be verified: +type JwtAuthenticationFilterProvider 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. When using an HTTPS endpoint, + // Envoy's system trust bundle is used to validate the server certificate. + // + // Example: + // uri: https://www.foo.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. +} + +//+kubebuilder:object:root=true + +// AuthenticationList contains a list of Authentication. +type AuthenticationList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []AuthenticationFilter `json:"items"` +} + +func init() { + SchemeBuilder.Register(&AuthenticationFilter{}, &AuthenticationList{}) +} diff --git a/api/v1alpha1/groupversion_info.go b/api/v1alpha1/groupversion_info.go new file mode 100644 index 0000000000..26c969c6d2 --- /dev/null +++ b/api/v1alpha1/groupversion_info.go @@ -0,0 +1,26 @@ +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + +// Package v1alpha1 contains API Schema definitions for the gateway.envoyproxy.io API group. +// +//+kubebuilder:object:generate=true +//+groupName=gateway.envoyproxy.io +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "gateway.envoyproxy.io", Version: "v1alpha1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..8d470935d8 --- /dev/null +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,131 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthenticationFilter) DeepCopyInto(out *AuthenticationFilter) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthenticationFilter. +func (in *AuthenticationFilter) DeepCopy() *AuthenticationFilter { + if in == nil { + return nil + } + out := new(AuthenticationFilter) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AuthenticationFilter) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthenticationFilterSpec) DeepCopyInto(out *AuthenticationFilterSpec) { + *out = *in + if in.JwtProviders != nil { + in, out := &in.JwtProviders, &out.JwtProviders + *out = make([]JwtAuthenticationFilterProvider, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthenticationFilterSpec. +func (in *AuthenticationFilterSpec) DeepCopy() *AuthenticationFilterSpec { + if in == nil { + return nil + } + out := new(AuthenticationFilterSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AuthenticationList) DeepCopyInto(out *AuthenticationList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]AuthenticationFilter, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthenticationList. +func (in *AuthenticationList) DeepCopy() *AuthenticationList { + if in == nil { + return nil + } + out := new(AuthenticationList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AuthenticationList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *JwtAuthenticationFilterProvider) DeepCopyInto(out *JwtAuthenticationFilterProvider) { + *out = *in + if in.Audiences != nil { + in, out := &in.Audiences, &out.Audiences + *out = make([]string, len(*in)) + copy(*out, *in) + } + out.RemoteJWKS = in.RemoteJWKS +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JwtAuthenticationFilterProvider. +func (in *JwtAuthenticationFilterProvider) DeepCopy() *JwtAuthenticationFilterProvider { + if in == nil { + return nil + } + out := new(JwtAuthenticationFilterProvider) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RemoteJWKS) DeepCopyInto(out *RemoteJWKS) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RemoteJWKS. +func (in *RemoteJWKS) DeepCopy() *RemoteJWKS { + if in == nil { + return nil + } + out := new(RemoteJWKS) + in.DeepCopyInto(out) + return out +} diff --git a/internal/provider/kubernetes/config/crd/bases/gateway.envoyproxy.io_authenticationfilters.yaml b/internal/provider/kubernetes/config/crd/bases/gateway.envoyproxy.io_authenticationfilters.yaml new file mode 100644 index 0000000000..d590025854 --- /dev/null +++ b/internal/provider/kubernetes/config/crd/bases/gateway.envoyproxy.io_authenticationfilters.yaml @@ -0,0 +1,106 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: authenticationfilters.gateway.envoyproxy.io +spec: + group: gateway.envoyproxy.io + names: + kind: AuthenticationFilter + listKind: AuthenticationFilterList + plural: authenticationfilters + singular: authenticationfilter + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of the AuthenticationFilter + type. + properties: + jwtProviders: + description: "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: \n https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/jwt_authn_filter.html" + items: + description: 'JwtAuthenticationFilterProvider defines the JSON Web + Token (JWT) authentication provider type and how JWTs should be + verified:' + properties: + audiences: + description: "Audiences is a list of JWT audiences allowed to + access. For additional details, see: \n https://tools.ietf.org/html/rfc7519#section-4.1.3 + \n Example: audiences: - foo.apps.example.com bar.apps.example.com + \n If not provided, JWT audiences are not checked." + items: + type: string + maxItems: 8 + type: array + issuer: + description: "Issuer is the principal that issued the JWT.\tFor + additional details, see: \n https://tools.ietf.org/html/rfc7519#section-4.1.1 + \n Example: issuer: https://auth.example.com \n If not provided, + the JWT issuer is not checked." + maxLength: 253 + type: string + name: + description: 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. + maxLength: 253 + minLength: 1 + type: string + remoteJWKS: + description: RemoteJWKS defines how to fetch and cache JSON + Web Key Sets (JWKS) from a remote HTTP/HTTPS endpoint. + properties: + uri: + description: "URI is the HTTP/HTTPS URI to fetch the JWKS. + When using an HTTPS endpoint, Envoy's system trust bundle + is used to validate the server certificate. \n Example: + uri: https://www.foo.com/oauth2/v1/certs" + maxLength: 253 + minLength: 1 + type: string + required: + - uri + type: object + required: + - name + - remoteJWKS + type: object + maxItems: 4 + type: array + type: + description: "Type defines the type of authentication provider to + use. Supported provider types are: \n * JWT: A provider that uses + JSON Web Token (JWT) for authenticating requests." + enum: + - JWT + type: string + required: + - type + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/tools/make/kube.mk b/tools/make/kube.mk index d0d55d22f5..234740e21a 100644 --- a/tools/make/kube.mk +++ b/tools/make/kube.mk @@ -31,7 +31,7 @@ manifests: $(tools/controller-gen) ## Generate WebhookConfiguration, ClusterRole generate: $(tools/controller-gen) ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. # Note that the paths can't just be "./..." with the header file, or the tool will panic on run. Sorry. @$(LOG_TARGET) - $(tools/controller-gen) $(CONTROLLERGEN_OBJECT_FLAGS) paths="{$(ROOT_DIR)/api/config/...,$(ROOT_DIR)/internal/ir/...,$(ROOT_DIR)/internal/gatewayapi/...}" + $(tools/controller-gen) $(CONTROLLERGEN_OBJECT_FLAGS) paths="{$(ROOT_DIR)/api/...,$(ROOT_DIR)/internal/ir/...,$(ROOT_DIR)/internal/gatewayapi/...}" .PHONY: kube-test kube-test: manifests generate $(tools/setup-envtest) ## Run Kubernetes provider tests.