Configuring JWT authentication

The NAV API supports authentication with JSON Web Tokens (JWT). JWT issuers that your NAV instance should accept tokens from can be configured in webfront/jwt.conf. The public key for the issuer is required, and can be configured either directly as a PEM file or via a JWKS endpoint.

A configuration for two issuers may look like this:

[https://jwt-issuer1.no] # Name of issuer matching `iss` claim of issued tokens
aud=https://mynav.no # Expected value of the `aud` claim in issued tokens
keytype=JWKS # JWKS endpoint is used as source for public key
key=https://jwt-issuer1.no/jwks # URL to JWKS endpoint

[https://jwt-issuer2.no]
aud=https://mynav.no
keytype=PEM # PEM file is used as source for public key
key=/some/path/public_key.pem # Path to PEM file

Other issuers may be defined by adding additional sections of the same format. It is important to note that the section names must match the iss claim of the tokens generated by this issuer. This is how NAV maps an incoming token to the correct configuration.

Likewise aud must match the aud claim of the tokens. This is a security measure to make sure a NAV instance only accepts tokens meant for it. Otherwise the NAV instance would accept all JWT tokens generated by an issuer. In other words, anyone using the same token issuer could generate tokens and gain access to your NAV instance.

Configuring local JWT token generation

Local JWT token generation is configured in the nav section of webfront/jwt.conf.

You must configure three things: a private key, a public key, and the issuer name. The keys must be a private/public RSA keypair in PEM format. The issuer name is used for the iss and aud claims of generated tokens. The issuer name can be whatever you want, but a natural choice is the domain name of your NAV instance (e.g. nav.example.com). Optionally, you can also configure the lifetime of access tokens and refresh tokens. These can be configured using the units s=seconds, m=minutes, h=hours or d=days. Default values are 1 hour for access tokens and 24 hours for refresh tokens. An example configuration is shown below:

[nav]
# Absolute path to private key in PEM format
private_key=/path/to/jwtRS256.key
# Absolute path to public key in PEM format.
public_key=/path/to/jwtRS256.key.pub
# Used for the 'iss' and 'aud' claims of generated tokens.
name=nav.example.com
#access_token_lifetime=1h
#refresh_token_lifetime=24h

The keypair can be generated like so:

openssl genrsa -out jwtRS256.key 4096
openssl rsa -in jwtRS256.key -pubout -outform PEM -out jwtRS256.key.pub

This keypair should ideally only be used for JWT token generation in one NAV instance. If you are using the same keypair for multiple instances, you should use different issuer names for each instance. That is important because the NAV token validation uses the public key and the aud claim to decide if the token is valid, so if someone else can generate tokens using the same keypair and the same aud claim they can also gain access to your NAV instance.