SafeEntry APIs (1.0.0)

Download OpenAPI specification:Download

API Specifications for integrating with SafeEntry QR.

Security

Request Signing

All server-to-server API requests are to be digitally signed, by including the following parameters and values in the Authorization header:

PKI_SIGN app_id="{app_id}",
nonce="{random_nonce}",
signature_method="RS256",
signature="{base64_url_percent_encoded_signature}",
timestamp="{unix_epoch_in_milliseconds}"

Note: Above sample is separated by lines for ease-of-reading, and new-line denotations are to be omitted in the actual request.

  • {app_id} is the APP ID credential supplied upon onboarding,

  • {random_nonce} is an unique randomly generated text used for replay prevention,

  • {signature_method} is the signature algorithm of the authenticating gateway.

    • Value of signature_method = RS256
  • {base64_url_percent_encoded_signature} is the binary of the generated signature encoded in Base64 URL-safe format,

  • {unix_epoch_in_milliseconds} is the UNIX epoch time in milliseconds

Sample header with authorization parameters

Below is an example of an Authorization header for the sample application. Make sure you list the parameters in the sequence shown below.

  Authorization: PKI_SIGN
  app_id="STG2-SE-SELF-TEST",
  nonce="150590021034800",
  signature_method="RS256",
  signature="EEm+HEcNQajb5FkVd82zjojk+daYZXxSGPCOR2GHZeoyjZY1PK+aFMzHfWu7eJZYMa5WaEwWxdOdq5hjNbl8kHD7bMaOks7FgEPdjE++TNomfv7SMktDnIvZmPYAxhjb/C9POU2KT6tSlZT/Si/qMgD1cryaPwSeMoM59UZa1GzYmqlkveba7rma58uGwb3wZFH0n57UnouR6LYXDOOLkqi8uMZBuvRUvSJRXETAj2N0hT+4QJiN96Ct6IEQh/woZh0o74K5Ol9PpDSM08qC7Lj6N/k694J+hbBQVVviGn7/6mDkfbwdMDuoKs4t7NpqmAnwT+xaQSIZcexfrAVQYA==",
  timestamp="1505900210349"

Sample Code in NodeJS

  // generates the security headers for calling API gateway
  function generateAuthorizationHeader(url, params, method, strContentType, authType, appId, keyCertContent, passphrase) {

    if (authType == "L2") {
      return generateRS256Header(url, params, method, strContentType, appId, keyCertContent, passphrase);
    } else {
      return "";
    }
  };

  // Signing Your Requests
  function generateRS256Header(url, params, method, strContentType, appId, keyCertContent, keyCertPassphrase) {
    var nonceValue = nonce();
    var timestamp = (new Date).getTime();

    // A) Construct the Authorisation Token Parameters
    var defaultAuthHeaders = {
      "app_id": appId, // App ID assigned to your application
      "nonce": nonceValue, // secure random number
      "signature_method": "RS256",
      "timestamp": timestamp // Unix epoch time
    };

    // B) Forming the Base String
    // Base String is a representation of the entire request (ensures message integrity)

    // i) Normalize request parameters
    var baseParams = sortJSON(_.merge(defaultAuthHeaders, params));

    var baseParamsStr = qs.stringify(baseParams);
    baseParamsStr = qs.unescape(baseParamsStr); // url safe

    // ii) concatenate request elements (HTTP method + url + base string parameters)
    var baseString = method.toUpperCase() + "&" + url + "&" + baseParamsStr;

    // C) Signing Base String to get Digital Signature
    var signWith = {
      key: fs.readFileSync(keyCertContent, 'utf8')
    }; // Provides private key

    // Load pem file containing the x509 cert & private key & sign the base string with it to produce the Digital Signature
    var signature = crypto.createSign('RSA-SHA256')
      .update(baseString)
      .sign(signWith, 'base64');

    // D) Assembling the Authorization Header
    var strAuthHeader = "PKI_SIGN app_id=\"" + appId + // Defaults to 1st part of incoming request hostname
      "\",timestamp=\"" + timestamp +
      "\",nonce=\"" + nonceValue +
      "\",signature_method=\"RS256\"" +
      ",signature=\"" + signature +
      "\"";

    return strAuthHeader;
  };

