{
"frameworkUri": "https://www.skillsfuture.sg/skills-framework",
"frameworkVersion": "1.0",
"frameworkName": "SFw",
"sector": "Air Transport",
"category": "Aircraft Operations",
"competencyCode": "ATP-ACO-4001-1.1",
"competencyDescription": "Monitor aircraft systems, performance and external environments as well as comply with Air Traffic Control (ATC) instructions and en route navigation requirements to ensure safe and optimal flight conditions",
"competencyLevel": "Level 4",
"competencyLevelDescription": "Analyse aircraft performance through close monitoring of flight decks to ensure optimal flight conditions during cruise"
}
You can add as many skills as needed. You can find a full example here
Migration legacy to new renderer
In order to help more institution to adopt the decentralized architecture of OpenCerts v2, we have created a guide to help early adopter to migrate from the legacy render to the decentralized renderer.
A good part of software engineering is to handle errors that arise from your application. At GovTech, we understand the importance of having good error handling practices too.
In this post, we detail some of our recent upgrades to the opencerts-verify library that improves the error handling coverage when attempting to verify OpenCerts or OpenAttestation documents.
Introduction
In the past, opencerts-verify could only handle just a few types of errors. With the increasing usage of OpenCerts in recent months due to the Covid-19 pandemic, we've seen a wide variety of interesting and funky errors.
For example,
Infura and Cloudflare would rate-limit you if you try to spam them through our verifier, and thus returns a HTTP 429 Too Many Requests error
Cloudflare's Ethereum Gateway would randomly return a HTTP 502 Bad Gateway error
Users will try to tamper with their certificate, just for the fun of it or to test our OpenCerts verifier ๐
For the first two scenarios, our OpenCerts verifier would previously show that the certificate is invalid. That's because we didn't handle HTTP errors in opencerts-verify.
For the last scenario, our OpenCerts verifier didn't handle those cases properly and instead, our opencerts.io frontend verifier will say that it's (a) not issued and (b) revoked at the same time. While such a case can happen, it clearly doesn't reflect the actual error โ that is, the user probably tampered with the certificate's merkleRoot. I'll describe more later in the Invalid Argument section.
New errors
From opencerts-verify version 2.2.0, we introduced the handling of these few errors and they are:
A 4xx code indicates an error caused by the user, whereas 5xx codes tell the client that they did everything correctly and it's the server itself who caused the problem.
Generally, Ethers classify both 4xx and 5xx errors as bad response.
(For those who're interested in how Ethers handle HTTP-related errors internally, you might want to take a look at this.)
Instead of checking for Ethers error messages (e.g. bad response, missing response, etc.), we now group them using Ethers error codes (e.g. SERVER_ERROR) wherever possible โ because there are just too many different error messages to handle.
Do note that error messages are NOT the same as error codes, you can think of error codes as an umbrella term for many error messages.
As for our decision to group both (a) user errors and (b) server errors together, that's because we don't need to have a finer level of granularity at this moment (i.e. we don't need to know that it's 4xx vs 5xx).
INVALID_ARGUMENT
As the name suggests, the INVALID_ARGUMENT error means the input argument is invalid. In this case, we're referring to the merkle root.
Because our verifier uses the document's merkleRoot to check against what's stored on the Ethereum blockchain, there were cases where users have tried to mess with their certificate.
Below are three examples of invalid merkleRoots:
61dc9186345e05cc2ae53dc72af880a3b66e2fa7983feaa6254d1518540de5 is even length, but is not 64 characters (or 32 bytes) as required of merkle roots - Ethers returns error message incorrect data length
61dc9186345e05cc2ae53dc72af880a3b66e2fa7983feaa6254d1518540de50 is not of a valid length - Ethers returns error message hex is of odd-length
61dc9186345e05cc2ae53dc72af880a3b66e2fa7983feaa6254d1518540de50Z is of valid length, BUT contains an invalid character (the Z) - Ethers returns error message invalid hex string
All three examples above are classified as INVALID_ARGUMENT from opencerts-verify version 2.2.0.
For good measure, 61dc9186345e05cc2ae53dc72af880a3b66e2fa7983feaa6254d1518540de50a is OK, leaving this here for an example of a valid merkleRoot to provide context for the three errors above.
Further discussion
That's all for now!
For any feedback, feel free to reach us out on GitHub.
As part of our efforts to ease the adoption of OpenCerts, we have worked on several items for the past weeks.
Multi issuers
While having multiple issuers has always been available in OpenCerts, there has been no documentation on this feature, as well how it differs from single issuer documents. The use cases might be rare (for instance when there is a collaboration between multiple institutions), but now we got you covered.
Deploy verify API
We have been providing an API to verify OpenCerts document for quite awhile, however we don't provide support or SLA for it. This resulted in people copying and pasting the code and then deploying it into their own infrastructure.
The repository already contained scripts to automatically deploy to different infrastructure, but there was another complication. The repository contains multiple functions and while you might be interested by the API to verify documents, you might not be interested in the other APIs.
We have worked on that and improved it:
every API is independently deployable (including verify API)
When revamping the documentation, we missed the article that covered the migration from v1 to v2. We fixed that problem, and the documentation is available again
For any feedback, feel free to reach us out on Github.
While we were working on the documentation, we also created many components that might be useful for OpenCerts integrators:
OpenAttestation CLI
We worked on OpenAttestation CLI to add a new option when wrapping documents. This option allow you to specify a URL to a custom schema to ensure the validity of the document you wrap. Read more in the documentation.
There are 2 differences between OpenCerts CLI and OpenAttestation CLI:
OpenAttestation CLI force you to use documentStore instead of certificateStore (don't worry they are strictly equivalent).
OpenAttestation CLI force you to provide identityProof using DNS-TXT record.
We strongly recommend and encourage to use OpenAttestation CLI in the future. OpenCerts CLI will be deprecated.
OpenCerts verifier
OpenCerts identity verification is based on a registry maintained by SSG. Because of this, OpenCerts identity verification is not compatible with OpenAttestation identity verification.
To overcome this problem, we built a javascript library @govtechsg/opencerts-verify that check the identity over OpenCerts registry and over DNS-TXT record. Read more in the documentation.
OpenCerts verify API
Sometimes during development you might need to make sure a certificate that you generated is valid. While you could use dev.opencerts.io to assert the validity of the certificate, the process is hard to automate and tedious.
To help you on this, we published an API that you might use to validate certificate using HTTP call. Read more in the documentation
This API does not provide any guarantee for production purposes. We might work on providing a terraform module that you could use to deploy the API on your own infrastructure.
Live transcripts
For institutions that might want to provide live transcripts to their students, we wrote documentation on how they can make use of OpenAttestation Status API. The documentation is just an implementation suggestion and does not mean you MUST follow it. Read more in the documentation