Client JWK Requirements

Clients are expected to provide public keys to Singpass in the JWK format. These public keys will be used in the following (non-exhaustive) scenarios:

The client must provide the public key(s) during onboarding, and they can do so only via ONE of the following forms:

  • Provide a JWKS in a JSON format.

  • Host the JWKS on a publicly accessible URL. This endpoint must be compatible with Singpass's service level expectations.

Signing key is always required for both direct and direct_pii_allowed clients. Encryption key is only required for direct_pii_allowed clients. direct_pii_allowed clients must ensure that the provided JWKS or the resource returned by the JWKS URL contains both the signing and encryption keys.

TIP: mkjwk.org is a useful open-source tool to generate different types of JWK for signing and encryption; compliant with Singpass's broad requirements on structure. While we DO NOT suggest this as a secure way to generate your real keypair (including private key); this can be a useful tool to understand how JWK works; and how it is represented for signing and encryption purposes; while you are reviewing against our supported algorithms below.

JWK for signing

The signing JWK will be used to verify the client assertion JWT provided during /token request, thereby authenticating the client.

Clients are allowed to provide multiple signature keys in the JWKS / hosted on the JWKS url provided during client creation.

The signature JWK should have the following attributes:

  • Must have key use of value sig per rfc7517#section-4.2

  • Must contain a key ID in the standard kid field per rfc7517#section-4.5

    • Will be used by Singpass to select the relevant key to verify the client assertion

  • Must be an EC key, with curves: P-256, P-384 or P-521 (NIST curves, aka secp256r1, secp384r1, secp521r1 respectively)

Example EC signing key using P-256 and a timestamped key Id

{
    "kty": "EC",
    "use": "sig",
    "kid": "sig-2021-01-15T12:09:06Z",
    "crv": "P-256",
    "x": "Tjm2thouQXSUJSrKDyMfVGe6ZQRWqCr0UgeSbNKiNi8",
    "y": "8BuGGu519a5xczbArHq1_iVJjGGBSlV5m_FGBJmiFtE"
}

Key Rotation

Relying parties can rotate their signing keys in a self-driven manner. To do this with zero downtime the Relying party must

  • support use of JWKS URLs and be onboarded as such

  • ensure their replacement signing key has a different key ID (kid) to the original key

  • ensure their replacement signing key matches the other cryptographic key requirements

To do this with zero downtime, the following procedure should be followed by the Relying Party:

JWK for encryption

The encryption JWK will be used to encrypt ID tokens requested from the /token endpoint.

Singpass will select the strongest available, supported encryption key from either a local JWKS, or JWKS URL to encrypt returned ID tokens for those relying parties who require any PII in the ID token.

The encryption JWK must have the following attributes:

  • Must have key use of value enc per rfc7517#section-4.2

  • Must contain a key ID in the standard kid field per rfc7517#section-4.5

    • The key ID will be specified in the returned JWE header so that clients can pick the right key for decryption

  • Must have key type (kty) of EC

  • Must specify the appropriate key encryption alg the relying party wants Singpass to use, consistent with the key type/curve (kty), and meet the requirements below on allowed alg/curve/key sizes, consistent with RFC7518 - JSON Web Algorithm specification

Example EC encryption key using P-256 and a timestamped key Id; asking us to encrypt the CEK using ECDH-ES+A128KW

{
    "kty": "EC",
    "use": "enc",
    "kid": "enc-2021-01-15T12:09:06Z",
    "crv": "P-256",
    "x": "xom6kD54yfXRPvMFVYFlVjUKzmNhz7wf0DP_2h9kXtY",
    "y": "lrh8C9c8-SBJTm1FcfqLkj2AnHtaxpnB1qsN6PiFFJE",
    "alg": "ECDH-ES+A128KW"
}

Key Preference

If the relying party exposes multiple supported encryption keys, Singpass will select the key to use for encrypting tokens based on the following logic:

  1. prefer any EC key (kty) matching the above requirements

  2. prefer EC keys with stronger crv (curve) above EC keys with weaker curve

  3. prefer EC keys with stronger alg key wrapping above weaker ones

  4. otherwise pick the first compatible key we find

Key Rotation

Relying parties can rotate their encryption keys in a self-driven manner. To do this with zero downtime the Relying party must

  • support use of JWKS URLs and be onboarded as such

  • have the ability to decrypt tokens produced with either one of two different encryption keys based on either

    • selecting the correct decryption key by its key ID (kid)

    • trial-and-error decryption against multiple keys in a collection

  • ensure their replacement key matches the other cryptographic key requirements noted above

To do this with zero downtime, the following procedure should be followed by the Relying Party:

JWKS URL Service Level Expectations

Singpass requires that any JWKS is published on an endpoint that

  • is served behind HTTPS on port 443 using a TLS server certificate issued by a standard publicly verifiable CA issuer (no private CAs), with complete cert chain presented by the server

  • is publicly accessible (no IP whitelisting, mTLS or other custom HTTP header requirements outside standard HTTP headers such as Content-Type, Accept)

  • is able to respond in a timely fashion with respect to the below configuration

Note: While the above is a technical requirement; the user experience of your users may be affected if we are unable to retrieve your JWKS in a timely fashion upon our cache expiry due to slower token exchanges with your backend. We recommend aiming for this response to be as fast as possible based on an in-memory cache; or simple static asset retrieval.

If Singpass fails to retrieve a valid JWKS from the provided URL after cache expiry, the relying party’s token exchange will fail with an OAuth2/OIDC invalid_client error in these circumstances:

  • if client assertions are used, and we are unable to validate the relying party’s assertion using their signing key

  • if encryption of returned ID tokens is required, and we are unable to retrieve the relying party’s preferred encryption key

Last updated