JWT Authentication

Authentication Source

Before configuring a JWT middleware, a JWT Authentication Source must be defined in the static configuration.

Below is an example of a minimal JWT Authentication Source that can be added to a static configuration:

[authSources]
  [authSources.jwtSource]
    [authSources.jwtSource.jwt]
      signingSecret = "super-secret"
authSources:
  jwtSource:
    jwt:
      signingSecret: super-secret

Note

To use base64-encoded signingSecrets, set the signingSecretBase64Encoded option to true.

Authentication Source Options

signingSecret

Optional (one of signingSecret or publicKey must be set), Default=""

The signingSecret option can be set to the secret used for signing the JWT certificates. It is then used by the middleware to verify incoming requests.

[authSources]
  [authSources.jwtSource]
    [authSources.jwtSource.jwt]
      signingSecret = "super-secret"
authSources:
  jwtSource:
    jwt:
      signingSecret: super-secret

signingSecretBase64Encoded

Optional, Default=false

The signingSecretBase64Encoded option can be set to indicate that the signingSecret is base64-encoded. If set to true, the signingSecret will be base64 decoded before being used.

[authSources]
  [authSources.jwtSource]
    [authSources.jwtSource.jwt]
      signingSecret = "c3VwZXItc2VjcmV0Cg=="
      signingSecretBase64Encoded = true
authSources:
  jwtSource:
    jwt:
      signingSecret: c3VwZXItc2VjcmV0Cg==
      signingSecretBase64Encoded: true

publicKey

Optional (one of signingSecret or publicKey must be set), Default=""

The publicKey option can be used as an alternative to a signing secret to verify incoming requests. In that case, users should sign their token using a private key, and the public key can be used to verify the signature.

[authSources]
  [authSources.jwtSource]
    [authSources.jwtSource.jwt]
      publicKey = """
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnzyis1ZjfNB0bBgKFMSv
vkTtwlvBsaJq7S5wA+kzeVOVpVWwkWdVha4s38XM/pa/yr47av7+z3VTmvDRyAHc
aT92whREFpLv9cj5lTeJSibyr/Mrm/YtjCZVWgaOYIhwrXwKLqPr/11inWsAkfIy
tvHWTxZYEcXLgAXFuUuaS3uF9gEiNQwzGTU1v0FqkqTBr4B8nW3HCN47XUu0t8Y0
e+lf4s4OxQawWD79J9/5d3Ry0vbV3Am1FtGJiJvOwRsIfVChDpYStTcHTCMqtvWb
V6L11BWkpzGXSW4Hv43qa+GSYOD2QU68Mb59oSk2OB+BtOLpJofmbGEGgvmwyCI9
MwIDAQAB
-----END PUBLIC KEY-----
"""
authSources:
  jwtSource:
    jwt:
      publicKey:|-
        -----BEGIN PUBLIC KEY-----
        MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnzyis1ZjfNB0bBgKFMSv
        vkTtwlvBsaJq7S5wA+kzeVOVpVWwkWdVha4s38XM/pa/yr47av7+z3VTmvDRyAHc
        aT92whREFpLv9cj5lTeJSibyr/Mrm/YtjCZVWgaOYIhwrXwKLqPr/11inWsAkfIy
        tvHWTxZYEcXLgAXFuUuaS3uF9gEiNQwzGTU1v0FqkqTBr4B8nW3HCN47XUu0t8Y0
        e+lf4s4OxQawWD79J9/5d3Ry0vbV3Am1FtGJiJvOwRsIfVChDpYStTcHTCMqtvWb
        V6L11BWkpzGXSW4Hv43qa+GSYOD2QU68Mb59oSk2OB+BtOLpJofmbGEGgvmwyCI9
        MwIDAQAB
        -----END PUBLIC KEY-----

JWT Middleware

After declaring a JWT Authentication Source in the static configuration of the cluster, JWT middlewares can be added to routers in the dynamic configuration.

The JWT middleware verifies that a token is provided in the Authorization header (Authorization: Bearer <JWT>) of incoming requests or in the query parameters of the request (jwt=<JWT>).

JWT Query Parameter

The JWT query parameter is currently not configurable. Only the jwt query parameter will be checked.

With no specific configuration, a JWT middleware only validates the signature of a JWT and checks the nbf, exp and iat standard claims (if they are present). Custom claim validation can be configured with Custom Claims Validation.

Middleware Options

source

Required, Default=""

The source option should contain the name of the authorization source used by the middleware.

labels:
  - "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.source=jwtSource"
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: test-jwtAuth
spec:
  plugin:
    jwtAuth:
      source: jwtSource
- "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.source=jwtSource"
"labels": {
    "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.source": "jwtSource"
}
labels:
  - "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.source=jwtSource"
[http.middlewares]
  [http.middlewares.test-jwtAuth.plugin.jwtAuth]
    source = "jwtSource"
http:
  middlewares:
    test-jwt:
      plugin:
        jwtAuth:
          source: jwtSource

forwardAuthorization

Optional, Default=false

The forwardAuthorization option determines if the authorization headers will be forwarded or stripped from a request after it has been approved by the middleware.

labels:
  - "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.forwardAuthorization=true"
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: test-jwtAuth
spec:
  plugin:
    jwtAuth:
      forwardAuthorization: true
- "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.forwardAuthorization=true"
"labels": {
    "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.forwardAuthorization": true
}
labels:
  - "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.forwardAuthorization=true"
