# Client JWKS

Clients must provide public keys in the JSON Web Key (JWK) format to enable secure signing and encryption operations. These keys are essential for verifying signed client requests and for encrypting ID tokens returned by Corppass.

Clients authenticating with Corppass using **JWT-based client assertions** must expose a **JSON Web Key Set (JWKS)** at a publicly accessible URL. This allows Corppass to verify the digital signatures of JWTs submitted with PAR (Pushed Authentication Request) or token requests.

## What is a JWKS?

A JWKS is a JSON document that contains one or more **public keys**. Each key corresponds to a private key that the client uses to sign JWTs. Corppass uses the `kid`  (Key ID) in the JWT header to find the matching key in the JWKS and verify the signature.

{% hint style="warning" %}
Ensure that the private key component (`d`) is **never** **included** in the JWK. Only public key parameters such as `x`, `y`, `e`, `n` should be exposed to maintain the security of cryptographic operations.
{% endhint %}

### Hosting your JWKS

Clients integrating with Corppass **must adhere** to the following service-level requirements to ensure secure and reliable interactions:

* **HTTPS Requirement**: The JWKS endpoint must be served over **HTTPS on port 443**, using a **publicly trusted and verifiable TLS certificate**.
* **Performance**: The endpoint should respond within **3 seconds** to ensure optimal performance and minimal authentication latency.
* **Key Availability**: The JWKS must always include at least one valid public key for signing and encryption respectively.

### JWKS Example

<pre class="language-json"><code class="lang-json"><strong>{
</strong>  "keys": [
    { 
      "kty": "EC", 
      "use": "sig",
      "alg": "ES256",
      "kid": "UErQ3h_cFg3FQHrWFwAj7RPyeHjPoO7mj3IWj2jGhso", 
      "x": "7eArnDiZnGA0Pg115rH4X0VHbnI00fVag1wbLihruF4", 
      "y": "eK6jKnD1P4f9hsjZ9v4W6ZTuhwd87R01ClK1NEYAdoI", 
      "crv": "P-256" 
    },
    {
      "kty": "EC", 
      "use": "enc",
      "alg": "ECDH-ES+A128KW",
      "kid": "SfyArsBpqSONSMkYid3snFYPea69t1Blc-tiDaUUlVs", 
      "x": "xom6kD54yfXRPvMFVYFlVjUKzmNhz7wf0DP_2h9kXtY", 
      "y": "lrh8C9c8-SBJTm1FcfqLkj2AnHtaxpnB1qsN6PiFFJE",
      "crv": "P-256"
    }
  ]
}
</code></pre>

### JWK for Signing

The signing JWK is used to verify the **Client Assertion JWT** submitted during token requests.&#x20;

#### An example of Signing JWK (ES256, P-256 Curve):

<pre class="language-json"><code class="lang-json"><strong>{ 
</strong>  "kty": "EC", 
  "use": "sig", 
  "alg": "ES256", 
  "kid": "UErQ3h_cFg3FQHrWFwAj7RPyeHjPoO7mj3IWj2jGhso",
  "x": "7eArnDiZnGA0Pg115rH4X0VHbnI00fVag1wbLihruF4", 
  "y": "eK6jKnD1P4f9hsjZ9v4W6ZTuhwd87R01ClK1NEYAdoI", 
  "crv": "P-256" 
}
</code></pre>

<table><thead><tr><th width="161.94921875">Claim</th><th>Description</th></tr></thead><tbody><tr><td>kty</td><td>Specifies the key type. Must be <code>"EC"</code> to denote an Elliptic Curve key.</td></tr><tr><td>use</td><td>Indicates the intended use of the key. Must be set to <code>sig</code> to specify that the key is used for digital signature operations.</td></tr><tr><td>alg</td><td>Defines the algorithm intended for use with the key. Supported values are: <code>ES256</code>, <code>ES256K</code>, <code>ES384</code>, and <code>ES512</code>.</td></tr><tr><td>kid</td><td>A unique identifier that helps Corppass select the correct key for verifying client assertions.</td></tr><tr><td>crv</td><td><p>Indicates the elliptic curve used. Supported values are: </p><ul><li><code>P-256</code> (NIST <code>secp256r1</code>)</li><li><code>P-384</code> (NIST <code>secp384r1</code>)</li><li><code>P-521</code> (NIST <code>secp521r1</code>)</li><li><code>secp256k1</code></li></ul></td></tr></tbody></table>

### JWK for Encryption

