Skip to content

Commit 4a79cd2

Browse files
authored
feat: add support for trust config (#58)
Signed-off-by: Kevin Conner <[email protected]>
1 parent afe9244 commit 4a79cd2

File tree

6 files changed

+136
-11
lines changed

6 files changed

+136
-11
lines changed

api/v1alpha1/modelvalidation_types.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,25 @@ type PublicKeyConfig struct {
5151
KeyPath string `json:"keyPath,omitempty"`
5252
}
5353

54+
// ClientTrustConfig defines the configuration for client trust settings,
55+
// used when working with private rekor/fulcio instances.
56+
type ClientTrustConfig struct {
57+
// TrustConfigPath is the path to the trust configuration file.
58+
// This specifies the trust configuration needed for using private rekor/fulcio instances
59+
// and should conform to the ClientTrustConfig message.
60+
// +kubebuilder:validation:Required
61+
TrustConfigPath string `json:"trustConfigPath,omitempty"`
62+
}
63+
5464
// ValidationConfig defines the various methods available for validating model signatures.
5565
// At least one validation method must be specified.
5666
type ValidationConfig struct {
5767
SigstoreConfig *SigstoreConfig `json:"sigstoreConfig,omitempty"`
5868
PkiConfig *PkiConfig `json:"pkiConfig,omitempty"`
5969
PublicKeyConfig *PublicKeyConfig `json:"publicKeyConfig,omitempty"`
70+
// +kubebuilder:validation:Optional
71+
// ClientTrustConfig is the configuration for client trust settings.
72+
ClientTrustConfig *ClientTrustConfig `json:"clientTrustConfig,omitempty"`
6073
}
6174

6275
// ModelValidationSpec defines the desired state of ModelValidation
@@ -170,6 +183,11 @@ func (vc *ValidationConfig) GetConfigHash() string {
170183
hasher.Write([]byte(vc.PublicKeyConfig.KeyPath))
171184
}
172185

186+
if vc.ClientTrustConfig != nil {
187+
hasher.Write([]byte("clienttrust"))
188+
hasher.Write([]byte(vc.ClientTrustConfig.TrustConfigPath))
189+
}
190+
173191
return fmt.Sprintf("%x", hasher.Sum(nil))[:16] // Use first 16 chars for brevity
174192
}
175193

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/ml.sigstore.dev_modelvalidations.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,19 @@ spec:
5858
config:
5959
description: Configuration for validation methods.
6060
properties:
61+
clientTrustConfig:
62+
description: ClientTrustConfig is the configuration for client
63+
trust settings.
64+
properties:
65+
trustConfigPath:
66+
description: |-
67+
TrustConfigPath is the path to the trust configuration file.
68+
This specifies the trust configuration needed for using private rekor/fulcio instances
69+
and should conform to the ClientTrustConfig message.
70+
type: string
71+
required:
72+
- trustConfigPath
73+
type: object
6174
pkiConfig:
6275
description: |-
6376
PkiConfig defines the PKI-based verification configuration

internal/testutil/testutil.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ type TestModelValidationOptions struct {
3131
CertificateCA string
3232
CertIdentity string
3333
CertOidcIssuer string
34+
TrustConfigPath string
3435
}
3536

3637
// TestPodOptions holds configuration for creating test Pod resources
@@ -102,6 +103,13 @@ func CreateTestModelValidation(opts TestModelValidationOptions) *v1alpha1.ModelV
102103
}
103104
}
104105

106+
// Add ClientTrustConfig if trust config path is provided
107+
if opts.TrustConfigPath != "" {
108+
mv.Spec.Config.ClientTrustConfig = &v1alpha1.ClientTrustConfig{
109+
TrustConfigPath: opts.TrustConfigPath,
110+
}
111+
}
112+
105113
return mv
106114
}
107115

