|
1 | 1 | # **Cosign Verifier Library Implementation Using `sigstore-go`** |
2 | 2 |
|
3 | | -## Introduction |
| 3 | +## 1. Introduction |
4 | 4 |
|
5 | | -This document outlines the design of a Cosign verifier library using the newly developed `sigstore-go` API. The goal is to implement the `sigstore/cosign` library for `ratify` verifier API, and not relying on the legacy `sigstore/sigstore` library while ensuring compatibility with the `cosign` CLI experience. |
| 5 | +This document outlines the design of a Cosign verifier library using the newly developed `sigstore-go` API. |
| 6 | +The goal is to implement the `sigstore/cosign` library for `ratify` verifier API, and not relying on the legacy `sigstore/sigstore` library while ensuring compatibility with the `cosign` CLI experience. |
6 | 7 |
|
7 | | -## **2. Goals** |
| 8 | +## 2. Goals |
8 | 9 |
|
9 | 10 | Implement a lightweight and efficient signature verification library. |
10 | 11 |
|
11 | | -- Align closely with `cosign` verification workflows. |
12 | | -- Provide a Go API that simplifies integration with policy engines like Ratify. |
13 | 12 | - Utilize `sigstore-go` to ensure maintainability and support future updates. |
| 13 | +- Provide a Go API that simplifies integration with policy engines like Ratify. |
| 14 | +- Align closely with `cosign` verification workflows. |
14 | 15 |
|
15 | | -## **3. Architecture** |
| 16 | +## 3. Architecture |
16 | 17 |
|
17 | | -### **3.1. High-Level Flow** |
| 18 | +### 3.1. High-Level Flow |
18 | 19 |
|
19 | | -1. **Fetch Signature & Public Key**: Retrieve the signature and associated key from a registry or local source. |
20 | | -2. **Verify Signature**: Use `sigstore-go` to validate the signature. |
21 | | -3. **Check Fulcio & Rekor** (if applicable): Verify against transparency logs and certificate chains. |
22 | | -4. **Policy Evaluation** (Optional): Provide hooks for `cosign` policy-based verification. |
| 20 | +1. **Initialize Verifier, Trust Materials, Policies**: Initialize Cosign verifier with verifier options |
| 21 | +2. **Resolve Verify Option, Composite Verify Input**: Retrieve trust material and Cosign policy option. |
| 22 | +3. **Perform Verify with Trust Materials and Policies**: Use API from `sigstore-go` library to validate the signature. |
23 | 23 |
|
24 | | -### **3.2. Component Breakdown** |
| 24 | +### 3.2. Component Breakdown |
25 | 25 |
|
26 | 26 | | Component | Description | |
27 | 27 | |-----------|------------| |
28 | | -| `Verifier` | Core verification engine using `sigstore-go`. | |
29 | | -| `RegistryFetcher` | Retrieves signatures and attestations from OCI registries.Complete the executor behavor about getting signature descriptor. | |
30 | | -| `KeySource` | Loads keys from TUF, keyless (OIDC-based Fulcio), or user-provided sources. | |
31 | | -| `TransparencyLogVerifier` | Interacts with Rekor for transparency log validation. | |
32 | | -| `PolicyEvaluator` | (Optional) policy evaluation component. | |
| 28 | +| `Verifier`| Core verification engine using `sigstore-go`. | |
| 29 | +| `PolicyProvider`| Interface that provide identity policies. | |
| 30 | +| `TrustedMaterialProvider` | Interface that provides public keys, keyless identifies, and other resources needed for the trust chain. | |
33 | 31 |
|
34 | | -## **4. API Design** |
| 32 | +## 4. Design |
35 | 33 |
|
36 | | -### **4.1. Verifier Interface** |
| 34 | +### 4.1. Verifier Initialize |
37 | 35 |
|
38 | 36 | ```go |
39 | | -type Verifier interface { |
40 | | - // Name returns the name of the verifier. |
41 | | - Name() string |
| 37 | +type Verifier struct { |
| 38 | + name string |
| 39 | + config verify.VerifierConfig |
| 40 | + trustMaterialProvider TrustedMaterialProvider |
| 41 | + policyProvider PolicyProvider |
| 42 | +} |
| 43 | + |
| 44 | +type VerifierConfig struct { // nolint: revive |
| 45 | + // requireObserverTimestamps requires RFC3161 timestamps and/or log |
| 46 | + // integrated timestamps to verify short-lived certificates |
| 47 | + requireObserverTimestamps bool |
| 48 | + // observerTimestampThreshold is the minimum number of verified |
| 49 | + // RFC3161 timestamps and/or log integrated timestamps in a bundle |
| 50 | + observerTimestampThreshold int |
| 51 | + // requireTlogEntries requires log inclusion proofs in a bundle |
| 52 | + requireTlogEntries bool |
| 53 | + // tlogEntriesThreshold is the minimum number of verified inclusion |
| 54 | + // proofs in a bundle |
| 55 | + tlogEntriesThreshold int |
| 56 | + // requireSCTs requires SCTs in Fulcio certificates |
| 57 | + requireSCTs bool |
| 58 | + // ctlogEntriesTreshold is the minimum number of verified SCTs in |
| 59 | + // a Fulcio certificate |
| 60 | + ctlogEntriesThreshold int |
| 61 | +} |
42 | 62 |
|
43 | | - // Type returns the type name of the verifier. |
44 | | - Type() string |
| 63 | +type PolicyProvider interface { |
| 64 | + PolicyConfig(ocispec.Descriptor) PolicyConfig |
| 65 | +} |
45 | 66 |
|
46 | | - // Verifiable returns if the verifier can verify against the given artifact. |
47 | | - Verifiable(artifact ocispec.Descriptor) bool |
| 67 | +type Policy{ |
| 68 | + ignoreIdentities bool |
| 69 | + // CertificateIdentities is defined by the sigstore-go library |
| 70 | + certificateIdentities CertificateIdentities |
| 71 | +} |
48 | 72 |
|
49 | | - // Verify verifies the subject in the store against the artifact and |
50 | | - // returns the verification result. |
51 | | - Verify(ctx context.Context, opts *VerifyOptions) (*VerificationResult, error) |
| 73 | +type TrustMaterialProvider interface { |
| 74 | + // user ocispec.Descriptor to retrive the root.TrustedMaterial |
| 75 | + // root.TrustedMaterial is a interface for trust material defined by |
| 76 | + // the sigstore-go library |
| 77 | + TrustMaterial(ocispec.Descriptor) root.TrustedMaterial |
52 | 78 | } |
53 | 79 | ``` |
54 | 80 |
|
55 | | -### **4.2. Cosign Verify Options** |
| 81 | +### 4.2. Verify Options |
56 | 82 |
|
57 | | -`CosignVerifyOptions` is needed for verification. Those values are preloaded when initialize the verifier and store in a trust material map, using `SubjectDescriptor` as key. |
| 83 | +When ratify-go executor verify API, it takes following fields as input. |
58 | 84 |
|
59 | 85 | ```go |
60 | | -type CosignVerifyOptions struct { |
61 | | - Key string // Public key or keyless verification |
62 | | - RekorURL string // Optional transparency log URL |
63 | | - CertificateChain []byte // Optional certificate chain for Fulcio |
| 86 | +type VerifyOptions struct { |
| 87 | + // Store is the store to access the artifacts. Required. |
| 88 | + Store Store |
| 89 | + |
| 90 | + // Repository represents the fully qualified repository name of the subject, |
| 91 | + // including the registry name. |
| 92 | + // Required. |
| 93 | + Repository string |
| 94 | + |
| 95 | + // SubjectDescriptor is the descriptor of the subject being verified. |
| 96 | + // Required. |
| 97 | + SubjectDescriptor ocispec.Descriptor |
| 98 | + |
| 99 | + // ArtifactDescriptor is the descriptor of the artifact being verified |
| 100 | + // against. Required. |
| 101 | + ArtifactDescriptor ocispec.Descriptor |
64 | 102 | } |
65 | 103 | ``` |
66 | 104 |
|
67 | | -### **4.3. Cosign Verification Result** |
68 | | - |
69 | | -`CosignVerificationResult` is provided in `VerificationResult.Detail` as additional information that can be used to provide more context. |
| 105 | +With those descriptors and store to access the artifacts, the next step is to composite the cosign verify entity. |
| 106 | +The entity also contains public key, policies that showing the expected identity and issuer in the signing certificate. These values are preloaded when initializing the verifier. |
70 | 107 |
|
71 | 108 | ```go |
72 | | -type CosignVerificationResult struct { |
73 | | - VerifyOptions VerifyOptions // Showing ratify verifier input |
74 | | - Signatures []SignatureInfo |
75 | | - TransparencyLog *RekorLogInfo |
| 109 | +type VerifyEntity struct { |
| 110 | + // verify.SignedEntity is a interface defined by sigstore-go as the verify input |
| 111 | + signedEntity verify.SignedEntity |
| 112 | + // identityPolices is a list of policy options as verify input |
| 113 | + identityPolicies []verify.PolicyOption |
76 | 114 | } |
77 | 115 | ``` |
78 | 116 |
|
79 | | -### **4.3.1 SignatureInfo** |
| 117 | +**NOTE:** |
| 118 | + |
| 119 | +- Key-based verification requires providing the public key for cryptographically verification |
| 120 | + |
| 121 | +- Keyless verification finds an x509 certificate with a public key on the signature and verifies it against the Fulcio root trust (or user-supplied root trust). |
| 122 | + |
| 123 | +### 4.3. Verification Result |
| 124 | + |
| 125 | +`VerificationResult` defines the verification result that a verifier plugin |
| 126 | +must return. |
80 | 127 |
|
81 | 128 | ```go |
82 | | -type SignatureInfo struct { |
83 | | - Digest string |
84 | | - Signer string |
85 | | - Timestamp time.Time |
| 129 | +type VerificationResult struct { |
| 130 | + // Err is the error that occurred when the verification failed. |
| 131 | + // If the verification is successful, this field should be nil. Optional. |
| 132 | + Err error |
| 133 | + |
| 134 | + // Description describes the verification result if needed. Optional. |
| 135 | + Description string |
| 136 | + |
| 137 | + // Verifier refers to the verifier that generated the result. Required. |
| 138 | + Verifier Verifier |
| 139 | + |
| 140 | + // Detail is additional information that can be used to provide more context |
| 141 | + // about the verification result. Optional. |
| 142 | + Detail any |
| 143 | +} |
| 144 | + |
| 145 | + |
| 146 | +// `CosignVerificationResult` is provided in `VerificationResult.Detail` as additional information that can be used to provide more context. |
| 147 | + |
| 148 | +type CosignVerificationResult struct { |
| 149 | + MediaType string `json:"mediaType"` |
| 150 | + Signature *SignatureVerificationResult `json:"signature,omitempty"` |
| 151 | + VerifiedTimestamps []TimestampVerificationResult `json:"verifiedTimestamps"` |
| 152 | + VerifiedIdentity *CertificateIdentity `json:"verifiedIdentity,omitempty"` |
86 | 153 | } |
87 | 154 | ``` |
88 | 155 |
|
89 | | -## **5. Implementation Details** |
| 156 | +## 5. Implementation Details |
| 157 | + |
| 158 | +### 5.1. Using sigstore-go |
90 | 159 |
|
91 | | -### **5.1. Using sigstore-go** |
| 160 | +#### 5.1.1 Legacy vs. New Implementation |
| 161 | + |
| 162 | +| Aspect | Legacy (`sigstore/cosign`) | New (`sigstore-go`) | |
| 163 | +|----------------------|--------------------------------------------------------------------------------------------|--------------------------------------------------| |
| 164 | +| **Structure** | Tightly coupled to Cosign CLI | Modular, reusable library for SDK/API integrations | |
| 165 | +| **Verification** | Hardcoded workflows (e.g., fixed certificate checks in `pkg/cosign`) | Extensible via `sigstore-go` primitives (e.g., `TrustedRoot`) | |
| 166 | +| **Policy Support** | Limited to Cosign’s CLI flags | Native integration with Ratify’s verify option | |
| 167 | +| **Performance** | Optimized for CLI use cases (single-threaded verification) | Optimized for serverless/API (caching, parallelization) | |
92 | 168 |
|
93 | 169 | - Use `sigstore-go/pkg/verify` for signature verification. |
94 | | -- Fetch signatures using `sigstore-go/pkg/fetch`. |
95 | 170 | - Integrate with `sigstore-go/pkg/rekor` for transparency log checks. |
96 | 171 |
|
97 | | -### **5.2. Compatibility with cosign CLI** |
| 172 | +### 5.2. Feature Compatibility with Cosign CLI |
| 173 | + |
| 174 | +#### 5.2.1 Current Features |
| 175 | + |
| 176 | +- Verification of Cosign signatures by creating bundles for them (see [conformance tests](test/conformance/main.go) for example) |
| 177 | +- Verification with a Timestamp Authority (TSA) |
| 178 | +- Verification with Rekor (Artifact Transparency Log) |
| 179 | +- Structured verification results. |
98 | 180 |
|
99 | | -- Ensure CLI parity by supporting verification options (`--key`, `--rekor-url`, `--certificate-chain`). |
100 | | -- Handle public key and keyless verification workflows. |
| 181 | +#### 5.2.2 Limitations |
101 | 182 |
|
102 | | -### **5.3. Integration with Ratify** |
| 183 | +- Offline signature verification is currently not supported. |
| 184 | +- Verification of attestations and annotations are not supported. |
103 | 185 |
|
104 | | -- Implement an adapter for Ratify to use the verifier. |
105 | | -- Provide a structured output compatible with Ratify policies. |
| 186 | +**NOTE:** |
| 187 | +The verifier allows you to use the Sigstore Public Good TUF root or your own custom trusted root containing the root/intermediate certificates of the Fulcio/TSA/Rekor instances used to sign the bundle, in order to verify common open source bundles or bundles signed by your own private Sigstore instance. |
106 | 188 |
|
107 | | -## **6. Future Enhancements** |
| 189 | +## 6. Future Enhancements |
108 | 190 |
|
109 | | -- Enhanced error handling and logging. |
110 | | -- Policy-based verification hooks. |
| 191 | +- Enable `Provider` multiplexer. |
| 192 | +- Support user-provided trusted chains. |
| 193 | +- Support more policy for specific timestamps e.g., signed certificate timestamp, integrated timestamp. |
0 commit comments