
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](https://circleci.com/blog/january-4-2023-security-alert/) resulting in the compromise of [DataDog's RPM package signing key](https://www.bleepingcomputer.com/news/security/datadog-rotates-rpm-signing-key-exposed-in-circleci-hack/) 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](https://boxboat.com/2020/12/14/safeguarding-the-world-from-the-solarwinds-hack-and-future-supply-chain-attacks/), 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](https://github.com/testifysec/witness).
> Keyless signatures are more difficult for an attacker to compromise.
### What is a Keyless Signature, and How Can We Trust It?
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](https://sigstore.dev), 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](https://spiffe.io/) 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 multi-signing with one or more [timestamping authorities (TSA)](https://en.wikipedia.org/wiki/Trusted_timestamping).
#### MultiSig
[Multi-signature](https://www.techtarget.com/searchcio/definition/multisig-multisignature), or multi-sig, is a method of digital signing where multiple signatures are required to authorize a transaction or action. This can be useful when multiple parties need to approve a transaction, such as in a corporate or decentralized organization. A transaction can only be executed in a multi-sig setup if a specific number of signatures are provided, often set in advance. This provides an additional layer of security by ensuring that a transaction can only be executed if a certain number of parties agree.
> Multisig is a method of digital signing where multiple signatures are required to authorize a transaction or action
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 multi-signing to sign the signature created with the ephemeral key with one or more [timestamping authorities (TSA)](https://en.wikipedia.org/wiki/Trusted_timestamping). The [TSA(s)](https://en.wikipedia.org/wiki/Trusted_timestamping) 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 multi-sig with multiple [TSA(s)](https://en.wikipedia.org/wiki/Trusted_timestamping), it increases the security level of the process, as the signature can only be authenticated if a quorum the [TSA(s)](https://en.wikipedia.org/wiki/Trusted_timestamping) confirm that the signature was created within the validity period.
#### Signed Certificate Timestamp (SCT)
[Sigstore](https://sigstore.dev) does not use multi-sig to verify when a signature happened, instead a [signed certificate timestamp (SCT)](https://certificate.transparency.dev/howctworks/) is a promise for inclusion into the CT Log. It is embedded within the ephemeral certificate then the certificate is signed again by Fulcio. This creates a final certificate that contains the embedded [SCT](https://certificate.transparency.dev/howctworks/) 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](https://github.com/google/certificate-transparency-go).
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](https://www.bleepingcomputer.com/news/security/datadog-rotates-rpm-signing-key-exposed-in-circleci-hack/). 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](https://github.com/testifysec/witness) project, we support keyless signatures created using the [Sigstore](https://sigstore.dev) key provider or the [SPIRE](https://spiffe.io/) key provider. The [attestation](https://www.testifysec.com/blog/what-is-a-supply-chain-attestation/) is signed by the ephemeral keys and then multi-signed by one or more [TSA(s)](https://en.wikipedia.org/wiki/Trusted_timestamping). The [Witness](https://github.com/testifysec/witness) command-line tool implements both [Sigstore](https://sigstore.dev) and [SPIRE](https://spiffe.io/) 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](https://github.com/testifysec/witness/issues/226) verifying with SCTs in the future. However, signing with multiple [TSA(s)](https://en.wikipedia.org/wiki/Trusted_timestamping) allows users to trust ephemeral certificates while also providing a robust air-gap capability.
### Technical Description of Sigstore Keyless signatures
[Sigstore](https://sigstore.dev) 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](https://github.com/sigstore/fulcio)), a transparency log ([Trillian](https://certificate.transparency.dev/)), and [client API](https://github.com/sigstore/fulcio/tree/main/pkg/api) for signing and verifying artifacts. Witness [implements](https://github.com/testifysec/go-witness/blob/main/signer/fulcio/fulcio.go) the Fulcio client API to obtain signed certificates from the Fulcio CA. [Witness](https://github.com/testifysec/witness) does not currently validate the embedded [SCT](https://certificate.transparency.dev/howctworks/).
#### Fulcio
[Fulcio](https://github.com/sigstore/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](https://certificate.transparency.dev/howctworks/)), which serves as proof of the time at which the certificate was issued or signed.
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](https://sigstore.dev) clients only check the validity of the SCT, which is embedded in the certificate and acts as a promise for inclusion in the CT log but does not use the timestamp from the CT log. So instead, [Cosign](https://github.com/sigstore/cosign) verifies that the [SCT](https://certificate.transparency.dev/howctworks/) is valid, then it gets the inclusion time for the record it creates in [Rekor](https://github.com/sigstore/rekor) corresponding to the artifact it signs and uses it to verify the signature happened within the validity period. We discuss [Rekor](https://github.com/sigstore/rekor) later in this article.
#### Trillian (Certificate Transparency Log)
[Trillian](https://transparency.dev/) 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](https://certificate.transparency.dev/howctworks/).
#### Fulcio Client API
[Sigstore](https://sigstore.dev) 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](https://github.com/sigstore/fulcio/blob/main/examples/request-certificate/main.go).
The process involves several parties, including the software producer, OIDC (OpenID Connect), Fulcio, the CT Log (Trillian), and the consumer.
1. The process starts with the producer generating a private key, a unique digital code that is kept secret. The producer then authenticates with Sigstore through OIDC and sends the corresponding public key to Fulcio.
2. Fulcio then publishes the certificate to the certificate transparency log, which records the certificate and provides a promise for inclusion as a signed timestamp (SCT).
3. Fulcio provides a short-lived code signing certificate that includes an SCT (Signed Certificate Timestamp). The SCT is proof of inclusion in the certificate transparency log.
4. The producer uses their private key to sign the software artifact's meta-data. Finally, the signed meta-data is sent along with the software artifact to the consumer. Tools such as cosign rely on OCI (Open Container Initiative) repositories to distribute this signed meta-data.
5. The consumer can then check with the CT Log to verify the authenticity and integrity of the certificate used to sign the software artifact. The consumer can also do an offline verification using the SigStore Trust root. Finally, the consumer checks the timestamp in the signed certificate for certificate validity.
*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.*
```mermaid
sequenceDiagram
participant Producer
participant OIDC
participant Fulcio
participant CT Log
participant Consumer
Producer->> Producer: Generate Private Key
Producer->>OIDC: Authenticate with Sigstore
OIDC-->>Producer: Provide authenticated OIDC token
Producer->>Fulcio: Request code signing certificate, send public key
Fulcio->>CT Log: Publish certificate
CT Log->>Fulcio: Provide SCT as a promise for inclusion in the log
Fulcio->>Producer: Provide a short-lived code signing certificate with SCT
Producer->>Producer: Sign software artifact meta-data
Producer->>Consumer: Provide signed artifact meta-data
Consumer->>CT Log: Verify authenticity and integrity of the signature
opt Offline Verification Possible with Out of Band Trust Root Distribution
Consumer->>Fulcio: Verify the validity of code signing certificate using Sigstore Trust Root
end
Consumer->>Consumer:Check that SCT is valid
Consumer->>CT Log: Check CT log for inclusion
```
### The SPIFFE/SPIRE Project
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](https://spiffe.io/). [SPIRE](https://spiffe.io/) 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](https://spiffe.io/) can provide robust authentication mechanisms beyond those used in Fulcio's OIDC verification.
### Overview of the Witness project and its use of keyless signatures for attestations
[Witness](https://github.com/testifysec/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](https://www.testifysec.com/blog/what-is-a-supply-chain-attestation/) created by [Witness](https://github.com/testifysec/witness) must be trusted and attached to a functionary (authorized user). [Witness](https://github.com/testifysec/witness) policy enables administrators to enforce the steps used to create an artifact and who or what ran those steps.
#### Benefits of using MultiSig for Verification
[Witness](https://github.com/testifysec/witness) uses multi-sig with trusted timestamp authorities (TSAs) for verifying timestamps on [attestations](https://www.testifysec.com/blog/what-is-a-supply-chain-attestation/). This implementation allows users to verify [attestations](https://www.testifysec.com/blog/what-is-a-supply-chain-attestation/) 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](https://www.testifysec.com/blog/what-is-a-supply-chain-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.
### Overview of the Witness Signing and Verification Flow
[Witness](https://github.com/testifysec/witness) verification is designed to function without an internet connection or any centralized service, and as such, we implemented timestamping via [RFC 3161](https://www.ietf.org/rfc/rfc3161.txt) before transparency log verification. This process differs from the reference [Cosign](https://github.com/sigstore/cosign) verification. Here is a step-by-step breakdown of the flow:
1. The producer generates a private key, a unique digital code that is kept secret.
2. The producer authenticates with Sigstore through OIDC and sends the corresponding public key to Fulcio.
3. Fulcio provides a short-lived code signing certificate to the producer.
4. The producer uses the private key to sign the software attestation and includes the code signing certificate and signature in an envelope.
5. The producer sends the signature's hash to a TSA (Timestamping Authority) for signing.
6. The TSA timestamps the signature, and this timestamp response is added to the envelope.
7. The producer provides the signed software attestation to the consumer. The public key or CA of Fulcio and TSAs are provided to the consumer through a Witness policy.
8. The consumer verifies the authenticity and integrity of the software attestation by checking the public key was issued by Fulcio CA, the signature matches the attestation data, a trusted TSA timestamped the signature, the signature was timestamped within the certificate validity period, and the attestation data meets policy constraints. The consumer can also query for the software attestation via Archivista's API.
```mermaid
sequenceDiagram
participant Producer
participant OIDC
participant Fulcio
participant TSA
participant Consumer
Producer->> Producer: Generate Private Key
Producer->>OIDC: Authenticate with Sigstore
OIDC-->>Producer: Provide authenticated OIDC token
Producer->>Fulcio: Request code signing certificate, send public key
Fulcio-->>Producer: Provide a short-lived code signing certificate
Producer->>Producer: Sign software attestation, append cert and signature to envelope
Producer->>TSA: Send hash of signature to TSA for cross-signing
Producer->>Producer: Append TSA response to envelope
Producer->>Consumer: Provide Public Key/CAs as signed Witness Policy
Producer->>Consumer: Provide signed software attestation
note left of Consumer: Attestation can be queried via Archivista's API
rect rgb(230, 230, 230)
note right of TSA: offline verification
Consumer->>Consumer: Verify a trusted entity signs the policy
Consumer->>Consumer: Verify attestation data signed by a trusted functionary
Consumer->>Consumer: Verify a trusted CA timestamped signature Consumer->>Consumer: Verify signature matches attestation data and was timestamped within the certificate validity period
Consumer->>Consumer: Verify attestation data meets policy constraints
end
```
### What about Rekor, Cosign, and Transparency?
It's worth noting that currently, the Witness verification process does not verify the [SCT](https://certificate.transparency.dev/howctworks/) or publish the signed secure hash of the [attestation](https://www.testifysec.com/blog/what-is-a-supply-chain-attestation/) to the [Rekor](https://github.com/sigstore/rekor) transparency log. This would provide a transparent and auditable record of the signing process.
[Rekor](https://github.com/sigstore/rekor) and transparency are closely related in the context of Cosign. Cosign uses [Rekor](https://github.com/sigstore/rekor) as an additional layer of verification by storing a hashed record of the artifacts it signs. [Rekor](https://github.com/sigstore/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](https://github.com/testifysec/witness/issues/233) to implement transparency as an option in [Witness](https://github.com/testifysec/witness) to provide more auditability of the [attestations](https://www.testifysec.com/blog/what-is-a-supply-chain-attestation/) created in addition to the current flow which allows for verification using the [time stamping protocol (TSP)](https://en.wikipedia.org/wiki/Time_stamp_protocol). You can learn more about how certificate transparency works at [https://certificate.transparency.dev/howctworks/](https://certificate.transparency.dev/howctworks/).
### Example: Use Witness and Fulcio to Create and Verify an Attestation
#### Download Witness
First, download the [Witness](https://github.com/testifysec/witness) binary from the releases page on GitHub. Then, you can use the following command to download, extract and verify the shasum of the binary.
```bash
bash <(curl -s https://raw.githubusercontent.com/testifysec/witness/install-script/install-witness.sh)
```
#### Create the Signed Attestation
Next, run a build step and record the [attestation](https://www.testifysec.com/blog/what-is-a-supply-chain-attestation/). In this example, we will remove a test file if it exists and then use the witness run command to record the [attestation](https://www.testifysec.com/blog/what-is-a-supply-chain-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](https://www.testifysec.com/blog/what-is-a-supply-chain-attestation/) for. The [Sigstore public good](https://docs.sigstore.dev/#about-the-project) instance and [FreeTSA](https://www.freetsa.org/index_en.php) are used in this example
```bash
rm test.txt
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 remove the test file if it exists, then run the command echo "hello"> test.txt and record the [attestation](https://www.testifysec.com/blog/what-is-a-supply-chain-attestation/) of the file in a file called test.json.
View the [attestation](https://www.testifysec.com/blog/what-is-a-supply-chain-attestation/) data in the signed DSSE Envelope. You can do this by running the following command:
```bash
cat test.json | jq -r .payload | base64 -d | jq
```
#### Create the Artifact Policy
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](https://fulcio.sigstore.dev/api/v2/trustBundle)
Download the FreeTSA CA Certificate on their [website](https://www.freetsa.org/index_en.php).
Create a policy file that defines the [attestations](https://www.testifysec.com/blog/what-is-a-supply-chain-attestation/) 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.
- Make sure you replace my email with one associated with the account you used to sign the attestation.
- *Notice* the name and identifier in the `steps` section of the policy file. This corresponds with the `step` name indicated in the `witness run` command and the `payload` section of the attestation.
- You can also specify Rego constraints for each attestation which is evaluated against the attestation payload.
```json
{
"expires": "2030-12-17T23:57:40-05:00",
"steps": {
"test": {
"name": "test",
"attestations": [
{
"type": "https://witness.dev/attestations/product/v0.1"
}
],
"functionaries": [
{
"type": "root",
"certConstraint": {
"commonname": "*",
"dnsnames": ["*"],
"emails": ["cole@testifysec.com"],
"organizations": ["*"],
"uris": ["*"],
"roots": [
"3ba7b6cc4e95469d4d334b49cb257ad8537076fa84b0ca87ff4ecfe6a54680c1"
]
}
}
]
}
},
"roots": {
"3ba7b6cc4e95469d4d334b49cb257ad8537076fa84b0ca87ff4ecfe6a54680c1": {
"certificate": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNHakNDQWFHZ0F3SUJBZ0lVQUxuVmlWZm5VMGJySmFzbVJrSHJuL1VuZmFRd0NnWUlLb1pJemowRUF3TXdLakVWTUJNR0ExVUVDaE1NYzJsbmMzUnZjbVV1WkdWMk1SRXdEd1lEVlFRREV3aHphV2R6ZEc5eVpUQWVGdzB5TWpBME1UTXlNREEyTVRWYUZ3MHpNVEV3TURVeE16VTJOVGhhTURjeEZUQVRCZ05WQkFvVERITnBaM04wYjNKbExtUmxkakVlTUJ3R0ExVUVBeE1WYzJsbmMzUnZjbVV0YVc1MFpYSnRaV1JwWVhSbE1IWXdFQVlIS29aSXpqMENBUVlGSzRFRUFDSURZZ0FFOFJWUy95c0grTk92dURaeVBJWnRpbGdVRjlObGFyWXBBZDlIUDF2QkJIMVU1Q1Y3N0xTUzdzMFppSDRuRTdIdjdwdFM2THZ2Ui9TVGs3OThMVmdNekxsSjRIZUlmRjN0SFNhZXhMY1lwU0FTcjFrUzBOL1JnQkp6LzlqV0NpWG5vM3N3ZVRBT0JnTlZIUThCQWY4RUJBTUNBUVl3RXdZRFZSMGxCQXd3Q2dZSUt3WUJCUVVIQXdNd0VnWURWUjBUQVFIL0JBZ3dCZ0VCL3dJQkFEQWRCZ05WSFE0RUZnUVUzOVBwejFZa0VaYjVxTmpwS0ZXaXhpNFlaRDh3SHdZRFZSMGpCQmd3Rm9BVVdNQWVYNUZGcFdhcGVzeVFvWk1pMENyRnhmb3dDZ1lJS29aSXpqMEVBd01EWndBd1pBSXdQQ3NRSzREWWlaWURQSWFEaTVIRktuZnhYeDZBU1NWbUVSZnN5bllCaVgyWDZTSlJuWlU4NC85RFpkbkZ2dnhtQWpCT3Q2UXBCbGM0Si8wRHh2a1RDcXBjbHZ6aUw2QkNDUG5qZGxJQjNQdTNCeHNQbXlnVVk3SWkyemJkQ2RsaWlvdz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQ==",
"intermediates": [
"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUI5ekNDQVh5Z0F3SUJBZ0lVQUxaTkFQRmR4SFB3amVEbG9Ed3lZQ2hBTy80d0NnWUlLb1pJemowRUF3TXcKS2pFVk1CTUdBMVVFQ2hNTWMybG5jM1J2Y21VdVpHVjJNUkV3RHdZRFZRUURFd2h6YVdkemRHOXlaVEFlRncweQpNVEV3TURjeE16VTJOVGxhRncwek1URXdNRFV4TXpVMk5UaGFNQ294RlRBVEJnTlZCQW9UREhOcFozTjBiM0psCkxtUmxkakVSTUE4R0ExVUVBeE1JYzJsbmMzUnZjbVV3ZGpBUUJnY3Foa2pPUFFJQkJnVXJnUVFBSWdOaUFBVDcKWGVGVDRyYjNQUUd3UzRJYWp0TGszL09sbnBnYW5nYUJjbFlwc1lCcjVpKzR5bkIwN2NlYjNMUDBPSU9aZHhleApYNjljNWlWdXlKUlErSHowNXlpK1VGM3VCV0FsSHBpUzVzaDArSDJHSEU3U1hyazFFQzVtMVRyMTlMOWdnOTJqCll6QmhNQTRHQTFVZER3RUIvd1FFQXdJQkJqQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01CMEdBMVVkRGdRV0JCUlkKd0I1ZmtVV2xacWw2ekpDaGt5TFFLc1hGK2pBZkJnTlZIU01FR0RBV2dCUll3QjVma1VXbFpxbDZ6SkNoa3lMUQpLc1hGK2pBS0JnZ3Foa2pPUFFRREF3TnBBREJtQWpFQWoxbkhlWFpwKzEzTldCTmErRURzRFA4RzFXV2cxdENNCldQL1dIUHFwYVZvMGpoc3dlTkZaZ1NzMGVFN3dZSTRxQWpFQTJXQjlvdDk4c0lrb0YzdlpZZGQzL1Z0V0I1YjkKVE5NZWE3SXgvc3RKNVRmY0xMZUFCTEU0Qk5KT3NRNHZuQkhKCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0="
]
}
},
"timestampauthorities": {
"freetsa": {
"certificate": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUgvekNDQmVlZ0F3SUJBZ0lKQU1IcGhoWU5xT21BTUEwR0NTcUdTSWIzRFFFQkRRVUFNSUdWTVJFd0R3WUQKVlFRS0V3aEdjbVZsSUZSVFFURVFNQTRHQTFVRUN4TUhVbTl2ZENCRFFURVlNQllHQTFVRUF4TVBkM2QzTG1aeQpaV1YwYzJFdWIzSm5NU0l3SUFZSktvWklodmNOQVFrQkZoTmlkWE5wYkdWNllYTkFaMjFoYVd3dVkyOXRNUkl3CkVBWURWUVFIRXdsWGRXVnllbUoxY21jeER6QU5CZ05WQkFnVEJrSmhlV1Z5YmpFTE1Ba0dBMVVFQmhNQ1JFVXcKSGhjTk1UWXdNekV6TURFMU1qRXpXaGNOTkRFd016QTNNREUxTWpFeldqQ0JsVEVSTUE4R0ExVUVDaE1JUm5KbApaU0JVVTBFeEVEQU9CZ05WQkFzVEIxSnZiM1FnUTBFeEdEQVdCZ05WQkFNVEQzZDNkeTVtY21WbGRITmhMbTl5Clp6RWlNQ0FHQ1NxR1NJYjNEUUVKQVJZVFluVnphV3hsZW1GelFHZHRZV2xzTG1OdmJURVNNQkFHQTFVRUJ4TUoKVjNWbGNucGlkWEpuTVE4d0RRWURWUVFJRXdaQ1lYbGxjbTR4Q3pBSkJnTlZCQVlUQWtSRk1JSUNJakFOQmdrcQpoa2lHOXcwQkFRRUZBQU9DQWc4QU1JSUNDZ0tDQWdFQXRnS09EakF5OFJFUTJXVE5xVXVkQW5qaGxDcnBFNnFsCm1RZk5wcGVUbVZ2WnJINHp1dG4rTndUYUhBR3BqU0d2NC9XUnBaMXdaM0JSWjVtUFVCWnlMZ3EwWXJJZlE1RngKMHMvTVJaUHpjMXIzbEtXck1SOXNBUXg0bU40ejExeEZFTzUyOUwwZEZKalBGOU1EOEdwZDJmZVd6R3lwdGxlbApiK1BxVCsrK2ZPYTJvWTArTmFNTTdsL3hjTkhQT2FNejAvMm9sazBpMjJoYktlVmh2b2tQQ3FoRmh6c3VoS3NtCnE0T2Yvbyt0NmRJN3N4NWgwblBNbTRnR1NSaGZxK3o2QlRSZ0NycVFHMkZPTG9WRmd0NmlJbS9Cbk5mZlVyN1YKRFlkM3pabUl3Rk9qL0gzREtIb0dpay94SzNFODJZQTJadWxWT0ZSVy96ajRBcGpQYTVPRmJwSWtkMHBtenh6ZApFY0w0NzloU0E5ZEZpeVZtU3hQdFk1emUxUCtCRTliTVUxUFNjcFJ6dzhNSEZYeHlLcVcxM1F2N0xXdzRzYmszClNjaUI3R0FDYlFpVkd6Z2t2WEc2eTg1SE91dldOdkM1R0xTaXlQOUdsUEIwVjY4dGJ4ejRKVlRSZHcvWG4vWFQKRk56UkJNM2NxOGxCT0FWdC9QQVg1K3VGY3YxUzl3RkU4WWphQmZXQ1AxamRCaWwrYzRlKzB0ZHl3VDJvSm1ZQgpCRi9rRXQxd21Hd01tSHVuTkV1UU56aDFGdEpZNTRoYlVmaVdpMzhtQVNFN3hNdE1oZmovQzRTdmFwaUROODM3CmdZYVBmczh4M0taeGJYN0MzWUFzRm5KaW5sd0FVc3MxZmRLYXI4US9ZVnM3SC9uVTRjNEl4eHh6NGY2N2ZjVnEKTTJJVEtlbnRiQ01DQXdFQUFhT0NBazR3Z2dKS01Bd0dBMVVkRXdRRk1BTUJBZjh3RGdZRFZSMFBBUUgvQkFRRApBZ0hHTUIwR0ExVWREZ1FXQkJUNlZRMk1OR1pSUTB6MzU3T25iSld2ZXVha2x6Q0J5Z1lEVlIwakJJSENNSUcvCmdCVDZWUTJNTkdaUlEwejM1N09uYkpXdmV1YWtsNkdCbTZTQm1EQ0JsVEVSTUE4R0ExVUVDaE1JUm5KbFpTQlUKVTBFeEVEQU9CZ05WQkFzVEIxSnZiM1FnUTBFeEdEQVdCZ05WQkFNVEQzZDNkeTVtY21WbGRITmhMbTl5WnpFaQpNQ0FHQ1NxR1NJYjNEUUVKQVJZVFluVnphV3hsZW1GelFHZHRZV2xzTG1OdmJURVNNQkFHQTFVRUJ4TUpWM1ZsCmNucGlkWEpuTVE4d0RRWURWUVFJRXdaQ1lYbGxjbTR4Q3pBSkJnTlZCQVlUQWtSRmdna0F3ZW1HRmcybzZZQXcKTXdZRFZSMGZCQ3d3S2pBb29DYWdKSVlpYUhSMGNEb3ZMM2QzZHk1bWNtVmxkSE5oTG05eVp5OXliMjkwWDJOaApMbU55YkRDQnp3WURWUjBnQklISE1JSEVNSUhCQmdvckJnRUVBWUh5SkFFQk1JR3lNRE1HQ0NzR0FRVUZCd0lCCkZpZG9kSFJ3T2k4dmQzZDNMbVp5WldWMGMyRXViM0puTDJaeVpXVjBjMkZmWTNCekxtaDBiV3d3TWdZSUt3WUIKQlFVSEFnRVdKbWgwZEhBNkx5OTNkM2N1Wm5KbFpYUnpZUzV2Y21jdlpuSmxaWFJ6WVY5amNITXVjR1JtTUVjRwpDQ3NHQVFVRkJ3SUNNRHNhT1VaeVpXVlVVMEVnZEhKMWMzUmxaQ0IwYVcxbGMzUmhiWEJwYm1jZ1UyOW1kSGRoCmNtVWdZWE1nWVNCVFpYSjJhV05sSUNoVFlXRlRLVEEzQmdnckJnRUZCUWNCQVFRck1Da3dKd1lJS3dZQkJRVUgKTUFHR0cyaDBkSEE2THk5M2QzY3VabkpsWlhSellTNXZjbWM2TWpVMk1EQU5CZ2txaGtpRzl3MEJBUTBGQUFPQwpBZ0VBYUs5K3Y1T0ZZdTlNNnp0WUMrTDY5c3cxb21keWxpODlsWkFmcFdNTWg5Q1JtSmhNNktCcU0vaXB3b0x0Cm54eXhHc2JDUGhjUWp1VHZ6bSt5bE42VndUTW1JbFZ5VlNMS1laY2RTanQvZUNVTis0MUs3c0Q3R1ZteFpCQUYKSUxuQkRtVEdKbUxrclUwS3V1SXBqOGxJL0U2WjZObm11UDIrUkFRU0hzZkJRaTZzc3NuWE1vNEhPVzVndFBPNwpnRHJVcFZYSUQrKzFQNFhuZGtvS243U3Z3NW4welM5ZnYxaHhCY1lJSFBQUVV6ZTJ1MzBiQVF0MG4waUl5Ukx6CmFXdWh0cEF0ZDdmZndFYkFTZ3pCN0UrTkdGNHRwVjM3ZThLaUEyeGlHU1JxVDVuZHUyOGZncE9ZODdnRDNBcloKRGN0WnZ2VENmSGRBUzVrRU8zZ25HR2VaRVZMRG1mRXN2OFRHSmEzQWxqVmE1RTQwSVFEc1VYcFFMaThHK1VDNAoxRFdadThFVlQ0cm5ZYUN3MVZYN1NoT1IxUE5DQ3ZqYjhTOHRmZHVkZDl6aFUzZ0VCMHJ4ZGVUeTF0VmJOTFhXCjk5eTkweGN3cjFaSURVd00veFEvbm9POEZSaG0wTG9QQzczRWYrSjRaQmRydld3YXVGM3pKZTMzZDRpYnhFY2IKOC9wejVXekZrZWl4WU0ybnNIaHFIc0JLdzdKUG91S05YUm5sNUlBRTFlRm1xRHlDN0cvVlQ3T0Y2Njl4TTZoYgpVdDVHMjFKRTRjTks2Tk51Y1MrZnpnMUpQWDArM1Zoc1laamo3RDV1bGpSdlFYcko4aUhnci9NNmoyb0xIdlRBCkkyTUxkcTJxalpGRE9DWHN4QnhKcGJtTEdCeDlvdzZaZXJsVXh6d3MyQVd2MnBrPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0t"
}
}
}
```
### Sign the policy file
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.
```bash
openssl genpkey -algorithm ed25519 -outform PEM -out testkey.pem
openssl pkey -in testkey.pem -pubout > testpub.pem
```
Sign the policy file with the keypair.
```bash
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](https://theupdateframework.io/) and additional key providers.
#### Verify The Attestation
```
Witness verify -p policy-signed.json -a test.json -k testpub.pem -f test.txt
```
### Summary
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](https://github.com/testifysec/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](https://www.testifysec.com/blog/what-is-a-supply-chain-attestation/) created with [Witness](https://github.com/testifysec/witness) can be trusted and verified across an air gap
I want to thank [Andrew Block](https://twitter.com/sabre1041) and [Hayden Blauzvern](https://twitter.com/haydentherapper) 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](https://github.com/testifysec/witness) and [Archivista](https://github.com/testifysec/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.](https://www.testifysec.com/contact/)