JWT Security

What does it do?

On incoming requests, the gm-jwt-security filter creates a jwt token 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 code.

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 cookies or access tokens.

  • 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.

*The maximum header size is the size of all headers added together. This was tested and verified locally. see [Envoy docs for more info](https://www.envoyproxy.io/docs/envoy/v1.10.0/api-v2/config/filter/network/http_connection_manager/v2/http_connection_manager.proto.html?highlight=header%20size).

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

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 docs for more information.

timeoutMs

int

1000

--

Timeout in milliseconds for the connection between gm-proxy and gm-jwt-security service

maxRetries

int

0

--

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

retryDelayMs

int

200

--

Amount of time in milliseconds between each unsuccessful retry

Full Request Workflow

  • Makes a request to $GM_SENSE_ENDPOINT/policies to get a jwt token for the user.

    • In the request, userpolicyid will be the USER_DN from the incoming request.

    • api-key is be a preconfigured api token for each sidecar to interact with gm-jwt-security.

  • Process the response from gm-jwt-security.

    • If unsuccessful, return a 401 error.

    • If successful, set the jwt header to the returned token value.

image

Last updated

Was this helpful?