🔓 Auth0 Integration with Singpass
Tags: security, programming, devops
Published: 2021-11-12 18:58:21

#### Learn how to enable Singpass login with QR code in Auth0 Universal Login.

### <br>

When it comes to national digital identity, Singapore has a lot to say. 
Singapore launched [Singpass](https://www.singpass.gov.sg/) in 2003 and has been enhancing it over the years. 
Singpass’s initial goal was to authenticate citizens to government agencies and has since expanded to use in the private sector quite successfully.
Today, Singapore residents use Singpass to securely access over 1,700 services from more than 460 government agencies and private sector organisations. 

With Auth0's customer base quickly growing in Southeast Asia, Singapore and Japan, it was about time to officially offer Singpass services on the Auth0 platform.

This is the first of a two-post series. In this post, we’ll learn how to integrate Singpass QR Login with Auth0 Universal Login. 
In the next post, we’ll look into integrating Myinfo to share selective personal data such as name and email address.

## How Singpass QR Login Works

[Singpass QR login](https://api.singpass.gov.sg/library/login/developers/overview-at-a-glance) uses OIDC authorization code flow. 
Singpass offers an embedded SDK that renders a QR code returned from the authorization endpoint.

```html
<script src=”https://id.singpass.gov.sg/static/ndi_embedded_auth.js”></script>
```

Websites integrate with Singpass by hosting NDI embedded Javascript SDK. On page load, the Singpass SDK starts an authorization flow, with the `state` and `nonce` loaded to the page from the backend.

```javascript
const authParamsSupplier = async () => {
      return { state: "my-state", nonce: "my-nonce"};
  };

const onError = (errorId, message) => {
    console.log(`Error. errorId:${errorId} message:${message}`);
};

const initAuthSessionResponse = window.NDI.initAuthSession(
    'ndi-qr',
    {
        clientId: SINGPASS_CLIENT_ID, 
        redirectUri: SINGPASS_REDIRECT_URL,
        scope: 'openid',
        responseType: 'code'
    },
    authParamsSupplier,
    onError
);
```

NDI clients call authorization endpoint to return an embedded QR code. The Singpass app then scans the generated QR code, and the user then confirms the login. 
Next, the Embedded SDK receives a confirmation over Websocket and redirects to the client’s callback URL with an authorization code and state. 

![Singpass sequence diagram](https://images.ctfassets.net/23aumh6u8s0i/vfNDWisx8csQ7Ifg777EQ/7037d43c9924c70239e6d49fd365c988/01_private-qr.png)

After the exchange, `id_token`’s `sub` claim contains either an opaque digital identifier known as UUID or a combination of UUID and NRIC. 

```json
{ 
   "sub" : "s=S8829314B,u=1c0cee38-3a8f-4f8a-83bc-7a0e4c59d6a9",
   "aud" : "xxNsTfleQMHoW6tbUgSVNwnLWQ0xTeV0",
   "iss" : "https://stg-id.singpass.gov.sg",
   "exp" : 1609907975,
   "iat" : 1609907375,
   "nonce" : "alh5DS2Gfndv9i0jXYViqGIhiQdP4+4BrUvBhDXBYKk=",
   "amr" : [ "pwd", "swk" ]
}
```

Depending on the information requested, `id_token` is either signed or encrypted.

![id_token](https://images.ctfassets.net/23aumh6u8s0i/1IrIEcWP6iAmJQ4pS7iNrp/e0cb15a685523ab581f7567c543411b8/Screen_Shot_2021-10-13_at_13.12.10.png)

## Integrate Singpass with Auth0
During the discovery phase, we noticed some gaps between what Auth0 offers for integration with external OIDC providers and what Singpass required.

First challenge was that the `nonce` parameter that applications send to Auth0 is not available within UL where we wanted to initiate the NDI SDK.

Second, Auth0 currently does not support the [client-assertion](https://datatracker.ietf.org/doc/html/rfc7523#section-2.2) for token endpoints of OIDC connections. 
Singpass expects clients to use asymmetric [client_assertion JWT](https://stg-id.singpass.gov.sg/docs/authorization/api#_client_jwk_requirements) and customers should follow NDI’s process to generate an Elliptic-curve keypair and host public key in a public-facing `jwks.json` file. 
Customer’s public-key URL is shared with Singpass during lodging the application.

Lastly, Singpass’s `id_token` signing signature (`id_token_signing_alg_values_supported`), is `ES256` as pointed in their [openid-configuration](https://id.singpass.gov.sg/.well-known/openid-configuration). 
Auth0 only supports `RS256` signed `id_tokens` from upstream connections.

While integrating Singpass with Auth0 is not a native feature, we hope to build a simpler and easier solution in the future.

[Read more...](https://auth0.com/blog/auth0-integration-with-singpass/?–utm_source=content_synd&utm_medium=sc&utm_campaign=oauth)