diff --git a/api/envoy/config/filter/http/common/v1alpha/BUILD b/api/envoy/config/filter/http/common/v1alpha/BUILD new file mode 100644 index 0000000000000..c3374994f7488 --- /dev/null +++ b/api/envoy/config/filter/http/common/v1alpha/BUILD @@ -0,0 +1,12 @@ +load("//bazel:api_build_system.bzl", "api_proto_library") + +licenses(["notice"]) # Apache 2 + +api_proto_library( + name = "common", + srcs = ["config.proto"], + deps = [ + "//envoy/api/v2/core:base", + "//envoy/api/v2/core:http_uri", + ], +) diff --git a/api/envoy/config/filter/http/common/v1alpha/config.proto b/api/envoy/config/filter/http/common/v1alpha/config.proto new file mode 100644 index 0000000000000..cf17a7f8b7fb6 --- /dev/null +++ b/api/envoy/config/filter/http/common/v1alpha/config.proto @@ -0,0 +1,243 @@ +syntax = "proto3"; + +package envoy.config.filter.http.common.v1alpha; + +import "envoy/api/v2/core/base.proto"; +import "envoy/api/v2/core/http_uri.proto"; +import "google/protobuf/duration.proto"; +import "validate/validate.proto"; + +// This message specifies how a JSON Web Token (JWT) can be both verified and how/whether to forward it or not. +// +// Example: +// +// .. code-block:: yaml +// +// verifier: +// issuer: accounts.google.com +// audiences: +// - bookstore_android.apps.googleusercontent.com +// bookstore_web.apps.googleusercontent.com +// remote_jwks: +// - http_uri: +// - uri: https://accounts.google.com/.well-known/openid-configuration +// cluster: google_jwks_cluster +// cache_duration: +// - seconds: 300 +// forwarder: +// forward: true +// forward_payload_header: x-authorization +// +message JwtRule { + // Describes the rules for verifying a JWT. + JwtVerificationRule verifier = 1; + // Describes how to treat a successfuly verified JWT. + JwtForwardingRule forwarder = 2; +} + +// This message specifies how a JSON Web Token (JWT) can be verified. JWT format is defined +// `here `_. Please see `OAuth2.0 +// `_ and `OIDC1.0 `_ for +// the authentication flow. +// +// Example: +// +// .. code-block:: yaml +// +// issuer: https://example.com +// audiences: +// - bookstore_android.apps.googleusercontent.com +// bookstore_web.apps.googleusercontent.com +// remote_jwks: +// - http_uri: +// - uri: https://example.com/.well-known/jwks.json +// cluster: example_jwks_cluster +// cache_duration: +// - seconds: 300 +// +// [#not-implemented-hide:] +message JwtVerificationRule { + // Identifies the principal that issued the JWT. See `here + // `_. Usually a URL or an email address. + // + // Example: https://securetoken.google.com + // Example: 1234567-compute@developer.gserviceaccount.com + // + string issuer = 1 [(validate.rules).string.min_bytes = 1]; + + // The list of JWT `audiences `_. that are + // allowed to access. A JWT containing any of these audiences will be accepted. If not specified, + // will not check audiences in the token. + // + // Example: + // + // .. code-block:: yaml + // + // audiences: + // - bookstore_android.apps.googleusercontent.com + // bookstore_web.apps.googleusercontent.com + // + repeated string audiences = 2; + + // `JSON Web Key Set `_ is needed. to validate + // signature of the JWT. This field specifies where to fetch JWKS. + oneof jwks_source_specifier { + option (validate.required) = true; + + // JWKS can be fetched from remote server via HTTP/HTTPS. This field specifies the remote HTTP + // URI and how the fetched JWKS should be cached. + // + // Example: + // + // .. code-block:: yaml + // + // remote_jwks: + // - http_uri: + // - uri: https://www.googleapis.com/oauth2/v1/certs + // cluster: jwt.www.googleapis.com|443 + // cache_duration: + // - seconds: 300 + // + RemoteJwks remote_jwks = 3; + + // JWKS is in local data source. It could be either in a local file or embedded in the + // inline_string. + // + // Example: local file + // + // .. code-block:: yaml + // + // local_jwks: + // - filename: /etc/envoy/jwks/jwks1.txt + // + // Example: inline_string + // + // .. code-block:: yaml + // + // local_jwks: + // - inline_string: "ACADADADADA" + // + envoy.api.v2.core.DataSource local_jwks = 4; + } + + // Two fields below define where to extract the JWT from an HTTP request. + // + // If no explicit location is specified, the following default locations are tried in order: + // + // 1. The Authorization header using the Bearer schema. See `here + // `_. Example: + // + // Authorization: Bearer . + // + // 2. `access_token` query parameter. See `this + // `_ + // + + // Multiple JWTs can be verified for a request. Each JWT has to be extracted from the locations + // its issuer specified or from the default locations. + + // Specify the HTTP headers to extract JWT token. For examples, following config: + // + // .. code-block:: yaml + // + // from_headers: + // - name: x-goog-iap-jwt-assertion + // + // can be used to extract token from header:: + // + // x-goog-iap-jwt-assertion: . + // + repeated JwtHeader from_headers = 5; + + // JWT is sent in a query parameter. `jwt_params` represents the query parameter names. + // + // For example, if config is: + // + // .. code-block:: yaml + // + // from_params: + // - jwt_token + // + // The JWT format in query parameter is:: + // + // /path?jwt_token= + // + repeated string from_params = 6; +} + +// This message specifies how a JSON Web Token (JWT) should be forwarded or removed from a request. +// +// Example: +// +// .. code-block:: yaml +// +// forward: true +// forward_payload_header: x-authorization +// +// [#not-implemented-hide:] +message JwtForwardingRule { + // If false, the JWT is removed in the request after a success verification. If true, the JWT is + // not removed in the request. Default value is false. + bool forward = 1; + // This field specifies the header name to forward a successfully verified JWT payload to the + // backend. The forwarded data is:: + // + // base64_encoded(jwt_payload_in_JSON) + // + // If it is not specified, the payload will not be forwarded. + // Multiple JWTs in a request from different issuers will be supported. Multiple JWTs from the + // same issuer will not be supported. Each issuer can config this `forward_payload_header`. If + // multiple JWTs from different issuers want to forward their payloads, their + // `forward_payload_header` should be different. + string forward_payload_header = 2; +} + +// This message specifies how to fetch JWKS from remote and how to cache it. +message RemoteJwks { + // The HTTP URI to fetch the JWKS. For example: + // + // .. code-block:: yaml + // + // http_uri: + // - uri: https://www.googleapis.com/oauth2/v1/certs + // cluster: jwt.www.googleapis.com|443 + // + envoy.api.v2.core.HttpUri http_uri = 1; + + // Duration after which the cached JWKS should be expired. If not specified, default cache + // duration is 5 minutes. + google.protobuf.Duration cache_duration = 2; +} + +// This message specifies a header location to extract JWT token. +message JwtHeader { + // The HTTP header name. + string name = 1 [(validate.rules).string.min_bytes = 1]; + + // The value prefix. The value format is "value_prefix" + // For example, for "Authorization: Bearer ", value_prefix="Bearer " with a space at the + // end. + string value_prefix = 2; +} + +// This message specifies a 256-bit secret encoded in base64 form (44 ASCII characters including trailing '='). +message Secret256 { + string value = 1 [(validate.rules).string.min_bytes = 44, (validate.rules).string.max_bytes = 44]; +} + +// This message specifies a secret that can be used for protecting a session token. +// Example: +// +// .. code-block:: yaml +// +// secret: +// aesgcm256: +// value: "YWJjZGVmMDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODk=" +// +// [#not-implemented-hide:] +message SessionSecret { + oneof secret { + // Key for authentically encrypting and decrypting Session Tokens using AES-GCM. + Secret256 aesgcm256 = 1; + } +} diff --git a/api/envoy/config/filter/http/jwt_authn/v2alpha/BUILD b/api/envoy/config/filter/http/jwt_authn/v2alpha/BUILD index cc07bd29bddaa..b4a4474a90ca5 100644 --- a/api/envoy/config/filter/http/jwt_authn/v2alpha/BUILD +++ b/api/envoy/config/filter/http/jwt_authn/v2alpha/BUILD @@ -1,13 +1,12 @@ -licenses(["notice"]) # Apache 2 - load("//bazel:api_build_system.bzl", "api_proto_library") +licenses(["notice"]) # Apache 2 + api_proto_library( name = "jwt_authn", srcs = ["config.proto"], deps = [ - "//envoy/api/v2/core:base", - "//envoy/api/v2/core:http_uri", "//envoy/api/v2/route", + "//envoy/config/filter/http/common/v1alpha:common", ], ) diff --git a/api/envoy/config/filter/http/jwt_authn/v2alpha/config.proto b/api/envoy/config/filter/http/jwt_authn/v2alpha/config.proto index adab17168ddb8..e8329511d0c49 100644 --- a/api/envoy/config/filter/http/jwt_authn/v2alpha/config.proto +++ b/api/envoy/config/filter/http/jwt_authn/v2alpha/config.proto @@ -1,193 +1,50 @@ - syntax = "proto3"; package envoy.config.filter.http.jwt_authn.v2alpha; -import "envoy/api/v2/core/base.proto"; -import "envoy/api/v2/core/http_uri.proto"; import "envoy/api/v2/route/route.proto"; -import "google/protobuf/duration.proto"; -import "validate/validate.proto"; +import "envoy/config/filter/http/common/v1alpha/config.proto"; -// This message specifies how a JSON Web Token (JWT) can be verified. JWT format is defined -// `here `_. Please see `OAuth2.0 -// `_ and `OIDC1.0 `_ for -// the authentication flow. -// -// Example: -// -// .. code-block:: yaml -// -// issuer: https://example.com -// audiences: -// - bookstore_android.apps.googleusercontent.com -// bookstore_web.apps.googleusercontent.com -// remote_jwks: -// - http_uri: -// - uri: https://example.com/.well-known/jwks.json -// cluster: example_jwks_cluster -// cache_duration: -// - seconds: 300 -// +// This is the Envoy HTTP filter config for JWT authentication. // [#not-implemented-hide:] -message JwtRule { - // Identifies the principal that issued the JWT. See `here - // `_. Usually a URL or an email address. - // - // Example: https://securetoken.google.com - // Example: 1234567-compute@developer.gserviceaccount.com - // - string issuer = 1 [(validate.rules).string.min_bytes = 1]; - - // The list of JWT `audiences `_. that are - // allowed to access. A JWT containing any of these audiences will be accepted. If not specified, - // will not check audiences in the token. - // +message JwtAuthentication { + // Map of JWT rules for handling JWT validation and forwarding. + // The Key for each entry MUST exactly match the issuer field defined in the JWTVerificationRule. // Example: // // .. code-block:: yaml // - // audiences: - // - bookstore_android.apps.googleusercontent.com - // bookstore_web.apps.googleusercontent.com - // - repeated string audiences = 2; - - // `JSON Web Key Set `_ is needed. to validate - // signature of the JWT. This field specifies where to fetch JWKS. - oneof jwks_source_specifier { - option (validate.required) = true; - - // JWKS can be fetched from remote server via HTTP/HTTPS. This field specifies the remote HTTP - // URI and how the fetched JWKS should be cached. - // - // Example: - // - // .. code-block:: yaml - // - // remote_jwks: - // - http_uri: - // - uri: https://www.googleapis.com/oauth2/v1/certs - // cluster: jwt.www.googleapis.com|443 - // cache_duration: - // - seconds: 300 - // - RemoteJwks remote_jwks = 3; - - // JWKS is in local data source. It could be either in a local file or embedded in the - // inline_string. - // - // Example: local file - // - // .. code-block:: yaml - // - // local_jwks: - // - filename: /etc/envoy/jwks/jwks1.txt - // - // Example: inline_string - // - // .. code-block:: yaml - // - // local_jwks: - // - inline_string: "ACADADADADA" - // - envoy.api.v2.core.DataSource local_jwks = 4; - } - - // If false, the JWT is removed in the request after a success verification. If true, the JWT is - // not removed in the request. Default value is false. - bool forward = 5; - - // Two fields below define where to extract the JWT from an HTTP request. - // - // If no explicit location is specified, the following default locations are tried in order: - // - // 1. The Authorization header using the Bearer schema. See `here - // `_. Example: - // - // Authorization: Bearer . - // - // 2. `access_token` query parameter. See `this - // `_ - // - - // Multiple JWTs can be verified for a request. Each JWT has to be extracted from the locations - // its issuer specified or from the default locations. - - // Specify the HTTP headers to extract JWT token. For examples, following config: - // - // .. code-block:: yaml - // - // from_headers: - // - name: x-goog-iap-jwt-assertion - // - // can be used to extract token from header:: - // - // x-goog-iap-jwt-assertion: . - // - repeated JwtHeader from_headers = 6; - - // JWT is sent in a query parameter. `jwt_params` represents the query parameter names. - // - // For example, if config is: - // - // .. code-block:: yaml - // - // from_params: - // - jwt_token - // - // The JWT format in query parameter is:: - // - // /path?jwt_token= - // - repeated string from_params = 7; - - // This field specifies the header name to forward a successfully verified JWT payload to the - // backend. The forwarded data is:: - // - // base64_encoded(jwt_payload_in_JSON) - // - // If it is not specified, the payload will not be forwarded. - // Multiple JWTs in a request from different issuers will be supported. Multiple JWTs from the - // same issuer will not be supported. Each issuer can config this `forward_payload_header`. If - // multiple JWTs from different issuers want to forward their payloads, their - // `forward_payload_header` should be different. - string forward_payload_header = 8; -} - -// This message specifies how to fetch JWKS from remote and how to cache it. -message RemoteJwks { - // The HTTP URI to fetch the JWKS. For example: - // - // .. code-block:: yaml - // - // http_uri: - // - uri: https://www.googleapis.com/oauth2/v1/certs - // cluster: jwt.www.googleapis.com|443 - // - envoy.api.v2.core.HttpUri http_uri = 1; - - // Duration after which the cached JWKS should be expired. If not specified, default cache - // duration is 5 minutes. - google.protobuf.Duration cache_duration = 2; -} - -// This message specifies a header location to extract JWT token. -message JwtHeader { - // The HTTP header name. - string name = 1 [(validate.rules).string.min_bytes = 1]; - - // The value prefix. The value format is "value_prefix" - // For example, for "Authorization: Bearer ", value_prefix="Bearer " with a space at the - // end. - string value_prefix = 2; -} - -// This is the Envoy HTTP filter config for JWT authentication. -// [#not-implemented-hide:] -message JwtAuthentication { - // List of JWT rules to valide. - repeated JwtRule rules = 1; + // accounts.google.com: + // verifier: + // issuer: accounts.google.com + // audiences: + // - bookstore_android.apps.googleusercontent.com + // bookstore_web.apps.googleusercontent.com + // remote_jwks: + // - http_uri: + // - uri: https://accounts.google.com/.well-known/openid-configuration + // cluster: google_jwks_cluster + // cache_duration: + // - seconds: 300 + // forwarder: + // forward: true + // forward_payload_header: x-google-token + // accounts.acme.com: + // verifier: + // issuer: accounts.acme.com + // audiences: + // - bookstore.acme.com + // remote_jwks: + // - http_uri: + // - uri: https://accounts.acme.com/.well-known/openid-configuration + // cluster: acme_jwks_cluster + // cache_duration: + // - seconds: 600 + // forwarder: + // forward: true + // forward_payload_header: x-acme-token + // + map rules = 1; // If true, the request is allowed if JWT is missing or JWT verification fails. // Default is false, a request without JWT or failed JWT verification is not allowed. diff --git a/api/envoy/config/filter/http/oidc/v1alpha/BUILD b/api/envoy/config/filter/http/oidc/v1alpha/BUILD new file mode 100644 index 0000000000000..8aafbc67889d2 --- /dev/null +++ b/api/envoy/config/filter/http/oidc/v1alpha/BUILD @@ -0,0 +1,13 @@ +load("//bazel:api_build_system.bzl", "api_proto_library") + +licenses(["notice"]) # Apache 2 + +api_proto_library( + name = "oidc", + srcs = ["config.proto"], + deps = [ + "//envoy/api/v2/core:base", + "//envoy/api/v2/core:http_uri", + "//envoy/config/filter/http/common/v1alpha:common", + ], +) diff --git a/api/envoy/config/filter/http/oidc/v1alpha/config.proto b/api/envoy/config/filter/http/oidc/v1alpha/config.proto new file mode 100644 index 0000000000000..ff1d7a3f30de9 --- /dev/null +++ b/api/envoy/config/filter/http/oidc/v1alpha/config.proto @@ -0,0 +1,127 @@ +syntax = "proto3"; + +package envoy.config.filter.http.oidc.v1alpha; + +import "envoy/api/v2/core/base.proto"; +import "envoy/api/v2/core/http_uri.proto"; +import "envoy/api/v2/route/route.proto"; +import "envoy/config/filter/http/common/v1alpha/config.proto"; +import "validate/validate.proto"; + +// This message describes the client-side configuration for interfacing with +// an OpenID Connect Provider (OP). +message OidcProvider { + // Identifies the principal that issued the JWT. See `here + // `_. Usually a URL or an email address. + // + // Example: https://securetoken.google.com + // Example: 1234567-compute@developer.gserviceaccount.com + // + envoy.config.filter.http.common.v1alpha.JwtVerificationRule issuer; + + // `JSON Web Key Set `_ is needed. to validate + // signature of the JWT. This field specifies where to fetch JWKS. + envoy.config.filter.http.common.v1alpha.JwksSource jwks_source_specifier = 2; + + // Identifies the authorization endpoint for initiating an OpenID Connect authentication flow. + envoy.api.v2.core.HttpUri authorization_endpoint = 3; + + // Identifies the token endpoint for requesting authorization and id_tokens. + envoy.api.v2.core.HttpUri token_endpoint = 4; +} + +// This message describes the client configuration required for an OpenID Connect client. +// [#not-implemented-hide:] +message OidcClient { + // Identity of the OpenID Connect client. + // + // Example: ABCDEF1267 + string client_id = 1 [(validate.rules).string.min_bytes = 1]; + + // The client's secret for authenticating with an OP. + // + // Example: ABCDEF1267 + string client_secret = 2 [(validate.rules).string.min_bytes = 1]; +} + +// This message describes the configuration options for the OpenID Connect +// filter. +message OidcFilter { + // The filter's provider configuration. + // + // Example: + // + // .. code-block:: yaml + // + // issuer: https://securetoken.google.com + // jwks_source_specifier: + // remote_jwks: + // - http_uri: + // - uri: https://www.googleapis.com/oauth2/v1/certs + // cluster: jwt.www.googleapis.com|443 + // cache_duration: + // - seconds: 300 + // authorization_endpoint: + // - uri: https://www.googleapis.com/oauth2/v1/authorization + // cluster: jwt.www.googleapis.com|443 + // token_endpoint: + // - uri: https://www.googleapis.com/oauth2/v1/tokens + // cluster: jwt.www.googleapis.com|443 + // + OidcProvider provider = 1; + // The filter's client configuration. + // + // Example: + // + // .. code-block:: yaml + // + // client_id: ABCDEF + // client_secret: 0123456789ABCDEF + // + OidcClient client = 2; + // The configuation to use to secure the acquired JWT for use as a session token. + // + // Example: + // + // .. code-tblock:: yaml + // + // aesgcm256: + // secret: "YWJjZGVmMDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODk=" + // + envoy.config.filter.http.common.v1alpha.SessionSecret session = 3; + // This field indicates the landing page browsers will get redirected to upon successful authentication. + // Examples: bypass all CORS options requests + // + // .. code-block:: yaml + // + // landing_page: /home + // + string landing_page = 4; + // This field lists the patterns allowed to bypass OIDC authentication. + // + // Examples: bypass all CORS options requests + // + // .. code-block:: yaml + // + // bypass: + // - headers: + // - name: :method + // value: OPTIONS + // - headers: + // - name: :path + // regex_match: /.* + // + // Examples: bypass /healthz check + // + // .. code-block:: yaml + // + // bypass: + // - headers: + // - name: :method + // value: GET + // - headers: + // - name: :path + // exact_match: /healthz + // + repeated envoy.api.v2.route.RouteMatch bypass = 5; +}