In Part 1 and Part 2 of this blog series, the concept of Confidential Computing and its potential benefits and some of the technical underpinnings were introduced. Despite its many rewards, the challenges of a fully implemented and functional Confidential Computing system that aligns the hardware, operating environment and software program under a single coherent set of principles can be daunting. In this final installment, you’ll learn about some of these barriers and how the open source Certifier Framework can make adopting Confidential Computing possible.
Confidential Computing is in its adolescence and faces a number of barriers for use that the Certifier Framework eliminates. First, Confidential Computing platform hardware is diverse and users are faced with writing programs that only work with one platform. Second, without a framework, a programmer needs to add thousands of lines of new security code to a program to take advantage of Confidential Computing. Third, without careful thought, independently developed bespoke Confidential Computing programs can introduce compatibility and scalability problems. Fourth, while conceptually simple (so are Newton’s laws!), it takes experience to use these mechanisms safely and economically, without making program development vastly more complex and time consuming.
Introducing the open source Certifier Framework
The Certifier Framework is a new open source project that aims to address some of these barriers. It consists of two pieces:
- The first part of the framework is an application development library (the API) that provides a small but complete set of programming interfaces that enables an application programmer to either port an existing well-written application or develop a fresh one with minimal effort. In fact, with the API, porting such a program to Confidential Computing may only require half a dozen or so calls to the API. The API supports many CC platforms, so you need not rewrite an application that uses the Framework when moving to another platform. The API also provides support for policy control, secure storage, encryption and authentication services and secure authenticated channels. This addresses the first, second and part of the fourth adoption barriers mentioned above.
- The second part of the framework is a scalable certification service known as the Certifier Service. The Certifier Service consists of a set of server applications that evaluate policy and manage trust relationships in a security domain. Working with declarative policy supplied by an organization, the Certifier Service deploys a “fleet” of Confidential Computing programs, verifies security policy, manages interoperability and provides a scalable means for introducing new programs or adding new ones. This service addresses the final two barriers to adoption mentioned above.
Using the Framework
The Confidential Computing primitives (isolation, measurement, sealing and attestation) discussed in part 1 of this blog series, are usually used in a stylized way to protect programs and enforce the security policy.
This stylized use of the primitives includes:
- A public policy key that is embedded in the program – either physically or in another manner – guarantees it is reflected in the program measurement. The program will only trust statements or credentials that are ultimately signed by the policy key.
- When a program first runs, it generates an authentication key (consisting of a public/private key pair) and local encryption keys. The private portion of the authentication key and the encryption keys are stored in a secure, encrypted, integrity protected database using formal seal and unseal confidential computing practices. The public portion of the key is embedded in every application in a security domain.
- There are two mechanisms to “establish trust” with other such protected programs. The first and most important mechanism involves communications with a Certification Service and works as follows:
- Step 1: After initializing its keys, the program forms an attestation naming the public portion of its authentication key and transmits it, along with other cryptographically signed evidence to the certification service.
- Step 2: The service, using signed policy, evaluates all the evidence. If it satisfies the domain policy, it issues an X509 certificate, naming the authentication public key and the measurement (along with other X509 properties) signed by the private portion of the policy key. We call this an Admissions Certificate. (Yes, the service is the custodian of the private policy key.) These certificates are valid for a period named in policy but are usually fairly short lived. Once an Admissions Certificate is issued, a program does not need to use attestation again. (The certificate is valid, so certification is a critical but infrequent task.)
A secondary, though less preferred method to establish trust is for a program to offer this evidence (as described in Step 1 above) directly to another program. This is entirely possible but when used carelessly, it introduces scalability problems and requires deploying policy with the application and updating it as policy expands and changes.
The program processes the information, being careful to protect it with its keys when storing information locally. If the program needs to cooperate with another trusted program in this security domain, it contacts the other program, using TLS and supplies its Admissions Certificate. The contacted program also provides its Admissions Certificate and the two establish a mutually authenticated, encrypted, integrity protected channel. This handshake enables the secure transmission of data between programs. Sensitive information may include data or group keys protecting shared data or state. Note that once a channel is established each (program) channel principal is unforgeably identified by its measurement and this measurement can serve as a universal identifier for the program in an Access Control List that can provide granular and differentiated data protection.
The role of policy
Both the API and the Certifier Service depend on enforcement of policy in a security domain. A thoughtful use of policy allows a single application to enforce many different policies, each appropriate to a different deployment or use scenario. With the Certifier Framework, you need not rewrite the program for different use cases or when the same application is used by different companies with different rules.
Policy and trust enforcement starts with a public policy key. This consists of a public-private key pair. The security domain is a collection of programs that follow the same policy, hence it is part of the program measurement. The public policy key is embedded in every app of the security domain. The Certifier Service uses the private portion of the policy key to sign authoritative statements in the security domain. Each application can validate these statements based solely on the embedded public portion of the policy key. The Certifier Framework API provides support for using the embedded policy key in this way. The Certifier Service provides the tools to flexibly express policy as well as evaluate evidence against stated policy and distribute signed policy directives, including the Admissions Certificate discussed above.
The nitty gritty details
The Certifier API is used mostly with C++ (although there is a Go implementation too) and the Certifier Service is written in Go. The Certifier is “crypto agile,” currently supporting several public keys, encryption, integrity protection, encapsulation and storage algorithms, and more can be added as they become available (for example, Quantum safe public key algorithms). Key formats, transmission data structures and the native policy language are designed to avoid common pitfalls (like parsing vulnerabilities). All components (mainly OpenSSL, Boring SSL and protobufs) are open source.
Policy and claims are expressed in signed statements in a policy language. The Certifier Framework provides a policy language based on the Abadi Lampson SDSI/SPKI framework although you can use other policy languages. Both the API and the Service can validate claims and policy and determine if a set of claims intended to demonstrate policy compliance actually do so. This is the central function of the Service which performs this task when evaluating claims pro-offered by an application to support a request for the Admissions Certificate.
The Certifier Service, for example, produces a proof in the policy language as a result of evaluating claims from an application supporting a request for an Admissions Certificate. Here is a real live proof artifact from the Certifier Service supporting such a request. Remember, the goal is to prove that the authentication key provided in the attestation is trusted (corresponds to a program that is guaranteed to faithfully follow domain policy):
Key[rsa, policyKey, …] is-trusted and Key[rsa, policyKey, …] says Measurement[a051a41593ced366462caea392830628742943c3e81892ac17b70dab6fff0e10] is-trusted, imply via rule 3, Measurement[…] is-trusted
Key[rsa, policyKey, …] is-trusted and Key[rsa, policyKey, …] says Key[rsa, platformKey, …] is-trusted-for-attestation, imply via rule 5, Key[rsa, platformKey, …] is-trusted-for-attestation
Key[rsa, platformKey, …] is-trusted-for-attestation and Key[rsa, platformKey, …] says Key[rsa, attestKey, …] is-trusted-for-attestation, imply via rule 5, Key[rsa, attestKey, …] is-trusted-for-attestation
Key[rsa, attestKey, …] is-trusted-for-attestation and Key[rsa, attestKey, …] says Key[rsa, program-auth-key, …] speaks-for Measurement[…], imply via rule 6, Key[rsa, program-auth-key, …] speaks-for Measurement[…]
Measurement[…]is-trusted and Key[rsa, program-auth-key, …] speaks-for Measurement[…], imply via rule 1, Key[rsa, program-auth-key, …] is-trusted-for-authentication
Proved: Key[rsa, program-auth-key, …] is-trusted-for-authentication
The second statement in step 4 is the attestation. Policy rules and evidence are all expressed in the same language.
Conclusion and invitation
You can find the open source repository for the Certifier Framework on GitHub. In addition to the API and Service, it contains all the policy tools required to build and deploy applications. Importantly, it also contains simple copy and paste application examples for each supported Confidential Computing platform and is accompanied by complete documentation.
The Certifier Framework open source community welcomes contributions and comments. We would especially like to include useful applications that users can change and adapt. Naturally, we look forward to supporting other backends like TDX and Arm Realms. Let us know if you’d like to join and contribute. This is a huge opportunity to advance the adoption of secure distributed computing.