Using JWTs in Spring

This section describes the practical aspects of using JSON Web Tokens (JWTs) with the Java/Scala SDKs, if you are not sure what JWTs are, how they work or how to generate them, see JSON Web Tokens first.

Kalix’s JWT support is configured by placing annotations on methods in your endpoints.

Authentication

Kalix can validate the signature of JWT tokens provided in an Authorization header to grant access to your endpoints. Typically, these tokens will be generated in response to an authentication request, e.g. by supplying refresh token, or perhaps a username and password. These tokens may be generated by a third party service such as Auth0. You can find more information about the generating tokens here.

Bearer token validation

If you want to validate the bearer token of a request, you need to annotate your endpoint like:

@PostMapping("/message")
@JWT(validate = JWT.JwtMethodMode.BEARER_TOKEN) (1)
public Action.Effect<String> message(@RequestBody String msg) {
        return effects().reply(msg);
    }
1 Validating the Bearer is present in the Authorization header.

Only requests that have a bearer token that can be validated by one of the configured keys for the service will be allowed, all other requests will be rejected. The bearer token must be supplied with requests using the Authorization header, like:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

If you want to assert that only tokens from a particular issuer are allowed, that be can be done using the bearerTokenIssuer option:

@PostMapping("/message")
@JWT(validate = JWT.JwtMethodMode.BEARER_TOKEN,
 bearerTokenIssuer = "my-issuer")       (1)
public Action.Effect<String> messageWithIssuer(@RequestBody String msg) {
    return effects().reply(msg);
}
1 The token extracted from the bearer token must have this issuer.

It is recommended that this be used in combination with specifying an issuer in your JWT key configuration, otherwise any of the services whose keys you trust may spoof the issuer.

Kalix will place the claims from the validated token into the request metadata, so you can access it from your service. All claims are prefixed with _kalix-jwt-claim-, so for example, if you want to read the subject claim, you can read the metadata entry _kalix-jwt-claim-sub. String claims are passed unquoted. All other claim types, including arrays and objects, are passed using their JSON encoding

Running locally with JWT support

When running locally using docker compose, by default, a dev key with id dev is configured for use. This key uses the JWT none signing algorithm, which means the JWT tokens produced do not contain a cryptographic signature, nor are they validated against a signature when validating. Therefore, when calling an endpoint with a bearer token, only its presence is validated

If you wish to set the issuer for this dev key, you can do that modifying the docker-compose.yml file in your project, setting the JWT_DEV_SECRET_ISSUER environment variable in the kalix-proxy service:

version: "3"
services:
  kalix-proxy:
    ...
    environment:
      JWT_DEV_SECRET_ISSUER: "my-issuer"
      ...