Update 30.08.2022: Please note – This use-case is currently being refactored as public SAP IAS tokens (issued by the PKCE flow) do not contain the required SAP XSUAA audience anymore. Therefore, an additional token exchange is required to run the end-to-end scenario.
Covid has in some way affected every part of our lives, be it personal or professional. For example, some of us did not have the opportunity to work from home and therefore had to go to our employer’s office. In some countries, returning to the office brought new challenges, such as legal requirements that employers only allow employees access to the building if appropriate proof of vaccination or recovery was provided.
Often this is checked manually by human intervention at the entrance to the building, but this is impractical, time-consuming, and not always feasible. Hence, we decided to develop an example application using SAP BTP services (especially for SAP BTP Free Tier) and open source resources. For this reason, we have avoided paid services like the “Universal Verification Service” from UBIRCH and implemented the verification logic ourselves (Also for personal reasons to better understand how all the bits and pieces of a Covid certificate work together and what it consists of).
This app demonstrates some technical details of the SAP BTP Services and is not representative of a Covid app suitable for production. The sample certificate check should not be compared with the maturity level of a CoronaWarnApp, CovPassCheck app (by Robert Koch Institute) or licensed SAP products.
Furthermore, if you do want to develop such an app for your organization, please verify that you follow all applicable data protection and Covid requirements. This includes, for example, whether the health data (number of vaccinations, at what time, which vaccine, when recovered, etc.) may or may not be stored. In some countries it is even stipulated that health data such as these must not be stored at all but that the examination of such data must be logged. We intentionally avoided persistence of this data to keep the solution as generic as possible.
Architecture overview
We have chosen to provide a mobile-only frontend. In most cases, Covid certificates are either already stored on mobile devices and can be uploaded as a screenshot via an upload function, or the QR code is on a paper document and can be easily scanned using the mobile phone camera.
In many scenarios we have seen and heard from customers that the Covid certificate is simply saved on the server side and made available to an administrative employee, who must subsequently validate it – for example, using the CovPassCheck app. We wanted to avoid this because there would be time delays until certificates are manually checked and accepted, but it also makes the process more cumbersome due to the manual intervention required.
We have opted to build an automatic verification method that does not involve human participation (for the sake of technology). Alternatively, there is for instance the managed solution from UBIRCH, which would make the custom development of the verification & validation of the certificate obsolete.
For now, let’s assume you want to build your own automated app prototype to learn about the SAP BTP features involved. The automatic verification of certificates will in this case be triggered directly from the mobile app (created with SAP AppGyver) by using a simple REST service. We decided on a Node.js app using the SAP Cloud Application Programming (CAP) model, which takes over the synchronous communication, fetches data from other systems (such as SAP SuccessFactors) using another microservice, and persists the results in SAP HANA Cloud. A basic SAP Fiori Elements application on top is then used to list the employees who are entitled to enter the employers’ offices. Of course, we could have utilized plain Node.js without CAP, but because we focused on security using SAP Cloud Identity Service and XSUAA, CAP did a lot of the heavy lifting for us.
In terms of security, Identity Authentication Service is used as a central service that is linked to both the SAP AppGyver app as well as the CAP application (indirectly via XSUAA). Because the Identity Authentication Service is potentially connected to many other systems in the SAP landscape, this is the closest to a realistic scenario. But there’s more on that in a separate section of this blog post.
For admin users of the SAP Fiori Elements application, the name and the expiration date of the employee (that has been granted building access) may not be enough information. Therefore, SAP Graph is used to quickly and simply combine additional data from SAP SuccessFactors with the existing Covid certificate data and make it available to the user. This might for example include which nation the employee is coming from or if it’s a full-time employee/contingent worker.
Even in this case, where data is just originating from a single source system, SAP Graph has already assisted us in performing simpler queries to business entities (like the entity personal). However, SAP Graph is typically used to simplify data queries from a variety of SAP applications. Nonetheless, we wanted to use SAP Graph as an example to show how it may be used in general, as it is still a new SAP product.
Long Story Short:
Mobile app built using SAP AppGyver: Upload or scan Covid certificate
SAP CAP application: Processes Covid certificate (either image or decoded QR code)
SAP Graph: Reads employee information from SAP SuccessFactors
Identity Authentication Service: Acts as Identity Provider and handles authentication
— with the help of —
SAP XSUAA: Used to build secure CAP apps and connected to Identity Authentication Service
Security Setup
Find the related tutorial steps in the following GitHub repository (click here).
Security is a very critical aspect of mobile applications. Especially when dealing with confidential personal data. The usage of mobile clients results in additional complexity, risks, and security requirements to allow secure access to backend services. As you can see in the architecture diagram, the whole authentication flow starts from within SAP AppGyver and the user’s access token provided by SAP IAS is reused throughout the whole application backend. This includes an automated exchange to a corresponding SAP XSUAA token which allows you to make use of Principal Propagation when accessing SAP SuccessFactors via SAP Graph.
As part of this use case, you will learn how to setup the security related services required for the whole application. As the respective services will be an essential part of your CAP backend application and the actual SAP AppGyver app, they should be configured before you start the development of other components.
Before jumping into the security details, we recommend studying the following SAP blog post and corresponding GitHub repository. The blog post covers the interesting topic of Proof Key for Code Exchange (PKCE) which is an authorization grant type relevant for mobile clients (not being capable of storing a client secret for authentication purposes). It will also give you a better understanding why we use SAP IAS for user authentication, as opposed to SAP XSUAA, as it offers the required PKCE feature for public clients. Using the XSUAA cross-consumption feature, the respective access token can still be used to seamlessly work with SAP XSUAA based apps like CAP applications.
In this use case you will first create a new Identity Authentication service tenant (if not available to you already). Then you will setup the trust between your SAP BTP subaccount’s XSUAA and your Identity Authentication service tenant (if not done yet). Next, you will create a new application registration in SAP IAS and a corresponding SAP XSUAA service instance providing the required roles on the SAP BTP side. Finally, you will map respective SAP IAS group assignments to SAP BTP XSUAA role collections before testing the actual token exchange feature (cross-consumption) between the two authentication tools.
Backend application powered by SAP Cloud Application Programming Model
Find the related tutorial steps in the following GitHub repository (click here).
The CAP (SAP Cloud Application Programming Model) application is the heart of the entire architecture. While the SAP AppGyver app is responsible for scanning or uploading the Covid certificate’s QR code, and the EmployeeDetail microservice reads the corresponding employee data, the CAP application both connects the individual components and validates and verifies the actual Covid certificate.
If you are interested in the basic Covid certificate validation & verification, we have a section for you at the end of this blog post that goes into more details. We decided to develop the smallest possible variant ourselves in order not to come into conflict with licenses of other OpenSource packages or to incur costs for demos/tutorials through hosted solutions (such as from Ubirch).
Surprisingly, the user logs into the Identity Authentication service, but the CAP application is bound to the SAP XSUAA instance, according to the architecture diagram. So how does this work? Is it really possible to reuse the Identity Authentication token? Yes indeed! Do the tokens have to be exchanged at a high cost? No. If the appropriate settings are in place, CAP (or rather the @sap/xssec package – tokenexchanger.js) will do this automatically and internally. More information about the setup can be found in the corresponding security section.
Let me spend a few words on the SAP technology used for this app and the reasons why we used them. The SAP Cloud Application Programming (CAP) model excels at meeting requirements for enterprise-ready applications with only a few lines of declarative code. For example, instead of serving an (default) OData endpoint, the services for the mobile app are provided as a REST endpoint with only one keyword in the corresponding CDS file. The same is true for security requirements, which can be set with a single keyword. This is not a novel concept or new to CAP, but smaller applications in particular benefit from such adaptability due to the low development costs associated.
The backend application therefore either receives the Base64 encoded string, which is hidden behind the QR code and serves as a Covid certificate, or the QR code as a file. For the Base64 string (in case of the user uploading a photo of the QR code), we again use open source npm packages to extract the corresponding encoded string.
It is important to note that neither the actual data of the certificate nor the certificate as such are ever stored or logged. This confidential data only ends up in memory and disappears after processing.
Now the actual processing of the certificate starts. We have written a class that is instantiated exactly once per app and holds information that is read from trusted providers on the internet. These are essentially public keys that are used to technically validate certificates and generally indicate whether it’s valid or not. Furthermore, these trusted providers provide “business rules” that are used to verify the payload of certificates. Such business rules can, for example, determine how long various vaccinations or tests are valid and consequently how long the certificate is valid.
Get started with the SAP Cloud Application Programming Model: Tutorials on developers.sap.com | SAP Community Topic Page
SAP Fiori Elements application – the administrative perspective
Of course, not only should the end user be aware of the certificate verification result, but so should an administrative user (for example, a Pandemic Taskforce who requires an overview of the access permissions provided). For this requirement, we’ve included a basic overview page based on SAP Fiori Elements as part of the overall setup. Of course, there are many different levels of additional and more sophisticated possibilities at this point. These, however, are usually subject to legal restrictions of the individual nations and so are not included in this sample application.
For example, further expansion stages could include writing the certificate result back to the employee’s record in SAP SuccessFactors or an additional button in the SAP Fiori Elements application to manually revoke access permissions if validation rules have changed and all employees are required to upload their certificate again.
Get started with the SAP Fiori Elements: Tutorials on developers.sap.com | SAP Community Topic Page
Employee Lookup microservice
Find the related tutorial steps in the following GitHub repository (click here).
The Employee Lookup microservice uses the SAP Graph API to query SAP SuccessFactors and fetch the employee details.
SAP Graph is the new unified and consolidated API for SAP-managed data. With SAP Graph you can navigate to and access the data you need, regardless of where this data resides. SAP Graph abstracts the physical landscape and the details of the different product stacks and offers you a simple view of the SAP-managed data, which you can access through a single API, spanning all key use cases. SAP Graph accesses the data in the customer-configured landscape on your users’ behalf, technically acting as middleware. SAP Graph itself doesn’t store or cache any data.
The Employee Lookup Service exposes an API that queries SAP SuccessFactors using the SAP Graph API, and fetches the logged in employee details like firstName, lastName, isContingentWorker, employee photo, country, and location. It also compares and validates the first and last name with the user details retrieved from the Covid certificate. Only if the employee details of SAP SuccessFactors match with the details of the Covid certificate does the API return the fetched user details from the fields mentioned above.
If the employee details of SAP SuccessFactors don’t match the details of the Covid Certificate, the API throws an error.
Get started with SAP Graph: Tutorial on developers.sap.com | SAP Community Topic Page | SAP Developers YouTube | SAP HANA Academy YouTube
SAP AppGyver app – The end-user perspective
Find the related tutorial steps in the following GitHub repository (click here).
This comprehensive part of the use case will show you how to setup a SAP AppGyver mobile app that allows you to scan or upload a screenshot of a Covid certificate. After validation by the backend CAP application, the result of the check will be displayed in the SAP AppGyver app.
You will learn how to use the Low-Code/No-Code capabilities of this SAP solution while integrating the Identity Authentication service for secure backend access. Use of the Proof Key for Code Exchange (PKCE) flow in SAP AppGyver improves the enterprise-readiness of your app.
While we’re providing a very detailed step-by-step guide to build your own version of this app, please be aware, that features like the export of SAP AppGyver development objects or a simplified integration with SAP authentication services are part of the future roadmap (subject to change).
Get started with SAP AppGyver: Tutorial on developers.sap.com | SAP Community Topic Page | SAP Developers YouTube
How the certificate verification and validation works
This is probably the trickiest part for anybody that has never worked with encryption or decryption stuff (like me!). There’s so much information, reference coding, frameworks, documentation, and other concepts available that it’s easy to get lost. We wanted to have the simplest solution that could possibly work without competing with any existing solution that SAP, or a non-SAP provider offers.
First and foremost, it is critical to understand how a Covid certificate is structured, what data it contains, and what additional data is required for processing. Basically, there is a JSON at the beginning or end (depending on whether the disaggregation or encryption of a certificate is considered) that contains some additional technical details in addition to the actual vaccination/recovery/test information.
- The Validator App (see architecture image above which needs to be read from right to left) is in our case the mobile app built using SAP AppGyver. It scans the QR code of a Covid certificate with built-in functionality – the result of the scan is a Base45 string. Otherwise, in case the user uploads a file (e.g. screenshot), the QR code is decoded within the CAP app.
- This Base45 string is the result of a ZLib compression, which can easily be “inflated” (process that makes the data packet larger again) with npm packages.
- The result is a COSE (CBOR Object Signing and Encryption ) Signed Document.
- Extract the CBOR payload from the COSE document. Both COSE and CBOR are somewhat similar to JSON and JWTs just in a binary way. The basic structure of a COSE message consists of a protected and unprotected header, the payload, and a signature. CBOR is basically just a binary JSON object.
- There are trusted providers that provide the public keys (see “metadata” in the architecture image above). Verify the COSE document with the public keys coming from trusted providers (in Germany for instance from UBIRCH: https://de.dscg.ubirch.com/trustList/DSC/). Here ends the technical verification of the certificate.
- Decode the CBOR payload.
- Now you have a usual JSON Object either containing the vaccination, the recovery or test details. To validate how long the certificate (not from a technical perspective but from a functional perspective) is valid, so called “rules” are used. These rules are also coming from trusted providers (in Germany for instance – https://distribution.dcc-rules.de/rules).You can navigate further:– Adding the country to the end of the path to get all rules of a country
– Adding the hash of a specific rule to the path (incl. the country) to return a single rule All rules are based on the JSON Logic. The JSON Logic engine (OpenSource npm package) now takes three parameters: – Which payload to use
– Which rule to use
– Additional parameters (like a keydate)
Since the user in the mobile app defines which country they want the certificate to be validated for, all rules of that country are now processed with the JSON payload of the original certificate that was processed in the above steps. Since the processing is keydate based, the keydate to be checked is increased over and over again – until the JSON Logic engine says: Sorry, that certificate is not valid for the current keydate.
Official Technical Specifications for EU Digital COVID Certificates
Summary
There are a few things that we would probably do differently today or a few points that we could add to this app. For example, we could store the status of how long an employee has access in SAP SuccessFactors or revalidate all affected certificates of a country if something changes in the JSON logic rules (manual delta logic necessary to detect changes).
Overall, there are numerous ways to improve things, but we wanted to provide and visualize the most fundamental of the requirements.
In closing, please keep in mind that sensitive personal data is being processed that should never come into the hands of others. Therefore, processing is done on the fly and the actual payload data is not persisted. Consider the following alternate example: A company decides the employee is permitted to enter the workplace when they use their access card, and they wish to process the business rules at that time instead. This would require storing the entire certificate and then comparing it to the JSON logic rules once they try to enter the office in a specific country (rules are also country specific!). Given the sensitivity of the information contained in the certificate, we decided this was not a viable option.
As a reminder, we have provided a full GitHub repository with the necessary configuration steps and corresponding source code. Unfortunately, SAP AppGyver does not yet allow us to export projects, so the instructions for developing the app are a little more extensive. As already mentioned, the SAP AppGyver team is already working on this feature. Stay apprised on this and other features in the SAP AppGyver roadmap.
This sample application has been a joint effort by Martin Frick, James Rapp, Praveen Kumar Padegal Uwe Klasing, Nishnanth Payani and me.