Integrating national identity systems like Singapore's Singpass and MyInfo into commercial platforms is mandatory for KYC compliance in fintech, logistics, and utilities. However, their security specifications are strict, requiring signed JWTs, asymmetric decryption (JWKS), and mutual TLS (mTLS).
By implementing a standalone Digital Identity Bridge, you can consolidate the cryptography and protocol overhead into one secure boundary, keeping internal microservices simple.
1. The OIDC Flow for Singpass
Singpass utilizes OpenID Connect (OIDC) Authorization Code flow, augmented with client assertion signatures. The Go service must sign its client assertion JWT using a private key registered with Singpass:
func CreateClientAssertion(clientID, aud string, privKey *rsa.PrivateKey) (string, error) {
claims := jwt.MapClaims{
"sub": clientID,
"iss": clientID,
"aud": aud,
"iat": time.Now().Unix(),
"exp": time.Now().Add(5 * time.Minute).Unix(),
"jti": uuid.New().String(),
}
token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
return token.SignedString(privKey)
}
2. Decrypting MyInfo Data Payloads
MyInfo responses are encrypted using JWE (JSON Web Encryption). The Go bridge receives a payload, decrypts it using the company's private key, and verifies the signature using MyInfo's public keys. This requires parsing the compact JWE token, extracting the encrypted CEK (Content Encryption Key), and decrypting the body using AES-GCM.
Consolidating these secure handshakes into a dedicated Go bridge simplifies downstream microservices, which only need to accept verified, standardized internal JWTs.