Skip to content

Private Key JWT

We recommend using private_key_jwt as Client Authentication towards BankID.

As per the standard you must authenticate your application when calling:

or, any other resource APIs (e.g. BankID Signing).

Requirements

In order to use private_key_jwt you need to:

  • generate a keypair
  • build a JWKS according to spec with your public key(s)
  • submit JWKS to BankID support (or update your client in Stø Portal)

Multiple keys per Client

A Client may have multiple keys associated with it (JWKS). They are each distingushed by the kid (Key ID).

This is useful for key rotation.

Generate JWKS

In order to register your public key you need to provide the key in JWKS format.

This format is represented as an array of JWKs under the keys field.

An example JWKS may look like this:

{
  "keys":[
    {
      "kty":"EC",
      "crv":"P-256",
      "alg":"ES256",
      "x":"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4",
      "y":"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM",
      "use":"sig",
      "kid":"fpy9BfdmvVRubt5VN5Ct263YO5dpMi37nd1OKcJIzOQ"
    },
    {
      "kty":"RSA",
      "n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx
4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMs
tn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2
QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbI
SD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqb
w0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
      "e":"AQAB",
      "alg":"RS256",
      "use":"sig",
      "kid":"-b1ua3CUopwJCcLjCGslrpJsLSAFiDVGKK2yLehXMaE"
    }
  ]
}

The requirements for the JWK are:

Claim Description Example
kty key type RSA or EC
alg algorithm ES256 or RS256, but see also token_endpoint_auth_signing_alg_values_supported list of supported algorithms.
use Usage. Must be sig sig
kid Key ID. This you can generate as you wish, but it is important for key rotation. RKylPNVyCN8wIO5L55LnIwV7IPh0sErQQzn--CD1xk8

Then depending on key type you may have the actual key data encoded in fields such as:

  • n and e for RSA
  • crv, x and y for EC

KID generation

One way to generate the KID could be the Base64Url encoded SHA-256 digest of the public key.

Send us the JWKS

After building the JWKS, you can send it to us via a BankID Support case, or use the Stø Portal (depending on access and availability), if you are a partner with us.

We do not support URL to JWKS endpoint. You need to send us the JWKS for the Client.

Usage

Build JWT assertion claim

When you are going to call the Token endpoint (or any other protected resource), you need to:

  • build a JWT according to the table below.
  • sign JWT using a private key.

The requirements for the JWT are:

Claim Required Description
aud yes The endpoint to call. E.g. token endpoint. E.g. https://auth.current.bankid.no/auth/realms/current/protocol/openid-connect/token
sub yes The subject of this token, which is your Client ID. E.g. some-client-bankid-current
iss yes The issuer of this token, which is your Client ID. Same as subject. E.g some-client-bankid-current
jti yes A unique token identifier. Cannot be used several times. E.g. a2a39ffb-4899-43be-9938-560653778cd2
exp yes The token expiration time in seconds since Epoch (UNIX timestamp). E.g. 1759835872
ait no When the token was issued in seconds since Epoch (UNIX timestamp). E.g. 1759815872

Example decoded JWT with header and signature

{
  "typ": "JWT",
  "kid": "-b1ua3CUopwJCcLjCGslrpJsLSAFiDVGKK2yLehXMaE",
  "alg": "RS256"
}
.
{
  "aud" : "https://auth.current.bankid.no/auth/realms/current/protocol/openid-connect/token",
  "iss" : "some-client-bankid-current",
  "sub" : "some-client-bankid-current",
  "jti" : "a3a2fc6e-29e3-4b4d-9284-615982c213c4",
  "exp" : "1759835872",
  "iat" : "1759815872"
}
.
9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGj...

Always add the kid of the key used in the JWT header.

Add client assertion parameters to request

Parameter Description
client_assertion The client assertion is the signed JWT in Base64Url encoding.
client_assertion_type The type of client_assertion. This value is always url encoded urn:ietf:params:oauth:client-assertion-type:jwt-bearer.

Example Token Request with private_key_jwt

POST /auth/realms/current/protocol/openid-connect/token HTTP/1.1
Host: auth.current.bankid.no
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=Gw30fMKJBHkcOBSde5awLrMm4ahvgCNM2cFSTUOUflY
&redirect_uri=https://example.org/callback
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...

Key rotation

We support multiple keys per Client (JWKS) which makes it trivial to rotate the keys when needed.

If you want to add a new key for the Client, just contact BankID support (or your BankID Partner) with the new key as part of the JWKS. Then update it again to remove the old key after minimum 24 hours.

If you need to revoke a key, just contact BankID support (or your BankID Partner) with the revoked key gone, and new key added as part of the JWKS. Mark the ticket it as high priority and add REVOKE to the subject.