The encryption JWK is used to encrypt sensitive responses returned by the Authorization Server, including the ID Token issued at the `/token` endpoint and the payload from the `/userinfo` resource endpoint. This ensures that only the intended recipient (the client) can decrypt and access the protected information. Clients must publish a valid public encryption key in JWK format to enable this secure transmission.

#### An example of an Encryption JWK (ECDH-ES+A128KW, P-256 Curve)

```json
{ 
  "kty": "EC", 
  "use": "enc",
  "alg": "ECDH-ES+A128KW",
  "kid": "SfyArsBpqSONSMkYid3snFYPea69t1Blc-tiDaUUlVs", 
  "x": "xom6kD54yfXRPvMFVYFlVjUKzmNhz7wf0DP_2h9kXtY", 
  "y": "lrh8C9c8-SBJTm1FcfqLkj2AnHtaxpnB1qsN6PiFFJE", 
  "crv": "P-256", 
}
```

<table><thead><tr><th width="144.125">Claim</th><th>Description</th></tr></thead><tbody><tr><td>kty</td><td>Specifies the key type. Must be <code>"EC"</code> to indicate an Elliptic Curve key.</td></tr><tr><td>use</td><td>Indicates the intended use of the key. Must be set to <code>"enc"</code> to specify that the key is used for encryption.</td></tr><tr><td>alg</td><td>Defines the key management algorithm used for encryption. Supported values are: <code>ECDH-ES+A128KW</code>, <code>ECDH-ES+A192KW</code>, and <code>ECDH-ES+A256KW</code>.</td></tr><tr><td>kid</td><td>A unique identifier that allows the Authorization Server to select the correct public key for encrypting responses.</td></tr><tr><td>crv</td><td>Indicates the elliptic curve used. Supported values are: <code>P-256</code> (NIST <code>secp256r1</code>), <code>P-384</code> (NIST <code>secp384r1</code>), and <code>P-521</code> (NIST <code>secp521r1</code>).</td></tr></tbody></table>

## Key Rotation Guidelines

To maintain strong security hygiene and align with best practices, clients **should** rotate their signing and encryption keys regularly.&#x20;

Corppass supports seamless key rotation without downtime by allowing clients to publish multiple keys in their JWKS. The Authorization Server uses the `kid` (Key ID) value in incoming JWTs to select the appropriate key for verification or encryption.&#x20;

By following the steps below, clients can introduce new keys and deprecate old ones without impacting ongoing integrations.

### Signing Key Rotation

<table><thead><tr><th width="168.09765625">Time</th><th>Action</th></tr></thead><tbody><tr><td>Prep</td><td>The Relying Party (RP) generates a new signing key pair (K2) for use in signing client assertions.</td></tr><tr><td>T0</td><td>The RP publishes the new public key (K2) to its JWKS endpoint, while retaining the existing key (K1).</td></tr><tr><td>T0 - T+1 hour</td><td>Corppass retrieves the RP’s updated JWKS, which now includes K2. It uses the <code>kid</code> value in the client assertion's header to identify the correct key for signature verification</td></tr><tr><td>> T+1 hour</td><td>The RP begins signing client assertions using the new key (K2).</td></tr><tr><td>Clean Up</td><td>Once confident that K2 is in use and functioning correctly, the RP may remove the old key (K1) from its JWKS endpoint.</td></tr></tbody></table>

### Encryption Key Rotation

<table><thead><tr><th width="169.58984375">Time</th><th>Action</th></tr></thead><tbody><tr><td>Prep</td><td>The Relying Party (RP) generates a new encryption key pair (K2) for decrypting tokens. The existing key pair (K1) remains available for decrypting ID tokens.</td></tr><tr><td>T0</td><td>The RP updates its JWKS endpoint by removing public key K1 and adding the new public key K2.</td></tr><tr><td>T0 - T+1 hour</td><td>Corppass begins encrypting ID tokens and other protected payloads using the new encryption key (K2).</td></tr><tr><td>> T+1 hour</td><td><p>During key rotation, Corppass may begin encrypting ID tokens using a new key (<code>K2</code>), while some tokens may still be issued using the previous key (<code>K1</code>) due to caching or propagation delays.<br></p><p>Relying Parties (RPs) must implement <strong>dynamic decryption</strong> by inspecting the <strong><code>kid</code> field in the JWE header</strong> to determine which decryption key (K1 or K2) to use.</p><p><br>Failure to support multiple active decryption keys during rotation may result in decryption failures or rejected tokens.</p></td></tr><tr><td>Clean Up</td><td>Once the RP confirms that no new tokens are being encrypted with K1, it can safely remove support for decrypting with K1.</td></tr></tbody></table>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.corppass.gov.sg/technical-specifications/technical-concepts/client-jwks.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
