From 2139575afa6591f69e95e5d5cb74aeefe40791ee Mon Sep 17 00:00:00 2001 From: "update-envoy[bot]" <135279899+update-envoy[bot]@users.noreply.github.com> Date: Thu, 9 Nov 2023 16:07:05 +0000 Subject: [PATCH] credential injector: api for credential injector http filter (#27769) Signed-off-by: huabing zhao Signed-off-by: Huabing Zhao Co-authored-by: Andrei Nistor Co-authored-by: Yaroslav Skopets Mirrored from https://github.com/envoyproxy/envoy @ 430a45f94954b07a106eafc30be1bae24a40b3af --- BUILD | 3 + .../filters/http/credential_injector/v3/BUILD | 13 +++ .../v3/credential_injector.proto | 85 +++++++++++++++++++ .../injected_credentials/generic/v3/BUILD | 13 +++ .../generic/v3/generic.proto | 76 +++++++++++++++++ .../injected_credentials/oauth2/v3/BUILD | 14 +++ .../oauth2/v3/oauth2.proto | 70 +++++++++++++++ versioning/BUILD | 3 + 8 files changed, 277 insertions(+) create mode 100644 envoy/extensions/filters/http/credential_injector/v3/BUILD create mode 100644 envoy/extensions/filters/http/credential_injector/v3/credential_injector.proto create mode 100644 envoy/extensions/injected_credentials/generic/v3/BUILD create mode 100644 envoy/extensions/injected_credentials/generic/v3/generic.proto create mode 100644 envoy/extensions/injected_credentials/oauth2/v3/BUILD create mode 100644 envoy/extensions/injected_credentials/oauth2/v3/oauth2.proto diff --git a/BUILD b/BUILD index 9ce02ee5..c1c09803 100644 --- a/BUILD +++ b/BUILD @@ -171,6 +171,7 @@ proto_library( "//envoy/extensions/filters/http/compressor/v3:pkg", "//envoy/extensions/filters/http/connect_grpc_bridge/v3:pkg", "//envoy/extensions/filters/http/cors/v3:pkg", + "//envoy/extensions/filters/http/credential_injector/v3:pkg", "//envoy/extensions/filters/http/csrf/v3:pkg", "//envoy/extensions/filters/http/custom_response/v3:pkg", "//envoy/extensions/filters/http/decompressor/v3:pkg", @@ -262,6 +263,8 @@ proto_library( "//envoy/extensions/http/original_ip_detection/xff/v3:pkg", "//envoy/extensions/http/stateful_session/cookie/v3:pkg", "//envoy/extensions/http/stateful_session/header/v3:pkg", + "//envoy/extensions/injected_credentials/generic/v3:pkg", + "//envoy/extensions/injected_credentials/oauth2/v3:pkg", "//envoy/extensions/internal_redirect/allow_listed_routes/v3:pkg", "//envoy/extensions/internal_redirect/previous_routes/v3:pkg", "//envoy/extensions/internal_redirect/safe_cross_scheme/v3:pkg", diff --git a/envoy/extensions/filters/http/credential_injector/v3/BUILD b/envoy/extensions/filters/http/credential_injector/v3/BUILD new file mode 100644 index 00000000..e9b556d6 --- /dev/null +++ b/envoy/extensions/filters/http/credential_injector/v3/BUILD @@ -0,0 +1,13 @@ +# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py. + +load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") + +licenses(["notice"]) # Apache 2 + +api_proto_package( + deps = [ + "//envoy/config/core/v3:pkg", + "@com_github_cncf_udpa//udpa/annotations:pkg", + "@com_github_cncf_udpa//xds/annotations/v3:pkg", + ], +) diff --git a/envoy/extensions/filters/http/credential_injector/v3/credential_injector.proto b/envoy/extensions/filters/http/credential_injector/v3/credential_injector.proto new file mode 100644 index 00000000..efa16d3a --- /dev/null +++ b/envoy/extensions/filters/http/credential_injector/v3/credential_injector.proto @@ -0,0 +1,85 @@ +syntax = "proto3"; + +package envoy.extensions.filters.http.credential_injector.v3; + +import "envoy/config/core/v3/extension.proto"; + +import "xds/annotations/v3/status.proto"; + +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.filters.http.credential_injector.v3"; +option java_outer_classname = "CredentialInjectorProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/credential_injector/v3;credential_injectorv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; +option (xds.annotations.v3.file_status).work_in_progress = true; + +// [#protodoc-title: Credential Injector] +// [#not-implemented-hide:] +// Credential Injector :ref:`configuration overview `. +// [#extension: envoy.filters.http.credential_injector] + +// Credential Injector injects credentials into outgoing HTTP requests. The filter configuration is used to retrieve the credentials, or +// they can be requested through the OAuth2 client credential grant. The credentials obtained are then injected into the Authorization header +// of the proxied HTTP requests, utilizing either the Basic or Bearer scheme. +// +// If the credential is not present, the request will fail with 401 Unauthorized if fail_if_not_present is set to true. +// +// Notice: This filter is intended to be used for workload authentication, which means that the identity associated with the inserted credential +// is considered as the identity of the workload behind the envoy proxy(in this case, envoy is typically deployed as a sidecar alongside that +// workload). Please note that this filter does not handle end user authentication. Its purpose is solely to authenticate the workload itself. +// +// Here is an example of CredentialInjector configuration with Generic credential, which injects an HTTP Basic Auth credential into the proxied requests. +// +// .. code-block:: yaml +// +// overwrite: true +// fail_if_not_present: true +// credential: +// name: generic_credential +// typed_config: +// "@type": type.googleapis.com/envoy.extensions.injected_credentials.generic.v3.Generic +// credential: +// name: credential +// sds_config: +// path_config_source: +// path: credential.yaml +// header: Authorization +// +// credential.yaml for Basic Auth: +// .. code-block:: yaml +// +// resources: +// - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret" +// name: credential +// generic_secret: +// secret: +// inline_string: "Basic base64EncodedUsernamePassword" +// +// It can also be configured to inject a Bearer token into the proxied requests. +// credential.yaml for Bearer Token: +// .. code-block:: yaml +// +// resources: +// - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret" +// name: credential +// generic_secret: +// secret: +// inline_string: "Bearer myToken" +// +message CredentialInjector { + // Whether to overwrite the value or not if the injected headers already exist. + // Value defaults to false. + bool overwrite = 1; + + // Whether to fail the request if the credential is not present. + // Value defaults to false. + // If set to true, the request will fail with 401 Unauthorized if the credential is not present. + bool fail_if_not_present = 2; + + // The credential to inject into the proxied requests + // TODO add extension-category + config.core.v3.TypedExtensionConfig credential = 3 [(validate.rules).message = {required: true}]; +} diff --git a/envoy/extensions/injected_credentials/generic/v3/BUILD b/envoy/extensions/injected_credentials/generic/v3/BUILD new file mode 100644 index 00000000..01c5e7b7 --- /dev/null +++ b/envoy/extensions/injected_credentials/generic/v3/BUILD @@ -0,0 +1,13 @@ +# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py. + +load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") + +licenses(["notice"]) # Apache 2 + +api_proto_package( + deps = [ + "//envoy/extensions/transport_sockets/tls/v3:pkg", + "@com_github_cncf_udpa//udpa/annotations:pkg", + "@com_github_cncf_udpa//xds/annotations/v3:pkg", + ], +) diff --git a/envoy/extensions/injected_credentials/generic/v3/generic.proto b/envoy/extensions/injected_credentials/generic/v3/generic.proto new file mode 100644 index 00000000..5519ec10 --- /dev/null +++ b/envoy/extensions/injected_credentials/generic/v3/generic.proto @@ -0,0 +1,76 @@ +syntax = "proto3"; + +package envoy.extensions.injected_credentials.generic.v3; + +import "envoy/extensions/transport_sockets/tls/v3/secret.proto"; + +import "xds/annotations/v3/status.proto"; + +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.injected_credentials.generic.v3"; +option java_outer_classname = "GenericProto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/injected_credentials/generic/v3;genericv3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; +option (xds.annotations.v3.file_status).work_in_progress = true; + +// [#protodoc-title: Generic Credential] +// [#not-implemented-hide:] +// [#extension: envoy.injected_credentials.generic] + +// Generic extension can be used to inject HTTP Basic Auth, Bearer Token, or any arbitrary credential +// into the proxied requests. +// The credential will be injected into the specified HTTP request header. +// Example: +// +// .. code-block:: yaml +// +// credential: +// name: generic_credential +// typed_config: +// "@type": type.googleapis.com/envoy.extensions.injected_credentials.generic.v3.Generic +// credential: +// name: credential +// sds_config: +// path_config_source: +// path: credential.yaml +// header: Authorization +// +// credential.yaml for Basic Auth: +// +// .. code-block:: yaml +// +// resources: +// - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret" +// name: credential +// generic_secret: +// secret: +// inline_string: "Basic base64EncodedUsernamePassword" +// +// Refer to [RFC 7617: The 'Basic' HTTP Authentication Scheme](https://www.rfc-editor.org/rfc/rfc7617) for details. +// +// credential.yaml for Bearer Token: +// +// .. code-block:: yaml +// resources: +// - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret" +// name: credential +// generic_secret: +// secret: +// inline_string: "Bearer myToken" +// +// Refer to [RFC 6750: The OAuth 2.0 Authorization Framework: Bearer Token Usage](https://www.rfc-editor.org/rfc/rfc6750) for details. +// +message Generic { + // The SDS configuration for the credential that will be injected to the specified HTTP request header. + // It must be a generic secret. + transport_sockets.tls.v3.SdsSecretConfig credential = 1 + [(validate.rules).message = {required: true}]; + + // The header that will be injected to the HTTP request with the provided credential. + // If not set, filter will default to: ``Authorization`` + string header = 2 + [(validate.rules).string = {well_known_regex: HTTP_HEADER_NAME ignore_empty: true}]; +} diff --git a/envoy/extensions/injected_credentials/oauth2/v3/BUILD b/envoy/extensions/injected_credentials/oauth2/v3/BUILD new file mode 100644 index 00000000..e77e80ce --- /dev/null +++ b/envoy/extensions/injected_credentials/oauth2/v3/BUILD @@ -0,0 +1,14 @@ +# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py. + +load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") + +licenses(["notice"]) # Apache 2 + +api_proto_package( + deps = [ + "//envoy/config/core/v3:pkg", + "//envoy/extensions/transport_sockets/tls/v3:pkg", + "@com_github_cncf_udpa//udpa/annotations:pkg", + "@com_github_cncf_udpa//xds/annotations/v3:pkg", + ], +) diff --git a/envoy/extensions/injected_credentials/oauth2/v3/oauth2.proto b/envoy/extensions/injected_credentials/oauth2/v3/oauth2.proto new file mode 100644 index 00000000..bf898933 --- /dev/null +++ b/envoy/extensions/injected_credentials/oauth2/v3/oauth2.proto @@ -0,0 +1,70 @@ +syntax = "proto3"; + +package envoy.extensions.injected_credentials.oauth2.v3; + +import "envoy/config/core/v3/http_uri.proto"; +import "envoy/extensions/transport_sockets/tls/v3/secret.proto"; + +import "xds/annotations/v3/status.proto"; + +import "udpa/annotations/status.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.injected_credentials.oauth2.v3"; +option java_outer_classname = "Oauth2Proto"; +option java_multiple_files = true; +option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/injected_credentials/oauth2/v3;oauth2v3"; +option (udpa.annotations.file_status).package_version_status = ACTIVE; +option (xds.annotations.v3.file_status).work_in_progress = true; + +// [#protodoc-title: OAuth2 Credential] +// [#not-implemented-hide:] +// [#extension: envoy.injected_credentials.oauth2] + +// OAuth2 extension can be used to retrieve an OAuth2 access token from an authorization server and inject it into the +// proxied requests. +// Currently, only the Client Credentials Grant flow is supported. +// The access token will be injected into the request headers using the ``Authorization`` header as a bearer token. +message OAuth2 { + enum AuthType { + // The ``client_id`` and ``client_secret`` will be sent using HTTP Basic authentication scheme. + BASIC_AUTH = 0; + + // The ``client_id`` and ``client_secret`` will be sent in the URL encoded request body. + // This type should only be used when Auth server does not support Basic authentication. + URL_ENCODED_BODY = 1; + } + + // Credentials to authenticate client to the authorization server. + // Refer to [RFC 6749: The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749#section-2.3) for details. + message ClientCredentials { + // Client ID. + // Refer to [RFC 6749: The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749#section-2.3.1) for details. + string client_id = 1 [(validate.rules).string = {min_len: 1}]; + + // Client secret. + // Refer to [RFC 6749: The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749#section-2.3.1) for details. + transport_sockets.tls.v3.SdsSecretConfig client_secret = 2 + [(validate.rules).message = {required: true}]; + + // The method to use when sending credentials to the authorization server. + // Refer to [RFC 6749: The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749#section-2.3.1) for details. + AuthType auth_type = 3; + } + + // Endpoint on the authorization server to retrieve the access token from. + // Refer to [RFC 6749: The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749#section-3.2) for details. + config.core.v3.HttpUri token_endpoint = 1 [(validate.rules).message = {required: true}]; + + // Optional list of OAuth scopes to be claimed in the authorization request. + // Refer to [RFC 6749: The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749#section-4.4.2) for details. + repeated string scopes = 2; + + oneof flow_type { + option (validate.required) = true; + + // Client Credentials Grant. + // Refer to [RFC 6749: The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749#section-4.4) for details. + ClientCredentials client_credentials = 3; + } +} diff --git a/versioning/BUILD b/versioning/BUILD index fe64655d..1bf483d5 100644 --- a/versioning/BUILD +++ b/versioning/BUILD @@ -109,6 +109,7 @@ proto_library( "//envoy/extensions/filters/http/compressor/v3:pkg", "//envoy/extensions/filters/http/connect_grpc_bridge/v3:pkg", "//envoy/extensions/filters/http/cors/v3:pkg", + "//envoy/extensions/filters/http/credential_injector/v3:pkg", "//envoy/extensions/filters/http/csrf/v3:pkg", "//envoy/extensions/filters/http/custom_response/v3:pkg", "//envoy/extensions/filters/http/decompressor/v3:pkg", @@ -200,6 +201,8 @@ proto_library( "//envoy/extensions/http/original_ip_detection/xff/v3:pkg", "//envoy/extensions/http/stateful_session/cookie/v3:pkg", "//envoy/extensions/http/stateful_session/header/v3:pkg", + "//envoy/extensions/injected_credentials/generic/v3:pkg", + "//envoy/extensions/injected_credentials/oauth2/v3:pkg", "//envoy/extensions/internal_redirect/allow_listed_routes/v3:pkg", "//envoy/extensions/internal_redirect/previous_routes/v3:pkg", "//envoy/extensions/internal_redirect/safe_cross_scheme/v3:pkg",