SafeEntry APIs

Authentication

PKISign

PKI digital signature for server to server calls. See Request Signing for more details.

Security Scheme Type HTTP
HTTP Authorization Scheme Mutual authentication via PKI digital signature in Authorization header

SafeEntry

SafeEntry is a Cloud-based check-in/check-out system that digitalises the check-in/check-out process and simplifies informtion submission as visitors can simply scan a QR code using integrated applications, and share their name and contact information for the purpose of contact tracing.

SafeEntry Check-in/Check-out

Register Check-in/Check-out transactions.

  • The request body should be a JWE string, with decrypted payload as specified in this specification. Algorithm used:
    • RSA-OAEP (for content key wrapping)
    • AES256GCM (for content encrytion)
  • Encryption is done using our public key provided to you during onboarding.
Authorizations:
header Parameters
Authorization
required
string

Add authorization token constructed containing the RSA digital signature of the base string. Refer to https://www.ndi-api.gov.sg/library/safeentry-api/tutorial2 on how this token should be generated.

Request Body schema: application/jose
venueId
required
string

Refers to the unqiueID of your customer’s QR code. You can retrieve the venueId from the location’s QR code. E.g. https://www.safeentry-qr.gov.sg/login/PROD-201900099X-123456-MYCOMPANYNAME-SE.

tenantId
string

tenantId assigned.

actionType
required
string
Enum: "checkin" "checkout"

Type of action.

sub
required
string

Personal Identifier e.g. S9960846C, G0057585U. NRIC/FIN checksum will be validated if "uinfin" is specified for subType. For "others" subType, characters allowed are limited to alphanumeric and "-", length between 3 to 20.

subType
required
string
Enum: "uinfin" "others"

Type of Personal Identifier. NRIC/FIN checksum of "sub" will be validated if uinfin is specified.

mobileno
required
string

Mobile Number. E.g. 92376345, +6584673736

Responses

201

Created

400

Possible Scenarios:

  • Invalid Body. Error message: ["Missing venueId","Missing mobileno"...]
    • Missing venueId
    • Missing mobileno
    • Invalid mobileno
    • Missing actionType
    • Invalid actionType
    • Missing sub
    • Invalid uinfin
    • Invalid passport no
    • Missing sub type
    • Invalid sub type
  • Invalid venue. Error message: Invalid venue
  • Multi tenant app did not provide tenantId. Error message: Missing tenantId
  • Multi tenant app provided wrong tenantId. Error message: Invalid tenantId
401

Unauthorized.

Possible scenarios:

  • Venue does not allow for check-in via SingPass Mobile or SafeEntry Web Application.
  • No security header given (HTTP 'Authorization' header)
  • Invalid App ID used. Digital service is not registered with SafeEntry
  • The timestamp of server is not synchronised. Check timestamp of server.
  • The value of the nonce in the authorisation header was deemed to be repeated. Check that the nonce is not re-used
  • Ensure HTTP 'Authorization' header to be 'PKI_SIGN'
  • Signature incorrect - Verify your signature by using our signature verifier tool and ensure correct key is used to sign the base string.
    • Ensure that base string contains all parameters required
    • Ensure attributes in base string are separate by comma(,), and not %2C
    • Ensure that correct key is used to sign the base string
    • Ensure that HTTP call is made with the same query/body parameters used to formulate the base string.
    • Ensure the base string contains the following:
      1. HTTP GET method(in uppercase)
      2. API (e.g. https://..)
      3. These parameters:
        • app_id
        • nonce
        • signature
        • signature_method
        • timestamp

Details will be given in the error object returned.

403

Forbidden

Possible scenarios:

  • Incorrect API URL used. Refer to tutorial for the correct API URL(test/production)
500

Internal server error

post/partner/v1/entry

Sandbox

https://sandbox.api.safeentry-qr.gov.sg/partner/v1/entry

Test

https://test.api.safeentry-qr.gov.sg/partner/v1/entry

Production

https://api.safeentry-qr.gov.sg/partner/v1/entry

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "code": 0,
  • "message": "string"
}