Singpass Developer Docs
Developer Docs for Singpass
Developer Docs for Singpass
  • INTRODUCTION
    • Overview of Singpass
    • Understanding the basics of OIDC
  • Products
    • Login
      • Introduction
      • Key Principles
      • User Journey
      • Logo Download and Brand Guidelines
      • Singpass Button Guidelines (For developers and designers)
    • FAQ
      • Login
      • Myinfo
    • Myinfo
      • Introduction
      • Key Principles
      • User Journey
      • Logo Download and Brand Guidelines
      • Data Display Guidelines
      • Scheduled Downtimes
  • GETTING STARTED
    • Onboarding Checklist
    • User Journey
    • Create Singpass Application
    • Start Integration - Demo App
  • Technical Specifications
    • Singpass Authentication API
      • Overview of Singpass Flow
      • 1. Authorization Endpoint
        • Redirection on success
        • For Mobile Developers
      • 2. Token Endpoint
        • Authorization Code Grant
        • Client JWK Requirements
      • 3. Userinfo Endpoint
        • Requesting Userinfo
        • Validating the payload
      • .well-known Endpoints
        • OpenID Discovery Endpoint
        • JWKS Endpoint
      • Error Response
      • Frame busting for web views
    • Staging and Production URLs
  • Singpass Developer Portal (SDP)
    • User Guide
      • Obtain Access to SDP
      • Login to SDP
      • Toggle Staging vs Production
      • Create Staging App
      • Edit Staging App
      • Create Staging Test Account
      • Create Production App
      • Edit Production App
      • Consent to Singpass Service Agreement
      • View Singpass Service Agreement
      • Updating Billing Contact Information
      • Deactivate Production App
      • Activate Production App
      • How to View Production App Transactions
    • Understanding the App Config Fields
      • App Name
      • App Description
      • Site URL
      • Support Emails
      • Allowed Scopes
      • Redirect URL
      • Token-based Authentication
  • Data Catalog (Myinfo)
    • Understanding the Data
      • Local Registered Birth Records and Sponsored Child Records
      • CPF Contribution History (up to 15 months)
      • Notice of Assessment (Basic)
      • Notice of Assessment (Detailed)
    • Catalog
      • Personal
      • Finance
      • Education and Employment
      • Family
      • Vehicle and Driving Licence
      • Property
      • Government Scheme
  • TESTING
    • Testing with Singpass App
    • Myinfo Test Personas
  • MORE INFORMATION
    • Contact
Powered by GitBook
On this page
  • Curl request
  • HTTP request
  • HTTP response
  • HTTPie request
  • Request body
  • Response body
  • Caching and key rotation

Was this helpful?

  1. Technical Specifications
  2. Singpass Authentication API
  3. .well-known Endpoints

JWKS Endpoint

PreviousOpenID Discovery EndpointNextError Response

Last updated 7 months ago

Was this helpful?

Singpass signs all JWTs issued during the authentication process using its ASP signing key. Integrating parties can validate the JWT signatures by acquiring the signing public key from a JSON Web Key Set (JWKS) endpoint.

This endpoint will return one or more public keys in form. The correct JWK to use for signature validation will have its use attribute as sig (to indicate that it is a signing key), and its kid value should match the one found in the JWT under validation.

Public keys returned from this endpoint could be in random sequence or rotated for security enhancement. For more information, please refer to section.

Curl request

$ curl 'https://stg-id.singpass.gov.sg/.well-known/keys' -i -X GET \
    -H 'Accept: application/json'

HTTP request

GET /.well-known/keys HTTP/1.1
Accept: application/json
Host: stg-id.singpass.gov.sg

HTTP response

HTTP/1.1 200 OK
Cache-Control: max-age=21600, must-revalidate, no-transform, public
X-XSS-Protection: 0
X-Frame-Options: DENY
Date: Thu, 26 Sep 2024 03:38:09 GMT
Connection: keep-alive
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
Content-Type: application/json
Content-Length: 697

{
  "keys" : [ {
    "kty" : "EC",
    "use" : "sig",
    "crv" : "P-256",
    "kid" : "eckey-test-secondary",
    "x" : "9bRoLZyZeV49dMVYauCapuZJ7g8ae8e0vWERXr77OT8",
    "y" : "o6lIAyvlmjV7qkGLlLkPIoKHc9VQxSXWgZ-xnboPuuU"
  }, {
    "kty" : "EC",
    "use" : "sig",
    "crv" : "P-256",
    "kid" : "eckey-test",
    "x" : "MW_NF3jr-Fjn8RMg7_ewHfc4VBNJJUnn_gGht3Y-Aeo",
    "y" : "hqdPsdwc8FHpPl47VInEgK2F3and2P_0AnR2q92o4M0"
  }, {
    "kty" : "EC",
    "use" : "sig",
    "crv" : "P-256",
    "kid" : "alias/test-sp-auth-api-id-token-signing-key-kms-asymmetric-key-alias",
    "x" : "wit9gl-WpjLzgpNmpf4RP8UHLDHzqq1HHhQPmGCALdY",
    "y" : "oFVT90ZGZdkw8Ok-G9MvsE1SUhh1N0I78LFrprrIHx8"
  } ]
}

HTTPie request

$ http GET 'https://stg-id.singpass.gov.sg/.well-known/keys' \
    'Accept:application/json'

Request body

Response body

{
  "keys" : [ {
    "kty" : "EC",
    "use" : "sig",
    "crv" : "P-256",
    "kid" : "eckey-test-secondary",
    "x" : "9bRoLZyZeV49dMVYauCapuZJ7g8ae8e0vWERXr77OT8",
    "y" : "o6lIAyvlmjV7qkGLlLkPIoKHc9VQxSXWgZ-xnboPuuU"
  }, {
    "kty" : "EC",
    "use" : "sig",
    "crv" : "P-256",
    "kid" : "eckey-test",
    "x" : "MW_NF3jr-Fjn8RMg7_ewHfc4VBNJJUnn_gGht3Y-Aeo",
    "y" : "hqdPsdwc8FHpPl47VInEgK2F3and2P_0AnR2q92o4M0"
  }, {
    "kty" : "EC",
    "use" : "sig",
    "crv" : "P-256",
    "kid" : "alias/test-sp-auth-api-id-token-signing-key-kms-asymmetric-key-alias",
    "x" : "wit9gl-WpjLzgpNmpf4RP8UHLDHzqq1HHhQPmGCALdY",
    "y" : "oFVT90ZGZdkw8Ok-G9MvsE1SUhh1N0I78LFrprrIHx8"
  } ]
}

Caching and key rotation

IMPORTANT: Responses from this endpoint, or individual keys from inside the JWKS can and should be cached for at least 1 hour, and NOT retrieved for each JWT validation. Cache-Control headers on the response indicate a possible policy.

For varying reasons, keys used for signing can and will be rotated/changed with no defined schedule, and at the full discretion of NDI. When a key rotation happens, the new key will be available from the JWKS endpoint and will have a different kid value. The new kid value will be reflected in all the new JWTs signed by NDI. In such cases, cached copies of NDI public keys must be refreshed by re-invoking the JWKS endpoint.

If the validation of the NDI signature fails, re-fetch from the JWKS endpoint once for that validation.

Please read through the list of DON’Ts below:

  • Do not assume the position of a signing key among the list of the returned keys.

  • Do not validate NDI signatures using a hardcoded public key OR kid. Always determine the correct key (for signature verification) by inspecting the kid from the JWS header, and use it to retrieve the public key from our JWKS endpoint.

  • Do not cache only 1 key. Caching should be done for the entire JWKS.

JSON Web Key (JWK)
Caching and key rotation