internal/webhooks/pod_webhook.go

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -144,28 +144,27 @@ func validationConfigToArgs(logger logr.Logger, cfg v1alpha1.ValidationConfig, s
144144
"--identity", cfg.SigstoreConfig.CertificateIdentity,
145145
"--identity_provider", cfg.SigstoreConfig.CertificateOidcIssuer,
146146
)
147-
return res
148-
}
149-
150-
if cfg.PublicKeyConfig != nil {
147+
} else if cfg.PublicKeyConfig != nil {
151148
logger.Info("found public-key config")
152149
res = append(res,
153150
"key",
154151
fmt.Sprintf("--signature=%s", signaturePath),
155152
"--public_key", cfg.PublicKeyConfig.KeyPath,
156153
)
157-
return res
158-
}
159-
160-
if cfg.PkiConfig != nil {
154+
} else if cfg.PkiConfig != nil {
161155
logger.Info("found pki config")
162156
res = append(res,
163157
"certificate",
164158
fmt.Sprintf("--signature=%s", signaturePath),
165159
"--certificate_chain", cfg.PkiConfig.CertificateAuthority,
166160
)
167-
return res
161+
} else {
162+
logger.Info("missing validation config")
163+
return []string{}
164+
}
165+
166+
if cfg.ClientTrustConfig != nil {
167+
res = append(res, "--trust_config", cfg.ClientTrustConfig.TrustConfigPath)
168168
}
169-
logger.Info("missing validation config")
170-
return []string{}
169+
return res
171170
}

internal/webhooks/pod_webhook_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,5 +153,72 @@ var _ = Describe("Pod webhook", func() {
153153
}
154154
Expect(foundTrackedPod).To(BeTrue(), "Pod should be tracked in status")
155155
})
156+
157+
It("Should add trust_config argument when ClientTrustConfig is provided", func() {
158+
trustConfigName := "trust-config-test"
159+
trustConfigNamespace := fmt.Sprintf("trust-config-ns-%d", time.Now().UnixNano())
160+
161+
By("Creating the Namespace for trust config test")
162+
trustConfigNs := &corev1.Namespace{
163+
ObjectMeta: metav1.ObjectMeta{
164+
Name: trustConfigNamespace,
165+
},
166+
}
167+
err := k8sClient.Create(ctx, trustConfigNs)
168+
Expect(err).To(Not(HaveOccurred()))
169+
170+
By("Create ModelValidation with ClientTrustConfig")
171+
trustMv := testutil.CreateTestModelValidation(testutil.TestModelValidationOptions{
172+
Name: trustConfigName,
173+
Namespace: trustConfigNamespace,
174+
ConfigType: "sigstore",
175+
CertIdentity: "[email protected]",
176+
CertOidcIssuer: "https://accounts.google.com",
177+
TrustConfigPath: "/path/to/trust-config.json",
178+
})
179+
err = k8sClient.Create(ctx, trustMv)
180+
Expect(err).To(Not(HaveOccurred()))
181+
182+
statusTracker.AddModelValidation(ctx, trustMv)
183+
184+
By("create labeled pod with trust config")
185+
trustPod := testutil.CreateTestPod(testutil.TestPodOptions{
186+
Name: "trust-config-pod",
187+
Namespace: trustConfigNamespace,
188+
Labels: map[string]string{constants.ModelValidationLabel: trustConfigName},
189+
})
190+
err = k8sClient.Create(ctx, trustPod)
191+
Expect(err).To(Not(HaveOccurred()))
192+
193+
By("Checking that validation sidecar was created with trust config")
194+
foundTrustPod := &corev1.Pod{}
195+
Eventually(ctx, func(ctx context.Context) []corev1.Container {
196+
_ = k8sClient.Get(ctx, types.NamespacedName{
197+
Name: "trust-config-pod",
198+
Namespace: trustConfigNamespace,
199+
}, foundTrustPod)
200+
return foundTrustPod.Spec.InitContainers
201+
}, 5*time.Second).Should(HaveLen(1))
202+
203+
By("Verifying trust_config argument is present")
204+
initContainer := foundTrustPod.Spec.InitContainers[0]
205+
args := initContainer.Args
206+
Expect(args).To(ContainElement("--trust_config"))
207+
208+
// Find the index of --trust_config and verify the next element is the path
209+
trustConfigIndex := -1
210+
for i, arg := range args {
211+
if arg == "--trust_config" {
212+
trustConfigIndex = i
213+
break
214+
}
215+
}
216+
Expect(trustConfigIndex).To(BeNumerically(">=", 0), "trust_config argument should be present")
217+
Expect(trustConfigIndex+1).To(BeNumerically("<", len(args)), "trust_config should have a value")
218+
Expect(args[trustConfigIndex+1]).To(Equal("/path/to/trust-config.json"))
219+
220+
By("Cleanup trust config namespace")
221+
_ = k8sClient.Delete(ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: trustConfigNamespace}})
222+
})
156223
})
157224
})

0 commit comments

Comments
 (0)