Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
7a3129f
Add jwt auth filter config proto
qiwzhang Mar 8, 2018
30ee783
fix format
qiwzhang Mar 8, 2018
cfefc28
Update per comment
qiwzhang Mar 8, 2018
529471d
use HeaderMatcher
qiwzhang Mar 8, 2018
71a5490
Fix BUILD format
qiwzhang Mar 8, 2018
89720dd
Rename jwt_auth to jwt_authn
qiwzhang Mar 9, 2018
062cdf8
add not-implemented-hide
qiwzhang Mar 9, 2018
f20a77d
Added JwtHeader
qiwzhang Mar 9, 2018
95cfa93
Add allow_missing_jwt
qiwzhang Mar 9, 2018
4bbf204
move allow_failed_jwt to JWT message
qiwzhang Mar 9, 2018
335ec91
Add some default behavious
qiwzhang Mar 10, 2018
2f1aa17
Update comment for jwks
qiwzhang Mar 10, 2018
648cd3e
Add README.md
qiwzhang Mar 13, 2018
42fc1f7
Fix README format
qiwzhang Mar 13, 2018
d5b1617
Added back jwks_uri_cluster
qiwzhang Mar 13, 2018
888073f
Updated to use HttpUri
qiwzhang Mar 15, 2018
ef51a27
Update per comment
qiwzhang Mar 16, 2018
fea7712
Change JWT to JwtRule
qiwzhang Mar 16, 2018
dba79ad
Add validate rule for JwtHeader
qiwzhang Mar 16, 2018
955ddbf
Update README
qiwzhang Mar 16, 2018
cec86ef
Update per comment
qiwzhang Mar 19, 2018
64d6694
remove allow_failed_jwt
qiwzhang Mar 19, 2018
7625319
Fix format to fix column limit of 100
qiwzhang Mar 20, 2018
4ca5e41
remove jwt in field names
qiwzhang Mar 20, 2018
937d521
Update README with changed field names
qiwzhang Mar 20, 2018
b21a927
Update README
qiwzhang Mar 20, 2018
3c8bf24
Update comment for forward_payload_header
qiwzhang Mar 20, 2018
7dfc0f9
rename v2 to v2alpha
qiwzhang Mar 20, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions envoy/config/filter/http/jwt_authn/v2alpha/BUILD
Original file line number Diff line number Diff line change
@@ -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",
],
)
31 changes: 31 additions & 0 deletions envoy/config/filter/http/jwt_authn/v2alpha/README.md
Original file line number Diff line number Diff line change
@@ -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.
226 changes: 226 additions & 0 deletions envoy/config/filter/http/jwt_authn/v2alpha/config.proto
Original file line number Diff line number Diff line change
@@ -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"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

really last nit: make this realistic?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is too big to put a good jwks here

//
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;
}