@@ -12,7 +12,7 @@ import (
12
12
"os"
13
13
"time"
14
14
15
- "github.com/gookit/slog"
15
+ log "github.com/gookit/slog"
16
16
17
17
"github.com/google/go-containerregistry/pkg/authn"
18
18
"github.com/prometheus/client_golang/prometheus"
@@ -69,7 +69,7 @@ type CosignServerHandler struct {
69
69
func NewCosignServerHandler () * CosignServerHandler {
70
70
cs , err := restClient ()
71
71
if err != nil {
72
- slog .Errorf ("Can't init rest client: %v" , err )
72
+ log .Errorf ("Can't init rest client: %v" , err )
73
73
}
74
74
eb := record .NewBroadcaster ()
75
75
eb .StartRecordingToSink (& typedcorev1.EventSinkImpl {Interface : cs .CoreV1 ().Events ("" )})
@@ -83,12 +83,12 @@ func NewCosignServerHandler() *CosignServerHandler {
83
83
func restClient () (* kubernetes.Clientset , error ) {
84
84
restConfig , err := rest .InClusterConfig ()
85
85
if err != nil {
86
- slog .Errorf ("error init in-cluster config: %v" , err )
86
+ log .Errorf ("error init in-cluster config: %v" , err )
87
87
return nil , err
88
88
}
89
89
cs , err := kubernetes .NewForConfig (restConfig )
90
90
if err != nil {
91
- slog .Errorf ("error creating k8sclientset: %v" , err )
91
+ log .Errorf ("error creating k8sclientset: %v" , err )
92
92
return nil , err
93
93
}
94
94
return cs , err
@@ -110,17 +110,17 @@ func (csh *CosignServerHandler) recordNoVerification(p *corev1.Pod) {
110
110
func getPod (b []byte ) (* corev1.Pod , * v1.AdmissionReview , error ) {
111
111
arRequest := v1.AdmissionReview {}
112
112
if err := json .Unmarshal (b , & arRequest ); err != nil {
113
- slog .Error ("Incorrect body" )
113
+ log .Error ("Incorrect body" )
114
114
return nil , nil , err
115
115
}
116
116
if arRequest .Request == nil {
117
- slog .Error ("AdmissionReview request not found" )
117
+ log .Error ("AdmissionReview request not found" )
118
118
return nil , nil , fmt .Errorf ("admissionreview request not found" )
119
119
}
120
120
raw := arRequest .Request .Object .Raw
121
121
pod := corev1.Pod {}
122
122
if err := json .Unmarshal (raw , & pod ); err != nil {
123
- slog .Error ("Error deserializing container" )
123
+ log .Error ("Error deserializing container" )
124
124
return nil , nil , err
125
125
}
126
126
return & pod , & arRequest , nil
@@ -132,12 +132,12 @@ func (csh *CosignServerHandler) getPubKeyFromEnv(c *corev1.Container, ns string)
132
132
for _ , envVar := range c .Env {
133
133
if envVar .Name == CosignEnvVar {
134
134
if envVar .Value != "" {
135
- slog .Debugf ("Found public key in env var for container %q" , c .Name )
135
+ log .Debugf ("Found public key in env var for container %q" , c .Name )
136
136
return envVar .Value , nil
137
137
}
138
138
139
139
if envVar .ValueFrom != nil && envVar .ValueFrom .SecretKeyRef != nil {
140
- slog .Debugf ("Found reference to public key in secret %q for container %q" , envVar .ValueFrom .SecretKeyRef .Name , c .Name )
140
+ log .Debugf ("Found reference to public key in secret %q for container %q" , envVar .ValueFrom .SecretKeyRef .Name , c .Name )
141
141
return csh .getSecretValue (ns ,
142
142
envVar .ValueFrom .SecretKeyRef .Name ,
143
143
envVar .ValueFrom .SecretKeyRef .Key ,
@@ -154,23 +154,23 @@ func (csh *CosignServerHandler) getSecretValue(namespace, secret, key string) (s
154
154
defer cancel ()
155
155
s , err := csh .cs .CoreV1 ().Secrets (namespace ).Get (ctx , secret , metav1.GetOptions {})
156
156
if err != nil {
157
- slog .Debugf ("Can't get secret %s/%s : %v" , namespace , secret , err )
157
+ log .Debugf ("Can't get secret %s/%s : %v" , namespace , secret , err )
158
158
return "" , err
159
159
}
160
160
value := s .Data [key ]
161
161
if len (value ) == 0 {
162
- slog .Errorf ("Secret value of %q is empty for %s/%s" , key , namespace , secret )
162
+ log .Errorf ("Secret value of %q is empty for %s/%s" , key , namespace , secret )
163
163
return "" , nil
164
164
}
165
- slog .Debugf ("Found public key in secret %s/%s, value: %s" , namespace , secret , value )
165
+ log .Debugf ("Found public key in secret %s/%s, value: %s" , namespace , secret , value )
166
166
return string (value ), nil
167
167
}
168
168
169
169
func (csh * CosignServerHandler ) Healthz (w http.ResponseWriter , _ * http.Request ) {
170
170
w .WriteHeader (http .StatusOK )
171
171
_ , err := w .Write ([]byte ("ok" ))
172
172
if err != nil {
173
- slog .Errorf ("Can't write response: %v" , err )
173
+ log .Errorf ("Can't write response: %v" , err )
174
174
http .Error (w , fmt .Sprintf ("could not write response: %v" , err ), http .StatusInternalServerError ) //nolint:gocritic // function returns after call
175
175
}
176
176
}
@@ -191,13 +191,13 @@ func (csh *CosignServerHandler) Serve(w http.ResponseWriter, r *http.Request) {
191
191
192
192
// Url path of admission
193
193
if r .URL .Path != "/validate" {
194
- slog .Error ("No validate URI" )
194
+ log .Error ("No validate URI" )
195
195
http .Error (w , "no validate" , http .StatusBadRequest )
196
196
return
197
197
}
198
198
199
199
if len (body ) == 0 {
200
- slog .Error ("Empty body" )
200
+ log .Error ("Empty body" )
201
201
http .Error (w , "empty body" , http .StatusBadRequest )
202
202
return
203
203
}
@@ -207,14 +207,15 @@ func (csh *CosignServerHandler) Serve(w http.ResponseWriter, r *http.Request) {
207
207
208
208
pod , arRequest , err := getPod (body )
209
209
if err != nil {
210
- slog .Errorf ("Error getPod in %s/%s: %v" , pod .Namespace , pod .Name , err )
210
+ log .Errorf ("Error getPod in %s/%s: %v" , pod .Namespace , pod .Name , err )
211
211
http .Error (w , "incorrect body" , http .StatusBadRequest )
212
212
return
213
213
}
214
214
215
215
ctx := r .Context ()
216
216
kc , err := newKeychainForPod (ctx , pod )
217
217
if err != nil {
218
+ log .Errorf ("Error intializing k8schain %s/%s: %v" , pod .Namespace , pod .Name , err )
218
219
http .Error (w , "Failed initializing k8schain" , http .StatusInternalServerError )
219
220
return
220
221
}
@@ -229,7 +230,7 @@ func (csh *CosignServerHandler) Serve(w http.ResponseWriter, r *http.Request) {
229
230
230
231
err = csh .verifyContainer (pod .Spec .InitContainers [i ], pubKey )
231
232
if err != nil {
232
- slog .Errorf ("Error verifying init container %s/%s/%s: %v" , pod .Namespace , pod .Name , pod .Spec .InitContainers [0 ].Name , err )
233
+ log .Errorf ("Error verifying init container %s/%s/%s: %v" , pod .Namespace , pod .Name , pod .Spec .InitContainers [0 ].Name , err )
233
234
deny (w , err .Error (), arRequest .Request .UID )
234
235
return
235
236
}
@@ -243,7 +244,7 @@ func (csh *CosignServerHandler) Serve(w http.ResponseWriter, r *http.Request) {
243
244
}
244
245
err = csh .verifyContainer (pod .Spec .Containers [i ], pubKey )
245
246
if err != nil {
246
- slog .Errorf ("Error verifying container %s/%s/%s: %v" , pod .Namespace , pod .Name , pod .Spec .Containers [i ].Name , err )
247
+ log .Errorf ("Error verifying container %s/%s/%s: %v" , pod .Namespace , pod .Name , pod .Spec .Containers [i ].Name , err )
247
248
deny (w , err .Error (), arRequest .Request .UID )
248
249
return
249
250
}
@@ -272,7 +273,7 @@ func newKeychainForPod(ctx context.Context, pod *corev1.Pod) (authn.Keychain, er
272
273
273
274
kc , err := k8schain .NewInCluster (ctx , opt )
274
275
if err != nil {
275
- slog .Errorf ("Error intializing k8schain %s/%s: %v" , pod .Namespace , pod .Name , err )
276
+ log .Errorf ("Error intializing k8schain %s/%s: %v" , pod .Namespace , pod .Name , err )
276
277
return nil , err
277
278
}
278
279
return kc , nil
@@ -282,66 +283,66 @@ func newKeychainForPod(ctx context.Context, pod *corev1.Pod) (authn.Keychain, er
282
283
// If no public key is found, it returns an empty string.
283
284
func (csh * CosignServerHandler ) getPubKeyFor (c corev1.Container , ns string ) string { //nolint:gocritic // better for garbage collection
284
285
if c .Image == "" {
285
- slog .Debugf ("Container %q has no image, skipping verification" , c .Name )
286
+ log .Debugf ("Container %q has no image, skipping verification" , c .Name )
286
287
return ""
287
288
}
288
289
if len (c .Env ) == 0 {
289
- slog .Debugf ("Container %q has no env vars, skipping verification" , c .Name )
290
+ log .Debugf ("Container %q has no env vars, skipping verification" , c .Name )
290
291
return ""
291
292
}
292
293
pubKey , err := csh .getPubKeyFromEnv (& c , ns )
293
294
if err != nil {
294
- slog .Debugf ("Could not find pub key in container's %q environment: %v" , c .Name , err )
295
+ log .Debugf ("Could not find pub key in container's %q environment: %v" , c .Name , err )
295
296
}
296
297
297
298
// If no public key get here, try to load default secret
298
299
if pubKey == "" {
299
300
pubKey , err = csh .getSecretValue (ns , "cosignwebhook" , CosignEnvVar )
300
301
if err != nil {
301
- slog .Debugf ("Could not find pub key from default secret: %v" , err )
302
+ log .Debugf ("Could not find pub key from default secret: %v" , err )
302
303
}
303
304
}
304
305
305
306
// Still no public key, we don't care. Otherwise, POD won't start if we return with 403
306
307
// In future versions this should block the start of the container
307
308
if pubKey == "" {
308
- slog .Debugf ("No public key found, returning" )
309
+ log .Debugf ("No public key found, returning" )
309
310
return ""
310
311
}
311
312
312
- slog .Debugf ("Found public key for container %q" , c .Name )
313
+ log .Debugf ("Found public key for container %q" , c .Name )
313
314
return pubKey
314
315
}
315
316
316
317
// verifyContainer verifies the signature of the container image
317
318
func (csh * CosignServerHandler ) verifyContainer (c corev1.Container , pubKey string ) error { //nolint:gocritic // better for garbage collection
318
- slog .Debugf ("Verifying container %s" , c .Name )
319
+ log .Debugf ("Verifying container %s" , c .Name )
319
320
320
321
// Lookup image name of current container
321
322
image := c .Image
322
323
refImage , err := name .ParseReference (image )
323
324
if err != nil {
324
- slog .Errorf ("Error parsing image reference: %v" , err )
325
+ log .Errorf ("Error parsing image reference: %v" , err )
325
326
return fmt .Errorf ("could parse image reference for image %q" , image )
326
327
}
327
328
328
329
// Encrypt public key
329
330
publicKey , err := cryptoutils .UnmarshalPEMToPublicKey ([]byte (pubKey ))
330
331
if err != nil {
331
- slog .Errorf ("Error unmarshalling public key: %v" , err )
332
+ log .Errorf ("Error unmarshalling public key: %v" , err )
332
333
return fmt .Errorf ("public key for image %q malformed" , image )
333
334
}
334
335
335
336
// Load public key to verify
336
337
cosignLoadKey , err := signature .LoadECDSAVerifier (publicKey .(* ecdsa.PublicKey ), crypto .SHA256 )
337
338
if err != nil {
338
- slog .Errorf ("Error loading ECDSA verifier: %v" , err )
339
+ log .Errorf ("Error loading ECDSA verifier: %v" , err )
339
340
return errors .New ("failed creating key verifier" )
340
341
}
341
342
342
343
// Verify signature on remote image with the presented public key
343
344
remoteOpts := []ociremote.Option {ociremote .WithRemoteOptions (remote .WithAuthFromKeychain (csh .kc ))}
344
- slog .Debugf ("Verifying image %q with public key %q" , image , pubKey )
345
+ log .Debugf ("Verifying image %q with public key %q" , image , pubKey )
345
346
_ , _ , err = cosign .VerifyImageSignatures (
346
347
context .Background (),
347
348
refImage ,
@@ -354,26 +355,26 @@ func (csh *CosignServerHandler) verifyContainer(c corev1.Container, pubKey strin
354
355
355
356
// Verify Image failed, needs to reject container start
356
357
if err != nil {
357
- slog .Errorf ("Error verifying signature: %v" , err )
358
+ log .Errorf ("Error verifying signature: %v" , err )
358
359
return fmt .Errorf ("signature for %q couldn't be verified" , image )
359
360
}
360
361
361
362
// count successful verifies for prometheus metric
362
363
verifiedProcessed .Inc ()
363
- slog .Infof ("Image %q verified successfully" , image )
364
+ log .Infof ("Image %q verified successfully" , image )
364
365
return nil
365
366
}
366
367
367
368
// deny prevents the container from starting
368
369
func deny (w http.ResponseWriter , msg string , uid types.UID ) {
369
370
resp , err := json .Marshal (admissionReview (http .StatusForbidden , false , "Failure" , msg , uid ))
370
371
if err != nil {
371
- slog .Errorf ("Can't encode response: %v" , err )
372
+ log .Errorf ("Can't encode response: %v" , err )
372
373
http .Error (w , fmt .Sprintf ("could not encode response: %v" , err ), http .StatusInternalServerError )
373
374
return
374
375
}
375
376
if _ , err := w .Write (resp ); err != nil {
376
- slog .Errorf ("Can't write response: %v" , err )
377
+ log .Errorf ("Can't write response: %v" , err )
377
378
http .Error (w , fmt .Sprintf ("could not write response: %v" , err ), http .StatusInternalServerError )
378
379
}
379
380
}
@@ -382,12 +383,12 @@ func deny(w http.ResponseWriter, msg string, uid types.UID) {
382
383
func accept (w http.ResponseWriter , msg string , uid types.UID ) {
383
384
resp , err := json .Marshal (admissionReview (http .StatusOK , true , "Success" , msg , uid ))
384
385
if err != nil {
385
- slog .Errorf ("Can't encode response: %v" , err )
386
+ log .Errorf ("Can't encode response: %v" , err )
386
387
http .Error (w , fmt .Sprintf ("could not encode response: %v" , err ), http .StatusInternalServerError )
387
388
return
388
389
}
389
390
if _ , err := w .Write (resp ); err != nil {
390
- slog .Errorf ("Can't write response: %v" , err )
391
+ log .Errorf ("Can't write response: %v" , err )
391
392
http .Error (w , fmt .Sprintf ("could not write response: %v" , err ), http .StatusInternalServerError )
392
393
}
393
394
}
0 commit comments