Add jwt auth filter config proto (#530)
This is the first step to upstream Istio JWT auth filter to Envoy. Istio JWT auth filter is here [https://github.com/istio/proxy/tree/master/src/envoy/http/jwt_auth] The issue to upstream to envoy is: envoyproxy/envoy#2514 Signed-off-by: Wayne Zhang <qiwzhang@google.com>pull/563/head
parent
e73b8264a2
commit
11c750628b
3 changed files with 270 additions and 0 deletions
@ -0,0 +1,13 @@ |
|||||||
|
licenses(["notice"]) # Apache 2 |
||||||
|
|
||||||
|
load("//bazel:api_build_system.bzl", "api_proto_library") |
||||||
|
|
||||||
|
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", |
||||||
|
], |
||||||
|
) |
@ -0,0 +1,31 @@ |
|||||||
|
# JWT Authentication HTTP filter config |
||||||
|
|
||||||
|
## Overview |
||||||
|
|
||||||
|
1. The proto file in this folder defines an HTTP filter config for "jwt_authn" filter. |
||||||
|
|
||||||
|
2. This filter will verify the JWT in the HTTP request as: |
||||||
|
- The signature should be valid |
||||||
|
- JWT should not be expired |
||||||
|
- Issuer and audiences are valid and specified in the filter config. |
||||||
|
|
||||||
|
3. [JWK](https://tools.ietf.org/html/rfc7517#appendix-A) is needed to verify JWT signature. It can be fetched from a remote server or read from a local file. If the JWKS is fetched remotely, it will be cached by the filter. |
||||||
|
|
||||||
|
3. If a JWT is valid, the user is authenticated and the request will be forwarded to the backend server. If a JWT is not valid, the request will be rejected with an error message. |
||||||
|
|
||||||
|
## The locations to extract JWT |
||||||
|
|
||||||
|
JWT will be extracted from the HTTP headers or query parameters. The default location is the HTTP header: |
||||||
|
``` |
||||||
|
Authorization: Bearer <token> |
||||||
|
``` |
||||||
|
The next default location is in the query parameter as: |
||||||
|
``` |
||||||
|
?access_token=<TOKEN> |
||||||
|
``` |
||||||
|
|
||||||
|
If a custom location is desired, `from_headers` or `from_params` can be used to specify custom locations to extract JWT. |
||||||
|
|
||||||
|
## HTTP header to pass sucessfully verified JWT |
||||||
|
|
||||||
|
If a JWT is valid, its payload will be passed to the backend in a new HTTP header specified in `forward_payload_header` field. Its value is base64 encoded JWT payload in JSON. |
@ -0,0 +1,226 @@ |
|||||||
|
|
||||||
|
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"; |
||||||
|
|
||||||
|
// This message specifies how a JSON Web Token (JWT) can be verified. JWT format is defined |
||||||
|
// `here <https://tools.ietf.org/html/rfc7519>`_. Please see `OAuth2.0 |
||||||
|
// <https://tools.ietf.org/html/rfc6749>`_ and `OIDC1.0 <http://openid.net/connect>`_ 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 JwtRule { |
||||||
|
// Identifies the principal that issued the JWT. See `here |
||||||
|
// <https://tools.ietf.org/html/rfc7519#section-4.1.1>`_. 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 <https://tools.ietf.org/html/rfc7519#section-4.1.3>`_. 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 <https://tools.ietf.org/html/rfc7517#appendix-A>`_ 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 |
||||||
|
// <https://tools.ietf.org/html/rfc6750#section-2.1>`_. Example: |
||||||
|
// |
||||||
|
// Authorization: Bearer <token>. |
||||||
|
// |
||||||
|
// 2. `access_token` query parameter. See `this |
||||||
|
// <https://tools.ietf.org/html/rfc6750#section-2.3>`_ |
||||||
|
// |
||||||
|
|
||||||
|
// 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: <JWT>. |
||||||
|
// |
||||||
|
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=<JWT> |
||||||
|
// |
||||||
|
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<token>" |
||||||
|
// For example, for "Authorization: Bearer <token>", 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; |
||||||
|
|
||||||
|
// 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. |
||||||
|
bool allow_missing_or_failed = 2; |
||||||
|
|
||||||
|
// This field lists the patterns allowed to bypass JWT verification. This only applies when |
||||||
|
// `allow_missing_or_failed_jwt` is false. Under this config, if a request doesn't have JWT, it |
||||||
|
// will be rejected. But some requests still needed to be forwarded without JWT, such as OPTIONS |
||||||
|
// for CORS and some health checking paths. |
||||||
|
// |
||||||
|
// 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 = 3; |
||||||
|
} |
Loading…
Reference in new issue