@@ -139,6 +139,10 @@ type TrafficPolicySpec struct {
139139 // This controls authentication using username/password credentials in the Authorization header.
140140 // +optional
141141 BasicAuth * BasicAuthPolicy `json:"basicAuth,omitempty"`
142+
143+ // APIKeyAuthentication authenticates users based on a configured API Key.
144+ // +optional
145+ APIKeyAuthentication * APIKeyAuthentication `json:"apiKeyAuthentication,omitempty"`
142146}
143147
144148// URLRewrite specifies URL rewrite rules using regular expressions.
@@ -416,6 +420,118 @@ type CSRFPolicy struct {
416420 AdditionalOrigins []shared.StringMatcher `json:"additionalOrigins,omitempty"`
417421}
418422
423+ // APIKeySource defines where to extract the API key from within a single key source.
424+ // Within a single key source, if multiple types are specified, precedence is:
425+ // header > query parameter > cookie. The header is checked first, and only falls back
426+ // to query parameter if the header is not present, then to cookie if both header and query
427+ // are not present.
428+ // +kubebuilder:validation:AtLeastOneOf=header;query;cookie
429+ type APIKeySource struct {
430+ // header specifies the name of the header that contains the API key.
431+ // +optional
432+ // +kubebuilder:validation:MinLength=1
433+ // +kubebuilder:validation:MaxLength=256
434+ Header * string `json:"header,omitempty"`
435+
436+ // query specifies the name of the query parameter that contains the API key.
437+ // +optional
438+ // +kubebuilder:validation:MinLength=1
439+ // +kubebuilder:validation:MaxLength=256
440+ Query * string `json:"query,omitempty"`
441+
442+ // cookie specifies the name of the cookie that contains the API key.
443+ // +optional
444+ // +kubebuilder:validation:MinLength=1
445+ // +kubebuilder:validation:MaxLength=256
446+ Cookie * string `json:"cookie,omitempty"`
447+ }
448+
449+ // +kubebuilder:validation:ExactlyOneOf=secretRef;secretSelector
450+ type APIKeyAuthentication struct {
451+ // keySources specifies the list of key sources to extract the API key from.
452+ // Key sources are processed in array order and the first one that successfully
453+ // extracts a key is used. Within each key source, if multiple types (header, query, cookie) are
454+ // specified, precedence is: header > query parameter > cookie.
455+ //
456+ // If empty, defaults to a single key source with header "api-key".
457+ //
458+ // Example:
459+ // keySources:
460+ // - header: "X-API-KEY"
461+ // - query: "api_key"
462+ // - header: "Authorization"
463+ // query: "token"
464+ // cookie: "auth_token"
465+ //
466+ // In this example, the system will:
467+ // 1. First try header "X-API-KEY"
468+ // 2. If not found, try query parameter "api_key"
469+ // 3. If not found, try header "Authorization" (then query "token", then cookie "auth_token" within that key source)
470+ //
471+ // +kubebuilder:validation:MinItems=0
472+ // +kubebuilder:validation:MaxItems=16
473+ // +optional
474+ KeySources []APIKeySource `json:"keySources,omitempty"`
475+
476+ // forwardCredential controls whether the API key is included in the request sent to the upstream.
477+ // If false (default), the API key is removed from the request before sending to upstream.
478+ // If true, the API key is included in the request sent to upstream.
479+ // This applies to all configured key sources (header, query parameter, or cookie).
480+ // +optional
481+ ForwardCredential * bool `json:"forwardCredential,omitempty"`
482+
483+ // clientIdHeader specifies the header name to forward the authenticated client identifier.
484+ // If not specified, the client identifier will not be forwarded in any header.
485+ // Example: "x-client-id"
486+ // +optional
487+ ClientIdHeader * string `json:"clientIdHeader,omitempty"`
488+
489+ // secretRef references a Kubernetes secret storing a set of API Keys. If there are many keys, 'secretSelector' can be
490+ // used instead.
491+ //
492+ // Each entry in the Secret represents one API Key. The key is an arbitrary identifier.
493+ // The value is a string, representing the API Key.
494+ //
495+ // Example:
496+ //
497+ // apiVersion: v1
498+ // kind: Secret
499+ // metadata:
500+ // name: api-key
501+ // stringData:
502+ // client1: "k-123"
503+ // client2: "k-456"
504+ //
505+ // +optional
506+ SecretRef * gwv1.SecretObjectReference `json:"secretRef,omitempty"`
507+
508+ // secretSelector selects multiple secrets containing API Keys. If the same key is defined in multiple secrets, the
509+ // behavior is undefined.
510+ //
511+ // Each entry in the Secret represents one API Key. The key is an arbitrary identifier.
512+ // The value is a string, representing the API Key.
513+ //
514+ // Example:
515+ //
516+ // apiVersion: v1
517+ // kind: Secret
518+ // metadata:
519+ // name: api-key
520+ // stringData:
521+ // client1: "k-123"
522+ // client2: "k-456"
523+ //
524+ // +optional
525+ SecretSelector * LabelSelector `json:"secretSelector,omitempty"`
526+ }
527+
528+ // LabelSelector selects resources using label selectors.
529+ type LabelSelector struct {
530+ // Label selector to select the target resource.
531+ // +required
532+ MatchLabels map [string ]string `json:"matchLabels"`
533+ }
534+
419535// +kubebuilder:validation:ExactlyOneOf=maxRequestSize;disable
420536type Buffer struct {
421537 // MaxRequestSize sets the maximum size in bytes of a message body to buffer.
0 commit comments