Skip to content

Commit

Permalink
feat: add support to extract from different identifier on JWT (envo…
Browse files Browse the repository at this point in the history
…yproxy#2206)

* feat: introduce FromHeaders, FromCookies, and FromParams field to JWT

Signed-off-by: Ardika Bagus <me@ardikabs.com>

* test: add test for JWT custom extractor

Signed-off-by: Ardika Bagus <me@ardikabs.com>

* chore: trigger generate and manifest generation

Signed-off-by: Ardika Bagus <me@ardikabs.com>

* chore: add comment for JWTFromHeader attributes

Signed-off-by: Ardika Bagus <me@ardikabs.com>

* chore: rename field to extractFrom

Signed-off-by: Ardika Bagus <me@ardikabs.com>

* chore: exclude Params and Headers attribute

prefer use case driven development which
we have no needs for having different JWT extraction
from either Params and Headers the default
which is Authorization HTTP Header or
access_token query parameters.

Signed-off-by: Ardika Bagus <me@ardikabs.com>

* docs: add doc string for JWTExtractor.Cookies if specified

Signed-off-by: Ardika Bagus <me@ardikabs.com>

---------

Signed-off-by: Ardika Bagus <me@ardikabs.com>
  • Loading branch information
ardikabs authored Nov 22, 2023
1 parent 457194f commit 87bc96f
Show file tree
Hide file tree
Showing 13 changed files with 703 additions and 1 deletion.
17 changes: 16 additions & 1 deletion api/v1alpha1/jwt_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,13 @@ type JWTProvider struct {
// The claim must be of type; string, int, double, bool. Array type claims are not supported
//
ClaimToHeaders []ClaimToHeader `json:"claimToHeaders,omitempty"`
// TODO: Add TBD JWT fields based on defined use cases.

// ExtractFrom defines different ways to extract the JWT token from HTTP request.
// If empty, it defaults to extract JWT token from the Authorization HTTP request header using Bearer schema
// or access_token from query parameters.
//
// +optional
ExtractFrom *JWTExtractor `json:"extractFrom,omitempty"`
}

// RemoteJWKS defines how to fetch and cache JSON Web Key Sets (JWKS) from a remote
Expand All @@ -81,3 +87,12 @@ type ClaimToHeader struct {
// to separate the JSON name path.
Claim string `json:"claim"`
}

// JWTExtractor defines a custom JWT token extraction from HTTP request.
type JWTExtractor struct {
// Cookies represents a list of cookie names to extract the JWT token from.
// If specified, Envoy will extract the JWT token from the listed cookies and validate each of them.
// If any cookie is found to be an invalid JWT, a 401 error will be returned.
//
Cookies []string `json:"cookies,omitempty"`
}
25 changes: 25 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,23 @@ spec:
- header
type: object
type: array
extractFrom:
description: ExtractFrom defines different ways to extract
the JWT token from HTTP request. If empty, it defaults
to extract JWT token from the Authorization HTTP request
header using Bearer schema or access_token from query
parameters.
properties:
cookies:
description: Cookies represents a list of cookie names
to extract the JWT token from. If specified, Envoy
will extract the JWT token from the listed cookies
and validate each of them. If any cookie is found
to be an invalid JWT, a 401 error will be returned.
items:
type: string
type: array
type: object
issuer:
description: Issuer is the principal that issued the JWT
and takes the form of a URL or email address. For additional
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
namespace: envoy-gateway
name: gateway-1
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
namespace: envoy-gateway
name: gateway-2
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
grpcRoutes:
- apiVersion: gateway.networking.k8s.io/v1alpha2
kind: GRPCRoute
metadata:
namespace: default
name: grpcroute-1
spec:
parentRefs:
- namespace: envoy-gateway
name: gateway-1
sectionName: http
rules:
- backendRefs:
- name: service-1
port: 8080
httpRoutes:
- apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: default
name: httproute-1
spec:
hostnames:
- gateway.envoyproxy.io
parentRefs:
- namespace: envoy-gateway
name: gateway-2
sectionName: http
rules:
- matches:
- path:
value: "/"
backendRefs:
- name: service-1
port: 8080
securityPolicies:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
namespace: envoy-gateway
name: policy-for-gateway
spec:
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: gateway-1
namespace: envoy-gateway
jwt:
providers:
- name: example1
issuer: https://one.example.com
audiences:
- one.foo.com
remoteJWKS:
uri: https://one.example.com/jwt/public-key/jwks.json
claimToHeaders:
- header: one-route-example-key
claim: claim1
- name: example2
issuer: https://two.example.com
audiences:
- two.foo.com
remoteJWKS:
uri: https://two.example.com/jwt/public-key/jwks.json
claimToHeaders:
- header: two-route-example-key
claim: claim2
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
namespace: default
name: policy-for-route
spec:
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
name: httproute-1
namespace: default
jwt:
providers:
- name: example3
issuer: https://three.example.com
audiences:
- three.foo.com
remoteJWKS:
uri: https://three.example.com/jwt/public-key/jwks.json
claimToHeaders:
- header: three-route-example-key
claim: claim3
extractFrom:
cookies:
- session_access_token
Loading

0 comments on commit 87bc96f

Please sign in to comment.