JWT Security

On incoming requests, the gm-jwt-security filter creates a jwt tokenarrow-up-right from the gm-jwt-security service "/policies" endpoint using the incoming USER_DN. It passes the token along with the request in a jwt header.

Gotchas

Ordering

When using TLS and, in most instances, this filter should be applied after inheaders and impersonation. This is because the userpolicyid sent to the gm-jwt-security is taken from the USER_DN header. If the gm-jwt-security filter is applied before those headers, it could retrieve a token for the wrong USER_DN associated with the request, or you will receive a 407 response and see the error

gm-proxy_1_3c03fda44591 | {"level":"error","filter":"gm-jwt-security","error":"USER_DN must be present to retrieve jwt token from gm-jwt-security","time":"2020-01-30T17:58:37Z","message":"DecodeHeaders() - retrieving USER_DN header"}

Header Length

Something to be careful of is the maximum size of headers allowed, as this can differ substantially between deployments. By default, the maximum header size for incoming requests is 60kb.* In production, we suggest a header size of no more than 30kb, as gm-proxy dynamically adds, updates, and removes header values while processing filters. If a request header is too large for the proxy to handle, it will return the request with a 431 response codearrow-up-right.

30kb should support most jwt token sizes since the average jwt token from gm-jwt-security is about 500 bytes. If this is still too small for your header, you can consider:

  • Set the parameter max_request_headers_kb to 96 in the envoy.http_connection_manager section of the proxy.**

  • Using an alternative approach to jwt authentication such as cookiesarrow-up-right or access tokensarrow-up-right.

  • Process access control information within the sidecar.

Note that for outgoing requests from the gm-proxy, the maximum request header size is about 1mb. This means that in some scenarios it's possible for a large jwt token to be added to outgoing headers but fail as an upstream request to another sidecar. Alternatively, the request could also succeed as an upstream request to external service, depending on the implementation.

* In testing, http/1.1 requests increase nicely to 96 KB (98,100 chars in header) but gRPC and http/2 requests start failing after a max of 74 KB. This could be because different protocols use different header compression algorithmsarrow-up-right*

Filter Configuration Options

Name
Type
Default
Example
Description

apiKey

string

[empty]

MTIzCg==

Api key used in request to gm-jwt-security

endpoint

string

[empty]

Endpoint of gm-jwt-security

jwtHeaderName

string

"jwt"

"custom-header-name"

Header in which the jwt token is put

useTls

bool

false

--

Should the filter use certs in connecting to gm-jwt-security?

certPath

string

"./certs/server.crt"

--

Certificate path

keyPath

string

"./certs/server.key"

--

Keyfile path

caPath

string

"./certs/intermediate.crt"

--

Certificate authority or intermediate certificate path

insecureSkipVerify

bool

false

--

Should calls to gm-jwt-security require hostname verification in certs? Should be used only for testing. See go docsarrow-up-right for more information.

timeoutMs

int

1000ms

--

Timeout in milliseconds for the connection between gm-proxy and gm-jwt-security service. Set to a negative number to disable timeouts completely, though this is not advised as it can cause an infinite hang in the sidecar.

maxRetries

int

0

--

Number of retries after failed connection between gm-proxy and gm-jwt-security service

retryDelayMs

int

0

--

Amount of time in milliseconds between each unsuccessful retry

cacheLimit

int

100

--

Maximum number of tokens held in cache. If negative, caching is disabled, must be > 0 to enable caching

cachedTokenExp

int

10m

--

Time in minutes to hold tokens in the cache. If negative, caching is disabled, must be > 0 to enable caching

Flow Chart

Last updated

Was this helpful?