[http.middlewares]
  [http.middlewares.test-jwtAuth.plugin.jwtAuth]
    forwardAuthorization = true
http:
  middlewares:
    test-jwt:
      plugin:
        jwtAuth:
          forwardAuthorization: true

forwardHeaders

Optional, Default=None

The forwardHeaders option sets the HTTP headers to add to requests and populate them with values extracted from a JWT.

labels:
  - "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.forwardHeaders.Group=grp"
  - "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.forwardHeaders.Expires-At=exp"
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: test-jwtAuth
spec:
  plugin:
    jwtAuth:
      forwardHeaders:
        Group: grp
        Expires-At: exp
- "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.forwardHeaders.Group=grp"
- "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.forwardHeaders.Expires-At=exp"
"labels": {
    "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.forwardHeaders.Group": "grp",
    "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.forwardHeaders.Expires-At": "exp"
}
labels:
  - "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.forwardHeaders.Group=grp"
  - "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.forwardHeaders.Expires-At=exp"
[http.middlewares]
  [http.middlewares.test-jwtAuth.plugin.jwtAuth]
    [http.middlewares.test-jwtAuth.plugin.jwtAuth.forwardHeaders]
      Group = "grp"
      Expires-At = "exp"
http:
  middlewares:
    test-jwt:
      plugin:
        jwtAuth:
          forwardHeaders:
            Group: grp
            Expires-At: exp

claims

Optional, Default=""

The claims option sets claims to validate in order to authorise the request.

labels:
  - "traefik.http.middlewares.test-jwt-auth.plugin.jwtAuth.claims=Equals(`grp`, `admin`)"
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: test-jwt-auth
spec:
  plugin:
    jwtAuth:
      claims: Equals(`grp`, `admin`)
- "traefik.http.middlewares.test-jwt-auth.plugin.jwtAuth.claims=Equals(`grp`, `admin`)"
"labels": {
  "traefik.http.middlewares.test-jwt-auth.plugin.jwtAuth.claims": "Equals(`grp`, `admin`)"
}
labels:
  - "traefik.http.middlewares.test-jwt-auth.plugin.jwtAuth.claims=Equals(`grp`, `admin`)"
[http.middlewares]
  [http.middlewares.test-jwt-auth.plugin.jwtAuth]
    claims = "Equals(`grp`, `admin`)"
http:
  middlewares:
    test-jwt-auth:
      plugin:
        jwtAuth:
          claims: Equals(`grp`, `admin`)
Syntax

The following functions are supported in claims:

Function Description Example
Equals Validated the equality of the value in key with value. Equals(`grp`, `admin`)
Prefix Validates the value in key has the prefix of value. Prefix(`referrer`, `http://example.com`)
Contains (string) Validates the value in key contains value. Contains(`referrer`, `/foo/`)
Contains (array) Validates the key array contains the value. Contains(`areas`, `home`)
SplitContains Validates the value in key contains the value once split by the separator. SplitContains(`scope`, ` `, `writer`)
OneOf Validates the key array contains one of the values. OneOf(`areas`, `office`, `lab`)

All function can be joined by boolean operands. The supported operands are:

Operand Description Example
&& Compares two functions and returns true only if both evaluate to true. Equals(`grp`, `admin`) && Equals(`active`, `true`)
|| Compares two functions and returns true if either evaluate to true. Equals(`grp`, `admin`) || Equals(`active`, `true`)
! Returns false if the function is true, otherwise returns true. !Equals(`grp`, `testers`)

All examples will return true for the following data structure:

{
  "active": true,
  "grp": "admin",
  "scope": "reader writer deploy",
  "referrer": "http://example.com/foo/bar",
  "areas": [
    "office",
    "home"
  ]
}

Advanced Configuration Example

Below is an advanced configuration example using custom claims validation and forward headers:

labels:
  - "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.source=jwtSource"
  - "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.forwardHeaders.Group=grp"
  - "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.forwardHeaders.Expires-At=exp"
  - "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.claims: Equals(`grp`, `admin`)"
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: test-jwtAuth
spec:
  plugin:
    jwtAuth:
      source: jwtSource
      forwardHeaders:
        Group: grp
        Expires-At: exp
      claims: Equals(`grp`, `admin`)
- "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.source=jwtSource"
- "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.forwardHeaders.Group=grp"
- "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.forwardHeaders.Expires-At=exp"
- "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.claims: Equals(`grp`, `admin`)"
"labels": {
    "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.source": "jwtSource",
    "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.forwardHeaders.Group": "grp",
    "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.forwardHeaders.Expires-At": "exp",
    "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.claims": "Equals(`grp`, `admin`)"
}
labels:
  - "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.source=jwtSource"
  - "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.forwardHeaders.Group=grp"
  - "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.forwardHeaders.Expires-At=exp"
  - "traefik.http.middlewares.test-jwtAuth.plugin.jwtAuth.claims: Equals(`grp`, `admin`)"
[http.middlewares]
  [http.middlewares.test-jwtAuth.plugin.jwtAuth]
    source = "jwtSource"
    [http.middlewares.test-jwtAuth.plugin.jwtAuth.forwardHeaders]
      Group = "grp"
      Expires-At = "exp"
    claims = "Equals(`grp`, `admin`)"
http:
  middlewares:
    test-jwt:
      plugin:
        jwtAuth:
          source: jwtSource
          forwardHeaders:
            Group: grp
            Expires-At: exp
          claims: Equals(`grp`, `admin`)