TestifySec Witness and Archivista: Supply Chain Security and SSDF Compliance for Federal Market
TestifySec Witness and Archivista for the Federal Market and SSDF Compliance TestifySec offers comprehensive solutions …
Cryptographic keys are essential to software supply chain security, but managing them can be complex and time-consuming. This is especially true for long-lived cryptographic keys stored on disk. These keys are generally used for signing artifacts or authenticating user accounts.
The recent security incident at CircleCI resulting in the compromise of DataDogs RPM package signing key has brought attention to the importance of effective key management practices. Long-lived keys stored on disk can easily be compromised by attackers, allowing them to impersonate official packages and leave customers and users vulnerable to supply chain attacks. This was tragically demonstrated in the SolarWinds hack, where officially signed packages for their flagship product caused a devastating supply chain attack.
An alternative approach is to use short-lived, ephemeral keys that are generated on-the-fly for each signature operation, making them more difficult for an attacker to compromise. However, verifying keyless signatures is more complex than traditional signatures, as the corresponding certificate used to validate the signature may no longer be valid when the signature needs to be verified.
This article will discuss how to verify keyless signatures and how we implement keyless signing in Witness.
Keyless signatures are more difficult for an attacker to compromise.
A keyless signature is a digital signature that allows for the secure authentication of a digital message without the need to manage long-lived private keys. When a message is signed using a keyless signature, an ephemeral key is generated and used for signing. In the case of Sigstore, the corresponding certificate is then automatically generated and signed by the Fulcio root certificate authority (CA), and the certificate is published in a certificate transparency log. When using SPIRE to generate ephemeral keys, we do not have a transparency log to verify against so we need another way to verify when the signature was created. We accomplish this by counter signing with one or more timestamping authorities (TSA).
Countersigning, also known as counter signing or counter signature, is the act of adding an additional signature to a document or agreement that has already been signed by another party. The countersignature is added as a way of providing additional authentication and verification that the original signature is valid and legitimate.
Counter signing with a timestamp provides proof that a digital signature existed at a specific time.
In the context of digital signatures, the term “counter signature” refers to the act of adding a different signature, generated by a different signer, to a digital signature. Typically, this is used to provide a signature on a signature, allowing for a proof that a signature existed at a given time (i.e., a timestamp).
In the case of keyless signatures, the ephemeral key used to sign the message is not long-lived, so it’s impossible to verify the signature’s authenticity based on the traditional certificate chain model. Therefore, one way to achieve this is by using counter signing to sign the signature created with the ephemeral key with one or more timestamping authorities (TSAs). The TSAs will sign the message with their key, and create a timestamp, thus providing proof that the signature was created within the validity period of the certificate. Furthermore, by using multiple TSAs, it increases the security level of the process, as the signature can only be authenticated if a quorum of the TSAs confirm that the signature was created within the validity period.
Overall, countersigning provides a useful tool for adding an additional layer of security and verification to digital signatures and other types of content, allowing for additional authentication and verification that the original signature is valid and legitimate.
Sigstore does not use counter signing to verify when a signature happened, instead a signed certificate timestamp (SCT), which is a promise for inclusion into the CT Log, is embedded within the ephemeral certificate then the certificate is signed again by Fulcio. This creates a final certificate that contains the embedded SCT and can be used by clients to verify the authenticity and integrity of the certificate. The code used to generate the SCT is located in the certifcate-transparency-go repository.
Update: Cosign now supports the timestamping and verifying timestamps.
This transparent and auditable process allows for the secure authentication of the digital signature without the need for long-lived private keys, which cause damage if leaked. Using keyless signatures can improve the security and reduce the complexity of digital signatures by eliminating the need to secure long-lived private keys. It can also make the revocation process easier since the root CA can simply stop signing the ephemeral keys used for signing if the user or system requesting a certificate for their key is no longer trusted.
In the case of the Witness project, we support keyless signatures created using the Sigstore key provider or the SPIRE key provider. The attestation is signed by the ephemeral keys and then counter signed by one or more TSA(s). The Witness command-line tool implements both Sigstore and SPIRE libraries to provide users with flexibility in how they manage their keyless signatures.
We do not currently support checking the SCT embedded by Fulcio. However, we do plan on supporting verifying with SCTs in the future. However, signing with multiple TSAs allows users to trust ephemeral certificates while also providing a robust air-gap capability.
Signing with multiple TSAs allows users to trust ephemeral certificates while also providing a robust air-gap capability.
Sigstore is a platform for creating and verifying keyless digital signatures for software artifacts. The keyless signing flow in Sigstore involves three main components: a certificate authority (Fulcio), a transparency log (Trillian), and client API for signing and verifying artifacts. Witness implements the Fulcio client API to obtain signed certificates from the Fulcio CA. Witness does not currently validate the embedded SCT.
Fulcio is a free, automatic certificate authority (CA) that issues short-lived certificates for signing code. These certificates include a subject identity, such as an email address, and special Sigstore-specific ASN.1 object identifiers. One of these objects is a signed certificate timestamp (SCT), which serves as proof of the time at which the certificate was issued.
Fulcio publishes all issued certificates to a certificate transparency log (CT) for verifiers to check if their identity has been compromised or mis-issued. However, Sigstore clients only check the validity of the SCT, which is embedded in the certificate. The SCT acts as a promise for inclusion in the CT log but Cosign does not use the timestamp from the CT log. Instead, Cosign verifies that the SCT is valid, then it gets the inclusion time for the record it creates in Rekor corresponding to the artifact it signs and uses it to verify the signature happened within the validity period. We discuss Rekor later in this article.
Trillian is a tamper-proof append-only log. It provides an immutable, verifiable history of activity and is used at a global scale by certificate issuers for certificate transparency. For example, Fulcio uses Trillian for transparency and for providing the SCT.
Sigstore has a client API that allows users to easily sign and verify software artifacts without the need to manage keys. The API simplifies the process of using digital signatures to ensure the integrity and authenticity of the software. It is intended to be used by individual users, open-source communities, and organizations to improve the security of their software supply chain. There is an example of using the Fulcio API in the Fulcio GitHub Repo.
The process involves several parties, including the software producer, OIDC (OpenID Connect), Fulcio, the CT Log (Trillian), and the consumer.
Note: The TUF trust root is online, but it can be cached by the consumer, so updates are only required every seven days. However, there is currently no way to completely do offline verification unless the consumer chooses to ignore expired timestamps, which would leave the system vulnerable to man-in-the-middle (MITM) attacks, so it is not recommended.
SPIFFE is a specification that enables the distribution of identity (SVID) in the form of x.509 certificates or JWTs. Its reference implementation is called SPIRE. SPIRE allows administrators to distribute private keys based on inventory data such as machine identity and workload identity. However, this added flexibility comes at the cost of increased configuration complexity and maintenance. Our next article will explore how SPIRE can provide robust authentication mechanisms beyond those used in Fulcio’s OIDC verification.
Witness is an open-source tool developed by TestifySec to secure software development practices and ensure compliance. First, it generates evidence about the software development process, such as test results, artifacts created, and user interactions. Then, it allows users to enforce policy based on the attributes of the evidence collected and the users or machines involved in the creation of the evidence.
The evidence or attestations created by Witness must be trusted and attached to a functionary (authorized user). Witness policy enables administrators to enforce the steps used to create an artifact and who or what ran those steps.
Witness policy enables administrators to enforce the steps used to create an artifact and who or what ran those steps.
Witness uses counter signing with trusted timestamp authorities (TSAs) for verifying timestamps included in our attestations. This implementation allows users to verify attestations created with ephemeral keys if they trust the TSAs and the issuer of the short-lived certificate. Using ephemeral keys in combination with a TSA significantly reduces the damage an attacker can cause if a private signing key is compromised. For instance, with Fulcio, the default certificate validity period is 20 minutes, but using a TSA can reduce this period to less than a minute. Additionally, attestation data can be verified across an air gap if the roots of trust (CA) for both the ephemeral keys and TSAs are present on both sides of the air gap. Most organizations requiring air-gapped capability have a method to distribute these root certificates.
Witness verification is designed to function without an internet connection or any centralized service, and as such, we implemented timestamping via RFC 3161 before transparency log verification. This process differs from the reference Cosign verification. Here is a step-by-step breakdown of the flow:
It’s worth noting that currently, the Witness verification process does not verify the SCT or publish the signed secure hash of the attestation to the Rekor transparency log. This would provide a transparent and auditable record of the signing process.
Rekor and transparency are closely related in the context of Cosign. Cosign uses Rekor as an additional layer of verification by storing a hashed record of the artifacts it signs. Rekor is an append-only transparency log that uses Trillian as its store. It stores signed artifact meta-data and their corresponding certificates. This allows users to verify the authenticity and integrity of the artifacts by checking the signatures against the entries in the log.
This design allows for public auditing of artifacts without exposing their details, but it does give a signal about internal processes that might not be intended for public consumption. It also adds complexity when trying to verify artifacts across security boundaries. With this in mind, we plan to implement transparency as an option in Witness to provide more auditability of the attestations created in addition to the current flow which allows for verification using the time stamping protocol (TSP). You can learn more about how certificate transparency works at https://certificate.transparency.dev/howctworks/.
First, download the Witness binary from the releases page on GitHub. You can also use the following bash/curl command to download, extract, verify the shasum of the binary, then install it at
bash <(curl -s https://raw.githubusercontent.com/testifysec/witness/main/install-witness.sh)
Next, run a build step and record the attestation. In this example, we will remove a test file if it exists, init a git repo, and make a commit. Witness runs a
git attestor by default and needs a valid commit. Then use the
witness run command to record the attestation. The
-s flag specifies the step name, the
-o flag specifies the output file,
--fulcio flag specifies the URL of the Fulcio server,
--fulcio-oidc-client-id flag specifies the OIDC client ID,
--fulcio-oidc-issuer flag specifies the OIDC issuer, and
--timestamp-servers flag specifies the timestamp servers.
echo "hello"> test.txt is the command we will create an attestation for. The Sigstore public good instance and FreeTSA are used in this example.
git init || true touch README.md || true git add README.md && git commit -m "init" || true rm test.txt || true
Now you are ready to run the command to create the attestation.
witness run -s test -o test.json --fulcio https://v1.fulcio.sigstore.dev --fulcio-oidc-client-id https://oauth2.sigstore.dev/auth --fulcio-oidc-issuer sigstore --timestamp-servers https://freetsa.org/tsr -- echo "hello" > test.txt
This command will run the command
echo "hello"> test.txt and record the attestation of the command in a file called
View the attestation data in the signed DSSE Envelope. You can do this by running the following command:
cat test.json | jq -r .payload | base64 -d | jq
Download the Fulcio Root CA. The Fulcio Root CA is used to verify the Fulcio certificate chain. It is available at https://fulcio.sigstore.dev/api/v2/trustBundle
Download the FreeTSA CA Certificate on their website.
Create a policy file that defines the attestations required for a build step to be considered valid. Next, add the base64 encoded TSA certs, Fulcio Root, and Intermediate certificates to the policy file and as a functionary on the build step.
stepssection of the policy file. This corresponds with the
stepname indicated in the
witness runcommand and the
payloadsection of the attestation.
Policies need to be signed to ensure the authenticity and integrity of the policy. Signing the policy ensures that the policy has not been tampered with or modified by an unauthorized party. It also verifies that the intended author or organization indeed created the policy. This ensures that the policy can be trusted as a legitimate and accurate representation of the intended build or supply chain process. Signing the policy also enables the policy to be verified and authenticated by third-party consumers or auditors.
Create a keypair to sign the policy with.
openssl genrsa -out testkey.pem 2048 openssl rsa -in testkey.pem -outform PEM -pubout -out testpub.pem
Sign the policy file with the keypair.
witness sign -k testkey.pem -o policy-signed.json -f policy.json
Currently, we only support signing and verifying policy with long-lived file-based keypairs. Work is in progress to help users distribute, manage, and trust policy using TUF and additional key providers.
witness verify -p policy-signed.json -a test.json -k testpub.pem -f test.txt
Keyless signatures provide a secure way to authenticate digital messages without the need to manage long-lived private keys. However, verifying the authenticity of these signatures can be more complex than traditional signatures.
The Witness project uses keyless signatures to authenticate digital messages without the need to manage long-lived private keys. We use timestamping authorities (TSAs) to add a timestamp to the signature created by the ephemeral key. This timestamp proves that the signature was created within the certificate’s validity period and allows us to verify the authenticity of the keyless signature even when the device or system is offline or disconnected from the internet. This ensures that attestations created with Witness can be trusted and verified across an air gap
I want to thank Andrew Block and Hayden Blauzvern from the SigStore project for their help with the editing of this article.
If you want to enhance the security of your software supply chain, we encourage you to explore our Witness and Archivista GitHub repositories. Our team offers support and services, and we are developing a Software as a Service (SaaS) platform. If you are interested in learning more about how we can assist you in implementing keyless signatures in your organization, please don’t hesitate to contact us.
TestifySec Witness and Archivista for the Federal Market and SSDF Compliance TestifySec offers comprehensive solutions …
As the landscape of software security evolves, organizations continually grapple with the challenge of ensuring the …
TestifySec Judge Provides Visibility into the Security of Your InventoryLearn More